[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/OroraTech/firefront/master/src/FFPoint.cpp [Back]  [Original]

/**
 * @file FFPoint.cpp
 * @brief Implements the methods of the FFPoint class
 * @copyright Copyright (C) 2025 ForeFire, Fire Team, SPE, CNRS/Universita di Corsica.
 * @license This program is free software; See LICENSE file for details. (See LICENSE file).
 * @author JeanBaptiste Filippi  2025
 */

#include "FFPoint.h"

using namespace std;

namespace libforefire{

const double FFPoint::Pi = 3.141592653589793;

// constructors and destructor
FFPoint::FFPoint(){
	x = 0.;
	y = 0.;
	z = 0.;
}

FFPoint::FFPoint(const double x0,const  double y0,const  double z0){
	x = x0;
	y = y0;
	z = z0;
}
FFPoint::~FFPoint(){
	// TODO
}
FFPoint::FFPoint(const FFPoint& p) : x(p.x), y(p.y), z(p.z) {
	// nothing else to do
}

// overloading operators
const FFPoint operator+(const FFPoint& left, const FFPoint& right){
	return FFPoint(left.x+right.x,left.y+right.y,left.z+right.z);
}
const FFPoint operator-(const FFPoint& left, const FFPoint& right){
	return FFPoint(left.x-right.x,left.y-right.y,left.z-right.z);
}
const FFPoint operator*(const double& k, const FFPoint& right){
	return FFPoint(k*right.x,k*right.y,k*right.z);
}
FFPoint& operator+=(FFPoint& left, const FFPoint& right){
	left.x += right.x;
	left.y += right.y;
	left.z += right.z;
	//
	//
	return left;
}
FFPoint& operator-=(FFPoint& left, const FFPoint& right){
	left.x -= right.x;
	left.y -= right.y;
	left.z -= right.z;
	return left;
}
FFPoint& operator*=(FFPoint& left, const double& k){
	left.x *= k;
	left.y *= k;
	left.z *= k;
	return left;
}
int operator==(const FFPoint& left, const FFPoint& right){
	return (left.x==right.x)&&(left.y==right.y)&&(left.z==right.z);
}
int operator!=(const FFPoint& left, const FFPoint& right){
	return (left.x!=right.x)||(left.y!=right.y)||(left.z!=right.z);
}

// Accessors
double& FFPoint::getX(){
	return x;
}
double& FFPoint::getY(){
	return y;
}
double& FFPoint::getZ(){
	return z;
}
FFPoint& FFPoint::getLoc(){
	return *this;
}

// Mutators
void FFPoint::setX(const double& x0){
	x = x0;
}
void FFPoint::setY(const double& y0){
	y = y0;
}
void FFPoint::setZ(const double& z0){
	z = z0;
}
void FFPoint::setLoc(const double& x0, const double& y0, const double& z0){
	x = x0;
	y = y0;
	z = z0;
}
void FFPoint::setLoc(FFPoint p){
	x = p.getX();
	y = p.getY();
	z = p.getZ();
}

// norm function
double FFPoint::norm(){
	double sqnorm = x*x + y*y + z*z;
	return sqrt(sqnorm);
}

// distance function
double FFPoint::distance(FFPoint p){
	return sqrt((p.x-x)*(p.x-x) + (p.y-y)*(p.y-y) + (p.z-z)*(p.z-z));
}

double FFPoint::distance2D(FFPoint p){
	return sqrt((p.x-x)*(p.x-x) + (p.y-y)*(p.y-y));
}

double FFPoint::distance2D(double& px, double& py){
	return sqrt((px-x)*(px-x) + (py-y)*(py-y));
}

// scalar product with another vector
double FFPoint::scalarProduct(FFPoint p){
	return x*p.x + y*p.y+ z*p.z;
}

// cross product function
FFPoint FFPoint::crossProduct(FFPoint p){
	if ( z == 0. or p.z == 0. ) return FFPoint(0.,0.,x*p.y-y*p.x);
	return FFPoint(y*p.z-z*p.y,x*p.z-z*p.x,x*p.y-y*p.x);
}

// 2D angle with another point
double FFPoint::angle2D(FFPoint p){
   double theta1 = atan2(y,x);
   double theta2 = atan2(p.y,p.x);
   double dtheta = theta2-theta1;
   while ( dtheta > Pi ) dtheta -= 2.*Pi;
   while ( dtheta < -Pi ) dtheta += 2.*Pi;
   return dtheta;
}

// Distance to a segment
double FFPoint::distanceToSegment(double& ax, double& ay
		, double& bx, double& by){
	// Return minimum distance between line segment ab and point
	const double ab = (ax-bx)*(ax-bx) + (ay-by)*(ay-by);  // i.e. |b-a|^2 -  avoid a sqrt
	if (ab == 0.0) return distance2D(ax, ay);   // a == b case
	// Consider the line extending the segment, parameterized as a + t (b - a).
	// We find projection of point onto the line.
	// It falls where t = [(p-a) . (b-a)] / |b-a|^2
	const double t = ((x-ax)*(bx-ax)+(y-ay)*(by-ay))/ab;
	if (t < 0.0) return distance2D(ax, ay);       // Beyond the 'a' end of the segment
	else if (t > 1.0) return distance2D(bx, by);  // Beyond the 'b' end of the segment
	double px = ax + t*(bx-ax);  // Projection falls on the segment
	double py = ay + t*(by-ay);  // Projection falls on the segment
	return distance2D(px, py);
}


// Signed distance between a point and a polygon
double FFPoint::signedDistanceToPolygon(
		size_t& nvert, double* vertx, double* verty, bool expanding){
	/* signed distance between a point and a polygon.  */
	double d = distanceToSegment(vertx[0], verty[0], vertx[nvert-1], verty[nvert-1]);
	double di;
	for ( size_t i = 0; i < nvert-1; i++ ){
		di = distanceToSegment(vertx[i], verty[i], vertx[i+1], verty[i+1]);
		if ( di < d ) d = di;
	}
	if ( pointInPolygon(nvert, vertx, verty) xor expanding ) return -d;
	return d;
}

// Testing if a point lies in a given polygon
bool FFPoint::pointInPolygon(size_t& nvert, double* vertx, double* verty){
	/* run a semi-infinite ray horizontally (increasing x, fixed y)
	 * out from the test point, and count how many edges it crosses.
	 * At each crossing, the ray switches between inside and outside.
	 * This is called the Jordan curve theorem */
	size_t i;
	size_t j = nvert-1 ;
	bool oddNodes = false;

	for ( i = 0 ; i < nvert; i++) {
		if ( ((verty[i]< y && verty[j] >= y) or (verty[j]< y && verty[i] >= y) )
				and ( (vertx[i] 

Web Proxy Viewer  |  New URL  |  Original Page