124 lines
2.8 KiB
C++
124 lines
2.8 KiB
C++
|
// This source code is property of the Computer Graphics and Visualization
|
|||
|
// chair of the TU Dresden. Do not distribute!
|
|||
|
// Copyright (C) CGV TU Dresden - All Rights Reserved
|
|||
|
|
|||
|
#include "LineSegment.h"
|
|||
|
#include "GridUtils.h"
|
|||
|
|
|||
|
|
|||
|
//default constructor
|
|||
|
LineSegment::LineSegment()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
//constructs a line segment by the two end points v0, v1 without using the edge handle
|
|||
|
LineSegment::LineSegment(const Eigen::Vector3f& v0, const Eigen::Vector3f& v1):v0(v0),v1(v1)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
//construct a line segment from the edge e of the halfedge mesh m
|
|||
|
LineSegment::LineSegment(const HEMesh& m,const OpenMesh::EdgeHandle& e):h(e)
|
|||
|
{
|
|||
|
auto h = m.halfedge_handle(e, 0);
|
|||
|
v0 = ToEigenVector(m.point(m.from_vertex_handle(h)));
|
|||
|
v1 = ToEigenVector(m.point(m.to_vertex_handle(h)));
|
|||
|
}
|
|||
|
|
|||
|
//returns an axis aligned bounding box of the line segment
|
|||
|
Box LineSegment::ComputeBounds() const
|
|||
|
{
|
|||
|
Box b;
|
|||
|
b.Insert(v0);
|
|||
|
b.Insert(v1);
|
|||
|
return b;
|
|||
|
}
|
|||
|
|
|||
|
//returns true if the line segment overlaps the given box b
|
|||
|
bool LineSegment::Overlaps(const Box& b) const
|
|||
|
{
|
|||
|
|
|||
|
Box aabb = ComputeBounds();
|
|||
|
|
|||
|
if(!b.Overlaps(aabb))
|
|||
|
return false;
|
|||
|
|
|||
|
Eigen::Vector3f o = b.Center();
|
|||
|
Eigen::Vector3f u1 = v0-o;
|
|||
|
Eigen::Vector3f u2 = v1-o;
|
|||
|
|
|||
|
Eigen::Vector3f d1 = v1-v0;
|
|||
|
d1.normalize();
|
|||
|
|
|||
|
float r = b.Radius(d1);
|
|||
|
float lb = u1.dot(d1);
|
|||
|
float ub = u2.dot(d1);
|
|||
|
if(lb > ub)
|
|||
|
std::swap(lb,ub);
|
|||
|
if(lb > r || ub < -r)
|
|||
|
return false;
|
|||
|
|
|||
|
Eigen::Vector3f e1(1,0,0);
|
|||
|
Eigen::Vector3f d2= d1.cross(e1);
|
|||
|
r = b.Radius(d2);
|
|||
|
lb = u1.dot(d2);
|
|||
|
ub = u2.dot(d2);
|
|||
|
if(lb > ub)
|
|||
|
std::swap(lb,ub);
|
|||
|
if(!OverlapIntervals(-r,r,lb,ub))
|
|||
|
return false;
|
|||
|
|
|||
|
Eigen::Vector3f e2(0,1,0);
|
|||
|
Eigen::Vector3f d3 = d1.cross(e2);
|
|||
|
r = b.Radius(d3);
|
|||
|
lb = u1.dot(d3);
|
|||
|
ub = u2.dot(d3);
|
|||
|
if(lb > ub)
|
|||
|
std::swap(lb,ub);
|
|||
|
if(!OverlapIntervals(-r,r,lb,ub))
|
|||
|
return false;
|
|||
|
|
|||
|
Eigen::Vector3f e3(0,0,1);
|
|||
|
Eigen::Vector3f d4 = d1.cross(e3);
|
|||
|
r = b.Radius(d4);
|
|||
|
lb = u1.dot(d4);
|
|||
|
ub = u2.dot(d4);
|
|||
|
|
|||
|
if(!OverlapIntervals(-r,r,lb,ub))
|
|||
|
return false;
|
|||
|
|
|||
|
|
|||
|
return true;
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//returns the point with smallest distance topoint p which lies on the line segment
|
|||
|
Eigen::Vector3f LineSegment::ClosestPoint(const Eigen::Vector3f& p) const
|
|||
|
{
|
|||
|
//the two endpoints of the line segment are v0,v1
|
|||
|
/* Task 3.2.1 */
|
|||
|
return Eigen::Vector3f(0,0,0);
|
|||
|
}
|
|||
|
|
|||
|
//returns the squared distance between point p and the line segment
|
|||
|
float LineSegment::SqrDistance(const Eigen::Vector3f& p) const
|
|||
|
{
|
|||
|
Eigen::Vector3f d = p-ClosestPoint(p);
|
|||
|
return d.squaredNorm();
|
|||
|
}
|
|||
|
|
|||
|
//returns the euclidean distance between point p and the line segment
|
|||
|
float LineSegment::Distance(const Eigen::Vector3f& p) const
|
|||
|
{
|
|||
|
return sqrt(SqrDistance(p));
|
|||
|
}
|
|||
|
|
|||
|
//returns a reference point which is on the line segment and is used to sort the primitive in the AABB tree construction
|
|||
|
Eigen::Vector3f LineSegment::ReferencePoint() const
|
|||
|
{
|
|||
|
return 0.5f*(v0 + v1);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|