private static bool EdgeOkUHS(H3.Cell.Edge edge, Circle region) { if (Tolerance.GreaterThan(edge.Start.Abs(), region.Radius) || Tolerance.GreaterThan(edge.End.Abs(), region.Radius)) { return(false); } return(EdgeOk(edge, m_params.UhsCutoff)); }
private static bool TetOk(Tet tet) { double cutoff = 0.95; foreach (Vector3D v in tet.Verts) { if (Tolerance.GreaterThan(v.Z, 0) || v.Abs() > cutoff) { return(false); } } return(true); }
/// <summary> /// Checks to see if two segments intersect. /// This does not actually calculate the intersection point. /// It uses information from the following paper: /// http://www.geometrictools.com/Documentation/DistanceLine3Line3.pdf /// </summary> public static bool DoSegmentsIntersect(Vector3D a1, Vector3D a2, Vector3D b1, Vector3D b2) { /* Our approach. * (1) Check if endpoints are on other segment. Note that this also checks if A endpoints equal B endpoints. * (2) Calc line-line distance. If > 0, we don't intersect. * (3) At this point, we only have to deal with non-parallel case in the paper, and only * need to determine if we are in "region 0" (we intersect) or not (we don't) */ // (1) if (PointOnSegment(a1, a2, b1) || PointOnSegment(a1, a2, b2) || PointOnSegment(b1, b2, a1) || PointOnSegment(b1, b2, a2)) { return(true); } // (2) Vector3D ma = a2 - a1; Vector3D mb = b2 - b1; if (Tolerance.GreaterThan(DistanceLineLine(ma, a1, mb, b1), 0)) { return(false); } // (3) Vector3D D = a1 - b1; double a = ma.Dot(ma); double b = -ma.Dot(mb); double c = mb.Dot(mb); double d = ma.Dot(D); double e = -mb.Dot(D); double det = a * c - b * b; double s = b * e - c * d; double t = b * d - a * e; if (s >= 0 && s <= det && t >= 0 && t <= det) { return(true); } return(false); }
public static Geometry GetGeometry(int p, int q, int r) { double t1 = Math.Sin(PiOverNSafe(p)) * Math.Sin(PiOverNSafe(r)); double t2 = Math.Cos(PiOverNSafe(q)); if (Tolerance.Equal(t1, t2)) { return(Geometry.Euclidean); } if (Tolerance.GreaterThan(t1, t2)) { return(Geometry.Spherical); } return(Geometry.Hyperbolic); }
public int Compare(Vector3D v1, Vector3D v2) { const int less = -1; const int greater = 1; if (Tolerance.LessThan(v1.X, v2.X)) { return(less); } if (Tolerance.GreaterThan(v1.X, v2.X)) { return(greater); } if (Tolerance.LessThan(v1.Y, v2.Y)) { return(less); } if (Tolerance.GreaterThan(v1.Y, v2.Y)) { return(greater); } if (Tolerance.LessThan(v1.Z, v2.Z)) { return(less); } if (Tolerance.GreaterThan(v1.Z, v2.Z)) { return(greater); } if (Tolerance.LessThan(v1.W, v2.W)) { return(less); } if (Tolerance.GreaterThan(v1.W, v2.W)) { return(greater); } // Making it here means we are equal. return(0); }
public static int IntersectionCircleCircle(Circle c1, Circle c2, out Vector3D p1, out Vector3D p2) { p1 = new Vector3D(); p2 = new Vector3D(); // A useful page describing the cases in this function is: // http://ozviz.wasp.uwa.edu.au/~pbourke/geometry/2circle/ p1.Empty(); p2.Empty(); // Vector and distance between the centers. Vector3D v = c2.Center - c1.Center; double d = v.Abs(); double r1 = c1.Radius; double r2 = c2.Radius; // Circle centers coincident. if (Tolerance.Zero(d)) { if (Tolerance.Equal(r1, r2)) { return(-1); } else { return(0); } } // We should be able to normalize at this point. if (!v.Normalize()) { Debug.Assert(false); return(0); } // No intersection points. // First case is disjoint circles. // Second case is where one circle contains the other. if (Tolerance.GreaterThan(d, r1 + r2) || Tolerance.LessThan(d, Math.Abs(r1 - r2))) { return(0); } // One intersection point. if (Tolerance.Equal(d, r1 + r2) || Tolerance.Equal(d, Math.Abs(r1 - r2))) { p1 = c1.Center + v * r1; return(1); } // There must be two intersection points. p1 = p2 = v * r1; double temp = (r1 * r1 - r2 * r2 + d * d) / (2 * d); double angle = Math.Acos(temp / r1); Debug.Assert(!Tolerance.Zero(angle) && !Tolerance.Equal(angle, Math.PI)); p1.RotateXY(angle); p2.RotateXY(-angle); p1 += c1.Center; p2 += c1.Center; return(2); }
/// <summary> /// Returns intersection points between a circle and a great circle. /// There may be 0, 1, or 2 intersection points. /// Returns false if the circle is the same as gc. /// </summary> static bool IntersectionCircleGC(Circle3D c, Vector3D gc, List <Vector3D> iPoints) { double radiusCosAngle = CosAngle(c.Normal, c.PointOnCircle); double radiusAngle = Math.Acos(radiusCosAngle); double radius = radiusAngle; // Since sphere radius is 1. // Find the great circle perpendicular to gc, and through the circle center. Vector3D gcPerp = c.Normal.Cross(gc); if (!gcPerp.Normalize()) { // Circles are parallel => Zero or infinity intersections. if (Tolerance.Equal(radius, Math.PI / 2)) { return(false); } return(true); } // Calculate the offset angle from the circle normal to the gc normal. double offsetAngle = c.Normal.AngleTo(gc); if (Tolerance.GreaterThan(offsetAngle, Math.PI / 2)) { gc *= -1; offsetAngle = c.Normal.AngleTo(gc); } double coAngle = Math.PI / 2 - offsetAngle; // No intersections. if (radiusAngle < coAngle) { return(true); } // Here is the perpendicular point on the great circle. Vector3D pointOnGC = c.Normal; pointOnGC.RotateAboutAxis(gcPerp, coAngle); // 1 intersection. if (Tolerance.Equal(radiusAngle, coAngle)) { iPoints.Add(pointOnGC); return(true); } // 2 intersections. // Spherical pythagorean theorem // http://en.wikipedia.org/wiki/Pythagorean_theorem#Spherical_geometry // We know the hypotenuse and one side. We need the third leg. // We do this calculation on a unit sphere, to get the result as a normalized cosine of an angle. double sideCosA = radiusCosAngle / Math.Cos(coAngle); double rot = Math.Acos(sideCosA); Vector3D i1 = pointOnGC, i2 = pointOnGC; i1.RotateAboutAxis(gc, rot); i2.RotateAboutAxis(gc, -rot); iPoints.Add(i1); iPoints.Add(i2); Circle3D test = new Circle3D { Normal = gc, Center = new Vector3D(), Radius = 1 }; return(true); }