private static void GenerateCurveTriangles(List <CurveTriangle> curveTriangles, Curve curve, double halfWidth, double prevAngle, double nextAngle) { // First, to generate the curve, pick the polygons var poly = curve.CurveVertices; // Fall back to line triangles if (poly.Length < 3) { return; } // Pick three vertices Double2 a = poly[0].Position, b = poly[1].Position, c = poly[2].Position; Double4 ta = poly[0].CurveCoords, tb = poly[1].CurveCoords, tc = poly[2].CurveCoords; var k = (b - a).Cross(c - a); // Generate extrusion CurveVertex Extrapolate(Double2 x) { var u = (x - a).Cross(c - a) / k; var v = -(x - a).Cross(b - a) / k; return(new CurveVertex(x, ta + u * (tb - ta) + v * (tc - ta))); } // The curve's entry angle and exit angle var entryAngle = curve.EntryAngle; var exitAngle = curve.ExitAngle; // Generate the polygon list var list = new List <Double2>(poly.Length + 4); // Add the vertex extremes AddExtremeVertex(list, halfWidth, poly[0].Position, prevAngle, entryAngle, true); // The order of the points is different for whether the curve is convex or not // Concave is: start - end - controls (reversed) // Convex is: start - controls - end if (!curve.IsConvex) { AddExtremeVertex(list, halfWidth, poly[poly.Length - 1].Position, exitAngle, nextAngle, false); Array.Reverse(poly); } // Extrapolate each vertex for (int i = 1; i < poly.Length - 1; i++) { var dv1 = (poly[i - 1].Position - poly[i].Position).Normalized; var dv2 = (poly[i + 1].Position - poly[i].Position).Normalized; // Use the half-arc sine rule here to calcualte the tangent vector var sec = 1 / Math.Sqrt(0.5 - 0.5 * dv1.Dot(dv2)); if (true) { list.Add(poly[i].Position + halfWidth * dv1.Rotate(Pi_2)); list.Add(poly[i].Position - halfWidth * dv2.Rotate(Pi_2)); } else { list.Add(poly[i].Position - halfWidth * sec * (dv1 + dv2).Normalized); } } if (curve.IsConvex) { AddExtremeVertex(list, halfWidth, poly[poly.Length - 1].Position, exitAngle, nextAngle, false); } // Triangulate the extrapolated list curveTriangles.AddRange(CurveVertex.MakeTriangleFan(list.Select(Extrapolate).ToArray())); }
public double DistanceSquaredTo(Double4 o) => (o - this).LengthSquared;
public double DistanceTo(Double4 o) => (o - this).Length;
public double Dot(Double4 o) => X * o.X + Y * o.Y + Z * o.Z + W * o.W;