// 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); }