/// <summary> /// Determines if this triangle contains the point p. /// </summary> /// <param name="p">The query point</param> /// <returns>True if p is not null and is inside this triangle</returns> /// <remarks>Note: on boundary is considered outside</remarks> public bool contains_BoundaryIsOutside(Point_dt p) { if (_halfplane | p == null) { return(false); } if (isCorner(p)) { return(false); } int a12 = p.pointLineTest(_a, _b); int a23 = p.pointLineTest(_b, _c); int a31 = p.pointLineTest(_c, _a); if ((a12 == Point_dt.LEFT && a23 == Point_dt.LEFT && a31 == Point_dt.LEFT) || (a12 == Point_dt.RIGHT && a23 == Point_dt.RIGHT && a31 == Point_dt.RIGHT)) { return(true); } else { return(false); } }
/// <summary> /// Constructs a new Circle_dt. /// </summary> /// <param name="c">Center of the circle.</param> /// <param name="r">Radius of the circle.</param> /// <remarks></remarks> public Circle_dt(Point_dt c, double r) { m_c = c; m_r = r; }
/// <summary> /// Create a bounding box between lowerLeft and upperRight /// </summary> /// <param name="lowerLeft">Lower left point of the box</param> /// <param name="upperRight">Upper right point of the box</param> public BoundingBox(Point_dt lowerLeft, Point_dt upperRight) { init(lowerLeft.x, upperRight.x, lowerLeft.y, upperRight.y); }
public bool isGreater(Point_dt p) { return(x > p.x | (x == p.x & y > p.y)); }
public bool isLess(Point_dt p) { return(x < p.x | (x == p.x & y < p.y)); }
public double distance2(Point_dt p) { return((p.x - x) * (p.x - x) + (p.y - y) * (p.y - y)); }
/// <summary> /// tests the relation between current point (as a 2D [x,y] point) and a 2D /// segment a,b (the Z values are ignored), returns one of the following: /// LEFT, RIGHT, INFRONTOFA, BEHINDB, ONSEGMENT, ISERROR /// </summary> /// <param name="a">The first point of the segment</param> /// <param name="b">The second point of the segment</param> /// <returns>The value (flag) of the relation between this point and the a,b line-segment.</returns> /// <remarks></remarks> public int pointLineTest(Point_dt a, Point_dt b) { double dx = b.x - a.x; double dy = b.y - a.y; double res = dy * (x - a.x) - dx * (y - a.y); if (res < 0) { return(LEFT); } if (res > 0) { return(RIGHT); } if (dx > 0) { if (x < a.x) { return(INFRONTOFA); } if (b.x < x) { return(BEHINDB); } return(ONSEGMENT); } if (dx < 0) { if (x > a.x) { return(INFRONTOFA); } if (b.x > x) { return(BEHINDB); } return(ONSEGMENT); } if (dy > 0) { if (y < a.y) { return(INFRONTOFA); } if (b.y < y) { return(BEHINDB); } return(ONSEGMENT); } if (dy < 0) { if (y > a.y) { return(INFRONTOFA); } if (b.y > y) { return(BEHINDB); } return(ONSEGMENT); } return(ISERROR); }
/// <summary> /// Search for p within current triangulation /// </summary> /// <param name="p">Query point</param> /// <returns>Return true if p is within current triangulation (in its 2D convex hull).</returns> public bool contains(Point_dt p) { Triangle_dt tt = Find(p); return(!tt.isHalfplane); }
/// <summary> /// Creates a half plane using the segment (A,B). /// </summary> public Triangle_dt(Point_dt A, Point_dt B) { _a = A; _b = B; _halfplane = true; }
public double distance3D(Point_dt p) { return(Math.Sqrt((p.x - x) * (p.x - x) + (p.y - y) * (p.y - y) + (p.z - z) * (p.z - z))); }
/// <summary> /// compute the Z value for the X, Y values of q. /// Assume current triangle represent a plane --> q does NOT need to be contained in this triangle. /// </summary> /// <param name="q">A x/y point.</param> /// <returns>A new <see cref="Point_dt"/> with same x/y than <paramref name="q"/> and computed z value</returns> /// <remarks>Current triangle must not be a halfplane.</remarks> public Point_dt z(Point_dt q) { double newz = z_value(q); return(new Point_dt(q.x, q.y, newz)); }
/// <summary> /// compute the Z value for the X, Y values of q. /// Assume current triangle represent a plane --> q does NOT need to be contained in this triangle. /// </summary> /// <param name="q">A x/y point.</param> /// <returns></returns> /// <remarks>Current triangle must not be a halfplane.</remarks> public double z_value(Point_dt q) { if (q == null) { throw new ArgumentException("Input point cannot be Nothing", "q"); } if (_halfplane) { throw new Exception("Cannot approximate the z value from a halfplane triangle"); } if (q.x == _a.x & q.y == _a.y) { return(_a.z); } if (q.x == _b.x & q.y == _b.y) { return(_b.z); } if (q.x == _c.x & q.y == _c.y) { return(_c.z); } double X = 0; double x0 = q.x; double x1 = _a.x; double x2 = _b.x; double x3 = _c.x; double Y = 0; double y0 = q.y; double y1 = _a.y; double y2 = _b.y; double y3 = _c.y; double Z = 0; double m01 = 0; double k01 = 0; double m23 = 0; double k23 = 0; // 0 - regular, 1-horizontal , 2-vertical int flag01 = 0; if (x0 != x1) { m01 = (y0 - y1) / (x0 - x1); k01 = y0 - m01 * x0; if (m01 == 0) { flag01 = 1; } //2-vertical } else { flag01 = 2; //x01 = x0 } int flag23 = 0; if (x2 != x3) { m23 = (y2 - y3) / (x2 - x3); k23 = y2 - m23 * x2; if (m23 == 0) { flag23 = 1; } //2-vertical } else { flag23 = 2; //x01 = x0 } if (flag01 == 2) { X = x0; Y = m23 * X + k23; } else if (flag23 == 2) { X = x2; Y = m01 * X + k01; } else { X = (k23 - k01) / (m01 - m23); Y = m01 * X + k01; } double r = 0; if (flag23 == 2) { r = (y2 - Y) / (y2 - y3); } else { r = (x2 - X) / (x2 - x3); } Z = _b.z + (_c.z - _b.z) * r; if (flag01 == 2) { r = (y1 - y0) / (y1 - Y); } else { r = (x1 - x0) / (x1 - X); } double qZ = _a.z + (Z - _a.z) * r; return(qZ); }
/// <summary> /// Checks if the given point is a corner of this triangle. /// </summary> /// <param name="p">The given point.</param> /// <returns>True if the given point is a corner of this triangle.</returns> public bool isCorner(Point_dt p) { return((p.x == _a.x & p.y == _a.y) | (p.x == _b.x & p.y == _b.y) | (p.x == _c.x & p.y == _c.y)); }
private Triangle_dt insertPointSimple(Point_dt p) { nPoints += 1; if ((!allColinear)) { Triangle_dt t = Find(startTriangle, p); if (t.isHalfplane) { startTriangle = extendOutside(t, p); } else { startTriangle = extendInside(t, p); } return(startTriangle); } if (nPoints == 1) { firstP = p; return(null); } if (nPoints == 2) { startTriangulation(firstP, p); return(null); } switch (p.pointLineTest(firstP, lastP)) { case Point_dt.LEFT: startTriangle = extendOutside(firstT.abnext, p); allColinear = false; break; // TODO: might not be correct. Was : Exit Select break; case Point_dt.RIGHT: startTriangle = extendOutside(firstT, p); allColinear = false; break; // TODO: might not be correct. Was : Exit Select break; case Point_dt.ONSEGMENT: insertCollinear(p, Point_dt.ONSEGMENT); break; // TODO: might not be correct. Was : Exit Select break; case Point_dt.INFRONTOFA: insertCollinear(p, Point_dt.INFRONTOFA); break; // TODO: might not be correct. Was : Exit Select break; case Point_dt.BEHINDB: insertCollinear(p, Point_dt.BEHINDB); break; // TODO: might not be correct. Was : Exit Select break; } return(null); }
public object Compare(Point_dt o1, Point_dt o2) { if (!(o1 == null | o2 == null)) { if ((m_flag == 0)) { if ((o1.x > o2.x)) { return(1); } if ((o1.x < o2.x)) { return(-1); } // x1 == x2 if ((o1.y > o2.y)) { return(1); } if ((o1.y < o2.y)) { return(-1); } } else if ((m_flag == 1)) { if ((o1.x > o2.x)) { return(-1); } if ((o1.x < o2.x)) { return(1); } // x1 == x2 if ((o1.y > o2.y)) { return(-1); } if ((o1.y < o2.y)) { return(1); } } else if ((m_flag == 2)) { if ((o1.y > o2.y)) { return(1); } if ((o1.y < o2.y)) { return(-1); } // y1 == y2 if ((o1.x > o2.x)) { return(1); } if ((o1.x < o2.x)) { return(-1); } } else if ((m_flag == 3)) { if ((o1.y > o2.y)) { return(-1); } if ((o1.y < o2.y)) { return(1); } // y1 == y2 if ((o1.x > o2.x)) { return(-1); } if ((o1.x < o2.x)) { return(1); } } } else { if (o1 == null & o2 == null) { return(0); } if (o1 == null & ((o2 != null))) { return(1); } if (((o1 != null)) & o2 == null) { return(-1); } } throw new Exception("Unexpected behavior, comparer should never have reached this point"); }
private void insertCollinear(Point_dt p, int res) { Triangle_dt t = default(Triangle_dt); Triangle_dt tp = default(Triangle_dt); Triangle_dt u = default(Triangle_dt); switch (res) { case Point_dt.INFRONTOFA: t = new Triangle_dt(firstP, p); tp = new Triangle_dt(p, firstP); t.abnext = tp; tp.abnext = t; t.bcnext = tp; tp.canext = t; t.canext = firstT; firstT.bcnext = t; tp.bcnext = firstT.abnext; firstT.abnext.canext = tp; firstT = t; firstP = p; break; // TODO: might not be correct. Was : Exit Select break; case Point_dt.BEHINDB: t = new Triangle_dt(p, lastP); tp = new Triangle_dt(lastP, p); t.abnext = tp; tp.abnext = t; t.bcnext = lastT; lastT.canext = t; t.canext = tp; tp.bcnext = t; tp.canext = lastT.abnext; lastT.abnext.bcnext = tp; lastT = t; lastP = p; break; // TODO: might not be correct. Was : Exit Select break; case Point_dt.ONSEGMENT: u = firstT; while (p.isGreater(u.a)) { u = u.canext; } t = new Triangle_dt(p, u.b); tp = new Triangle_dt(u.b, p); u.b = p; u.abnext.a = p; t.abnext = tp; tp.abnext = t; t.bcnext = u.bcnext; u.bcnext.canext = t; t.canext = u; u.bcnext = t; tp.canext = u.abnext.canext; u.abnext.canext.bcnext = tp; tp.bcnext = u.abnext; u.abnext.canext = tp; if ((firstT.Equals(u))) { firstT = t; } break; // TODO: might not be correct. Was : Exit Select break; } }
/// <summary> /// Simple copy constructor /// </summary> /// <param name="p">Another point</param> public Point_dt(Point_dt p) : this(p.x, p.y, p.z) { }
/// <summary> /// Return point with x/y and updated Z value (z value is as given by the triangulation) /// </summary> /// <param name="p">Query point (x/y=</param> /// <returns></returns> /// <remarks></remarks> public Point_dt z(Point_dt p) { Triangle_dt t = Find(p); return(t.z(p)); }
public bool circumcircle_contains(Point_dt p) { return(_circum.Radius > _circum.Center.distance2(p)); }