private static Vector3D[] CalcViaProjections(Vector3D p1, Vector3D p2, Vector3D p3, int divisions, Geometry g) { Vector3D h1 = Sterographic.PlaneToHyperboloid(p1); Vector3D h2 = Sterographic.PlaneToHyperboloid(p2); Vector3D h3 = Sterographic.PlaneToHyperboloid(p3); List <Vector3D> temp = new List <Vector3D>(); Segment seg1 = Segment.Line(h1, h2); Segment seg2 = Segment.Line(h3, h2); Vector3D[] s1 = seg1.Subdivide(divisions); Vector3D[] s2 = seg2.Subdivide(divisions); for (int i = 0; i < divisions; i++) { Segment seg = Segment.Line(s1[i], s2[i]); temp.AddRange(seg.Subdivide(divisions - i)); } temp.Add(h2); List <Vector3D> result = new List <Vector3D>(); foreach (Vector3D v in temp) { Vector3D copy = v; Sterographic.NormalizeToHyperboloid(ref copy); result.Add(Sterographic.HyperboloidToPlane(copy)); } return(result.ToArray()); }
public static Vector3D[] CalcViaProjections(Vector3D p1, Vector3D p2, Vector3D p3, int divisions, Geometry g) { if (g == Geometry.Euclidean) { throw new System.NotImplementedException(); } Vector3D h1 = new Vector3D(), h2 = new Vector3D(), h3 = new Vector3D(); if (g == Geometry.Hyperbolic) { h1 = Sterographic.PlaneToHyperboloid(p1); h2 = Sterographic.PlaneToHyperboloid(p2); h3 = Sterographic.PlaneToHyperboloid(p3); } else if (g == Geometry.Spherical) { h1 = Sterographic.PlaneToSphereSafe(p1); h2 = Sterographic.PlaneToSphereSafe(p2); h3 = Sterographic.PlaneToSphereSafe(p3); } List <Vector3D> temp = new List <Vector3D>(); Segment seg1 = Segment.Line(h1, h2); Segment seg2 = Segment.Line(h3, h2); Vector3D[] s1 = seg1.Subdivide(divisions); Vector3D[] s2 = seg2.Subdivide(divisions); for (int i = 0; i < divisions; i++) { Segment seg = Segment.Line(s1[i], s2[i]); temp.AddRange(seg.Subdivide(divisions - i)); } temp.Add(h2); List <Vector3D> result = new List <Vector3D>(); foreach (Vector3D v in temp) { Vector3D copy = v; if (g == Geometry.Hyperbolic) { Sterographic.NormalizeToHyperboloid(ref copy); result.Add(Sterographic.HyperboloidToPlane(copy)); } else if (g == Geometry.Spherical) { copy.Normalize(); result.Add(Sterographic.SphereToPlane(copy)); } } return(result.ToArray()); }
public static Vector3D Centroid(Geometry g, Vector3D[] conformalVerts) { if (g == Geometry.Euclidean) { Vector3D result = new Vector3D(); foreach (Vector3D v in conformalVerts) { result += v; } return(result / conformalVerts.Length); } Vector3D[] verts = conformalVerts.Select(v => { switch (g) { case Geometry.Spherical: return(Sterographic.PlaneToSphereSafe(v)); case Geometry.Hyperbolic: return(Sterographic.PlaneToHyperboloid(v)); } throw new System.ArgumentException(); }).ToArray(); // https://math.stackexchange.com/a/2173370/300001 Vector3D sum = new Vector3D(); for (int i = 0; i < verts.Length; i++) { sum += verts[i]; } Vector3D centroid = sum / Math.Sqrt(DotInGeometry(g, sum, sum)); NormalizeInGeometry(g, ref centroid); switch (g) { case Geometry.Spherical: return(Sterographic.SphereToPlane(centroid)); case Geometry.Hyperbolic: return(Sterographic.HyperboloidToPlane(centroid)); } throw new System.ArgumentException(); }