public static AngleToCounterClock ( Vector3D v1, Vector3D v2 ) : double | ||
v1 | Vector3D | |
v2 | Vector3D | |
Résultat | double |
/// <summary> /// Checks to see if two points are ordered on this segment, that is: /// P1 -> test1 -> test2 -> P2 returns true. /// P1 -> test2 -> test1 -> P2 returns false; /// Also returns false if test1 or test2 are equal, not on the segment, or are an endpoint. /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <returns></returns> public bool Ordered(Vector3D test1, Vector3D test2) { if (test1.Compare(test2)) { Debug.Assert(false); return(false); } if (!IsPointOn(test1) || !IsPointOn(test2)) { Debug.Assert(false); return(false); } if (test1.Compare(P1) || test1.Compare(P2) || test2.Compare(P1) || test2.Compare(P2)) { return(false); } if (SegmentType.Arc == Type) { Vector3D t1 = P1 - Center; Vector3D t2 = test1 - Center; Vector3D t3 = test2 - Center; double a1 = Clockwise ? Euclidean2D.AngleToClock(t1, t2) : Euclidean2D.AngleToCounterClock(t1, t2); double a2 = Clockwise ? Euclidean2D.AngleToClock(t1, t3) : Euclidean2D.AngleToCounterClock(t1, t3); return(a1 < a2); } else { double d1 = (test1 - P1).MagSquared(); double d2 = (test2 - P1).MagSquared(); return(d1 < d2); } }
private static bool PointOnArcSegment(Vector3D p, Segment seg) { double maxAngle = seg.Angle; Vector3D v1 = seg.P1 - seg.Center; Vector3D v2 = p - seg.Center; Debug.Assert(Tolerance.Equal(v1.Abs(), v2.Abs())); double angle = seg.Clockwise ? Euclidean2D.AngleToClock(v1, v2) : Euclidean2D.AngleToCounterClock(v1, v2); return(Tolerance.LessThanOrEqual(angle, maxAngle)); }
private static double StereoToEquidistant(double dist) { if (Infinity.IsInfinite(dist)) { return(1); } double dot = dist * dist; // X^2 + Y^2 + Z^2 double w = (dot - 1) / (dot + 1); double x = Math.Sqrt(1 - w * w); double r = Euclidean2D.AngleToCounterClock(new Vector3D(0, -1), new Vector3D(x, w)); return(r / Math.PI); }
/// <summary> /// Apply a transform to us. /// </summary> private void TransformInternal <T>(T transform) where T : ITransform { // NOTES: // Arcs can go to lines, and lines to arcs. // Rotations may reverse arc directions as well. // Arc centers can't be transformed directly. // NOTE: We must calc this before altering the endpoints. Vector3D mid = Midpoint; if (Infinity.IsInfinite(mid)) { mid = Infinity.IsInfinite(P1) ? P2 * Infinity.FiniteScale : P1 * Infinity.FiniteScale; } P1 = transform.Apply(P1); P2 = transform.Apply(P2); mid = transform.Apply(mid); // Can we make a circle out of the transformed points? Circle temp = new Circle(); if (!Infinity.IsInfinite(P1) && !Infinity.IsInfinite(P2) && !Infinity.IsInfinite(mid) && temp.From3Points(P1, mid, P2)) { Type = SegmentType.Arc; Center = temp.Center; // Work out the orientation of the arc. Vector3D t1 = P1 - Center; Vector3D t2 = mid - Center; Vector3D t3 = P2 - Center; double a1 = Euclidean2D.AngleToCounterClock(t2, t1); double a2 = Euclidean2D.AngleToCounterClock(t3, t1); Clockwise = a2 > a1; } else { // The circle construction fails if the points // are colinear (if the arc has been transformed into a line). Type = SegmentType.Line; // XXX - need to do something about this. // Turn into 2 segments? //if( isInfinite( mid ) ) // Actually the check should just be whether mid is between p1 and p2. } }
/// <summary> /// Maps a point in a rhombus to a point in the unit square, via a simple affine transformation. /// b1 and b2 are the two basis vectors of the rhombus. /// Does not currently check the input point. /// </summary> public static Vector3D MapRhombusToUnitSquare(Vector3D b1, Vector3D b2, Vector3D v) { double a = Euclidean2D.AngleToCounterClock(b1, new Vector3D(1, 0)); v.RotateXY(a); b1.RotateXY(a); b2.RotateXY(a); // Shear v.X -= b2.X * (v.Y / b2.Y); // Scale x and y. v.X /= b1.X; v.Y /= b2.Y; return(v); }