/** * */ package cz.cuni.mff.peckam.java.origamist.math; import static cz.cuni.mff.peckam.java.origamist.math.MathHelper.EPSILON; import javax.vecmath.Point2d; import javax.vecmath.Point3d; import javax.vecmath.Vector3d; import cz.cuni.mff.peckam.java.origamist.modelstate.ModelPoint; import cz.cuni.mff.peckam.java.origamist.modelstate.ModelSegment; import cz.cuni.mff.peckam.java.origamist.modelstate.ModelTriangle; import cz.cuni.mff.peckam.java.origamist.modelstate.ModelTriangleEdge; /** * This represents an intersection of a segment with a triangle. * * @param T The type of the triangle. * * @author Martin Pecka */ public class IntersectionWithTriangle<T extends Triangle3d> extends Segment3d { /** */ private static final long serialVersionUID = 3418089833892732927L; /** The triangle the intersection occurs on. */ public T triangle; /** * @param triangle A triangle. * @param segment A segment intersecting the triangle. */ public IntersectionWithTriangle(T triangle, Segment3d segment) { super(segment.getP1(), segment.getP2()); this.triangle = triangle; } /** * @return The triangle the intersection occurs on. */ public T getTriangle() { return triangle; } /** * @return <code>true</code> if the intersection segment coincides with an edge of the triangle (even partly * coincides if the segment is shorter than the side). */ public boolean isWholeSideIntersection() { if (v.epsilonEquals(new Vector3d(), EPSILON)) // a single point of intersection return false; for (Segment3d edge : triangle.getEdges()) { if (this.isParallelTo(edge) && edge.contains(p)) return true; } return false; } /** * Get the edge containing the point or nearest to the point. * * @param i Pass 0 to set point to p1, otherwise set it to p2. * @return The edge (if T instanceof ModelTriangle, return ModelSegment with null direction and originatingStepId * 0). */ public Segment3d getEdgeForPoint(int i) { Point3d p; if (i == 0) { p = this.p; } else { p = p2; } if (triangle instanceof ModelTriangle) { ModelTriangle mt = (ModelTriangle) triangle; if (triangle.s1.contains(p)) return new ModelTriangleEdge(mt, 0).getSegment(); else if (triangle.s2.contains(p)) return new ModelTriangleEdge(mt, 1).getSegment(); else if (triangle.s3.contains(p)) return new ModelTriangleEdge(mt, 2).getSegment(); else { double d1 = mt.s1.getNearestPoint(p).distance(p); double d2 = mt.s2.getNearestPoint(p).distance(p); double d3 = mt.s3.getNearestPoint(p).distance(p); if (d1 + EPSILON >= d2 && d1 + EPSILON >= d3) return new ModelTriangleEdge(mt, 0).getSegment(); if (d2 + EPSILON >= d1 && d2 + EPSILON >= d3) return new ModelTriangleEdge(mt, 1).getSegment(); if (d3 + EPSILON >= d1 && d3 + EPSILON >= d2) return new ModelTriangleEdge(mt, 2).getSegment(); } } else { if (triangle.s1.contains(p)) return triangle.s1; else if (triangle.s2.contains(p)) return triangle.s2; else if (triangle.s3.contains(p)) return triangle.s3; else { double d1 = triangle.s1.getNearestPoint(p).distance(p); double d2 = triangle.s2.getNearestPoint(p).distance(p); double d3 = triangle.s3.getNearestPoint(p).distance(p); if (d1 + EPSILON >= d2 && d1 + EPSILON >= d3) return triangle.s1; if (d2 + EPSILON >= d1 && d2 + EPSILON >= d3) return triangle.s2; if (d3 + EPSILON >= d1 && d3 + EPSILON >= d2) return triangle.s3; } } return null; } /** * Return the point with the given index. * * @param i Pass 0 to set point to p1, otherwise set it to p2. * @return The point (if T instanceof ModelTriangle, then return a corresponding ModelPoint). */ public Point3d getPoint(int i) { Point3d p; if (i == 0) { p = this.p; } else { p = p2; } if (triangle instanceof ModelTriangle) { ModelSegment edge = (ModelSegment) getEdgeForPoint(i); double param = edge.getP1().distance(p) / edge.getP1().distance(edge.getP2()); Point2d point = edge.getOriginal().getPointForParameter(param); return new ModelPoint(p, point); } else { return p; } } }