public static IntersectionLineLine ( Vector3D p1, Vector3D p2, Vector3D p3, Vector3D p4, Vector3D &intersection ) : int | ||
p1 | Vector3D | |
p2 | Vector3D | |
p3 | Vector3D | |
p4 | Vector3D | |
intersection | Vector3D | |
Résultat | int |
/// <summary> /// Construct a circle from 3 points /// </summary> /// <returns>false if the construction failed (if we are a line).</returns> public bool From3Points(Vector3D p1, Vector3D p2, Vector3D p3) { Reset(); // Check for any infinite points, in which case we are a line. // I'm not sure these checks are smart, since our IsInfinite check is so inclusive, // but Big Chop puzzle doesn't work if we don't do this. // ZZZ - Still, I need to think on this more. if (Infinity.IsInfinite(p1)) { this.From2Points(p2, p3); return(false); } else if (Infinity.IsInfinite(p2)) { this.From2Points(p1, p3); return(false); } else if (Infinity.IsInfinite(p3)) { this.From2Points(p1, p2); return(false); } /* Some links * http://mathforum.org/library/drmath/view/54323.html * http://delphiforfun.org/Programs/Math_Topics/circle_from_3_points.htm * There is lots of info out there about solving via equations, * but as with other code in this project, I wanted to use geometrical constructions. */ // Midpoints. Vector3D m1 = (p1 + p2) / 2; Vector3D m2 = (p1 + p3) / 2; // Perpendicular bisectors. Vector3D b1 = (p2 - p1) / 2; Vector3D b2 = (p3 - p1) / 2; b1.Normalize(); b2.Normalize(); b1.Rotate90(); b2.Rotate90(); Vector3D newCenter; int found = Euclidean2D.IntersectionLineLine(m1, m1 + b1, m2, m2 + b2, out newCenter); Center = newCenter; if (0 == found) { // The points are collinear, so we are a line. From2Points(p1, p2); return(false); } Radius = (p1 - Center).Abs(); Debug.Assert(Tolerance.Equal(Radius, (p2 - Center).Abs())); Debug.Assert(Tolerance.Equal(Radius, (p3 - Center).Abs())); return(true); }
public bool Intersects(Segment s) { Vector3D i1 = Vector3D.DneVector(), i2 = Vector3D.DneVector(); int numInt = 0; if (SegmentType.Arc == Type) { if (SegmentType.Arc == s.Type) { numInt = Euclidean2D.IntersectionCircleCircle(Circle, s.Circle, out i1, out i2); } else { numInt = Euclidean2D.IntersectionLineCircle(P1, P2, s.Circle, out i1, out i2); } } else { if (SegmentType.Arc == s.Type) { numInt = Euclidean2D.IntersectionLineCircle(s.P1, s.P2, Circle, out i1, out i2); } else { numInt = Euclidean2D.IntersectionLineLine(P1, P2, s.P1, s.P2, out i1); } } // -1 can denote conincident segments (I'm not consistent in the impls above :/), // and we are not going to include those for now. if (numInt <= 0) { return(false); } if (numInt > 0) { if (IsPointOn(i1) && s.IsPointOn(i1)) { return(true); } } if (numInt > 1) { if (IsPointOn(i2) && s.IsPointOn(i2)) { return(true); } } return(false); }
// Get the intersection points with a segment. // Returns null if the segment is an arc coincident with the circle (infinite number of intersection points). public Vector3D[] GetIntersectionPoints(Segment segment) { Vector3D p1, p2; int result; // Are we a line? if (this.IsLine) { if (SegmentType.Arc == segment.Type) { Circle tempCircle = segment.Circle; result = Euclidean2D.IntersectionLineCircle(this.P1, this.P2, tempCircle, out p1, out p2); } else { result = Euclidean2D.IntersectionLineLine(this.P1, this.P2, segment.P1, segment.P2, out p1); p2 = Vector3D.DneVector(); } } else { if (SegmentType.Arc == segment.Type) { Circle tempCircle = segment.Circle; result = Euclidean2D.IntersectionCircleCircle(tempCircle, this, out p1, out p2); } else { result = Euclidean2D.IntersectionLineCircle(segment.P1, segment.P2, this, out p1, out p2); } } if (-1 == result) { return(null); } List <Vector3D> ret = new List <Vector3D>(); if (result >= 1 && segment.IsPointOn(p1)) { ret.Add(p1); } if (result >= 2 && segment.IsPointOn(p2)) { ret.Add(p2); } return(ret.ToArray()); }
/// <summary> /// Returns the 6 simplex edges in the UHS model. /// </summary> public static H3.Cell.Edge[] SimplexEdgesUHS(int p, int q, int r) { // Only implemented for honeycombs with hyperideal cells right now. if (!(Geometry2D.GetGeometry(p, q) == Geometry.Hyperbolic)) { throw new System.NotImplementedException(); } Sphere[] simplex = SimplexCalcs.Mirrors(p, q, r, moveToBall: false); Circle[] circles = simplex.Select(s => H3Models.UHS.IdealCircle(s)).ToArray(); Vector3D[] defPoints = new Vector3D[6]; Vector3D dummy; Euclidean2D.IntersectionLineCircle(circles[1].P1, circles[1].P2, circles[0], out defPoints[0], out dummy); Euclidean2D.IntersectionLineCircle(circles[2].P1, circles[2].P2, circles[0], out defPoints[1], out dummy); Euclidean2D.IntersectionLineCircle(circles[1].P1, circles[1].P2, circles[3], out defPoints[2], out dummy); Euclidean2D.IntersectionLineCircle(circles[2].P1, circles[2].P2, circles[3], out defPoints[3], out dummy); Circle3D c = simplex[0].Intersection(simplex[3]); Vector3D normal = c.Normal; normal.RotateXY(Math.PI / 2); Vector3D intersection; double height, off; Euclidean2D.IntersectionLineLine(c.Center, c.Center + normal, circles[1].P1, circles[1].P2, out intersection); off = (intersection - c.Center).Abs(); height = Math.Sqrt(c.Radius * c.Radius - off * off); intersection.Z = height; defPoints[4] = intersection; Euclidean2D.IntersectionLineLine(c.Center, c.Center + normal, circles[2].P1, circles[2].P2, out intersection); off = (intersection - c.Center).Abs(); height = Math.Sqrt(c.Radius * c.Radius - off * off); intersection.Z = height; defPoints[5] = intersection; // Hyperideal vertex too? bool order = false; H3.Cell.Edge[] edges = null; if (Geometry2D.GetGeometry(q, r) == Geometry.Hyperbolic) { edges = new H3.Cell.Edge[] { new H3.Cell.Edge(new Vector3D(), new Vector3D(0, 0, 10)), new H3.Cell.Edge(defPoints[4], defPoints[5], order), new H3.Cell.Edge(defPoints[0], defPoints[4], order), new H3.Cell.Edge(defPoints[1], defPoints[5], order), new H3.Cell.Edge(defPoints[2], defPoints[4], order), new H3.Cell.Edge(defPoints[3], defPoints[5], order), }; } else { Vector3D vPointUHS = H3Models.BallToUHS(VertexPointBall(p, q, r)); defPoints[0] = defPoints[1] = vPointUHS; edges = new H3.Cell.Edge[] { new H3.Cell.Edge(vPointUHS, new Vector3D(0, 0, 10)), new H3.Cell.Edge(defPoints[4], defPoints[5], order), new H3.Cell.Edge(defPoints[0], defPoints[4], order), new H3.Cell.Edge(defPoints[1], defPoints[5], order), new H3.Cell.Edge(defPoints[2], defPoints[4], order), new H3.Cell.Edge(defPoints[3], defPoints[5], order), }; } return(edges); }