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