Raw File
Geometry.h
#pragma once
#include <Eigen/Dense>

#define ZERO_TOLERANCE 1e-8

typedef Eigen::Vector3d  Point_3;
typedef Eigen::Vector3d  Vector_3;

struct Segment_3{
	Segment_3(Point_3 p0 = Point_3(0,0,0), Point_3 p1 = Point_3(0,0,1)) { p[0] = p0; p[1] = p1; }
	Point_3 p[2];
	Point_3 point(int idx){ return p[idx]; }
	Vector_3 direction() { return (p[1] - p[0]).normalized(); }
};

struct Line_3{
	Line_3(Segment_3 s = Segment_3()) { point = s.point(0); direction = s.direction(); }
	Vector_3 point;
	Vector_3 direction;
};

struct Plane_3{
	Plane_3(Point_3 point = Vector_3(0,0,0), Vector_3 normal = Vector_3(0,0,1)) : p(point), n(normal.normalized()){
		double px = p.x(), py = p.y(), pz = p.z();
		double dx = n.x(), dy = n.y(), dz = n.z();
		pa = dx; pb = dy; pc = dz; pd = -dx*px - dy*py - dz*pz;
	}

	Point_3 p;
	Vector_3 n;
	double pa, pb, pc, pd;

	double a() const { return pa; }
	double b() const { return pb; }
	double c() const { return pc; }
	double d() const { return pd; }
};

static inline double squared_distance( Plane_3 plane, Point_3 point )
{
	double dist = plane.n.dot( Vector_3(point - plane.p) );
	return dist * dist; // squared
}


static inline double squared_distance_of_parallel( Line_3 mLine0, Line_3 mLine1 )
{
	Vector_3 diff = mLine0.point - mLine1.point;
	double b0 = diff.dot(mLine0.direction);
	double c = diff.squaredNorm();
	double s0, s1, sqrDist;

	// Lines are parallel, select any closest pair of points.
	s0 = -b0;
	s1 = (double)0;
	sqrDist = b0*s0 + c;

	// Account for numerical round-off errors.
	if (sqrDist < (double)0) sqrDist = (double)0;

	return sqrDist;
}

static inline double squared_distance( Line_3 mLine0, Line_3 mLine1 )
{
	Vector_3 diff = mLine0.point - mLine1.point;
	double a01 = -mLine0.direction.dot(mLine1.direction);
	double b0 = diff.dot(mLine0.direction);
	double c = diff.squaredNorm();
	double det = std::abs(1.0 - a01*a01);
	double b1, s0, s1, sqrDist;

	if (det >= ZERO_TOLERANCE)
	{
		// Lines are not parallel.
		b1 = -diff.dot(mLine1.direction);
		double invDet = ((double)1)/det;
		s0 = (a01*b1 - b0)*invDet;
		s1 = (a01*b0 - b1)*invDet;
		sqrDist = s0*(s0 + a01*s1 + ((double)2)*b0) +	s1*(a01*s0 + s1 + ((double)2)*b1) + c;
	}
	else
	{
		// Lines are parallel, select any closest pair of points.
		s0 = -b0;
		s1 = (double)0;
		sqrDist = b0*s0 + c;
	}

	// Account for numerical round-off errors.
	if (sqrDist < (double)0) sqrDist = (double)0;

	return sqrDist;
}

static inline Vector_3 cross_product( Vector_3 v1, Vector_3 v2 )
{
	return v1.cross(v2);
}

static inline Vector_3 cross_product( Segment_3 s1, Segment_3 s2 )
{
	return s1.direction().cross(s2.direction());
}
back to top