| | | 1 | | //======================================================================= |
| | | 2 | | // SegmentConeSurfaceGeometry.cs |
| | | 3 | | //======================================================================= |
| | | 4 | | // MIT License, Copyright (c) 2024-present David Oravsky (mrdav30) |
| | | 5 | | // See LICENSE file in the project root for full license information. |
| | | 6 | | //======================================================================= |
| | | 7 | | |
| | | 8 | | using System; |
| | | 9 | | using static FixedMathSharp.Geometry.CylinderContactAlgebra; |
| | | 10 | | using static FixedMathSharp.Geometry.ContactQuadratic; |
| | | 11 | | |
| | | 12 | | namespace FixedMathSharp.Geometry; |
| | | 13 | | |
| | | 14 | | /// <summary>One exact centered frame shared by the segment's support charts.</summary> |
| | | 15 | | internal readonly struct SegmentConeSurfaceGeometry |
| | | 16 | | { |
| | | 17 | | internal readonly SegmentConeSurfaceInput Input; |
| | | 18 | | internal readonly ConeFiniteSectionFrame Finite; |
| | | 19 | | internal readonly WideDirection3d A, B, Edge, BaseOffset; |
| | | 20 | | internal readonly Signed576 Radius; |
| | | 21 | | // Affine coordinates have at most 306 bits, dots at most 615. Weighted |
| | | 22 | | // points can exceed 832 bits and remain in the existing borrowed banks. |
| | | 23 | | internal readonly Signed320 RawScale; |
| | | 24 | | internal readonly Signed576 Cap; |
| | 2134 | 25 | | internal Signed576 FullHeight => WideArithmetic.AddSigned576(Cap, Cap); |
| | 17281 | 26 | | internal int Words => Input.Words; |
| | 8345 | 27 | | internal int FamilyWords => Input.FamilyWords; |
| | 18 | 28 | | internal int ValueWords => Input.ValueWords; |
| | | 29 | | internal readonly int ValueShift; |
| | | 30 | | |
| | | 31 | | internal SegmentConeSurfaceGeometry(in SegmentConeSurfaceInput input) |
| | | 32 | | { |
| | 2094 | 33 | | Input = input; |
| | 2094 | 34 | | Finite = input.HasSourceFrame |
| | 2094 | 35 | | ? new ConeFiniteSectionFrame(input.SourceFrame, input.Center, input.ConeRotation, input.Height, input.Radius |
| | 2094 | 36 | | : new ConeFiniteSectionFrame(input.Origin, input.Rotation, input.Center, input.ConeRotation, input.Height, i |
| | 4188 | 37 | | WideAxis3 first = Finite.ShapeFrame.Transform(input.Segment.Start), second = Finite.ShapeFrame.Transform(input.S |
| | 2094 | 38 | | Span<Signed320> components = stackalloc Signed320[9] |
| | 2094 | 39 | | { |
| | 2094 | 40 | | WideArithmetic.AddSigned320(Finite.ShapeFrame.CoordinateDenominator, Finite.ShapeFrame.CoordinateDenominator |
| | 2094 | 41 | | first.X, first.Y, first.Z, second.X, second.Y, second.Z, Finite.ShapeFrame.Cap, |
| | 2094 | 42 | | Signed320.NarrowValue(WideArithmetic.MultiplySigned320(Finite.ShapeFrame.CoordinateDenominator, Finite.Shape |
| | 2094 | 43 | | }; |
| | | 44 | | // One common reduction preserves the entire line and shape together. |
| | | 45 | | // It removes harmless composed-frame factors before fixed-degree charts. |
| | 2118 | 46 | | if (input.IsAffine) WideArithmetic.ReduceCommonScale(components); |
| | 6282 | 47 | | RawScale = components[0]; A = new(components[1], components[2], components[3]); B = new(components[4], component |
| | 4188 | 48 | | Cap = Signed576.ExtendValue(components[7]); Radius = Signed576.ExtendValue(components[8]); |
| | 2094 | 49 | | Edge = TriangleCircularGeometry.Subtract(B, A); |
| | 2094 | 50 | | BaseOffset = new(A.X, WideArithmetic.AddSigned576(A.Y, Cap), A.Z); |
| | 2094 | 51 | | Span<Signed576> coordinates = stackalloc Signed576[8] |
| | 2094 | 52 | | { A.X, A.Y, A.Z, B.X, B.Y, B.Z, Cap, Radius }; |
| | 2094 | 53 | | ValueShift = TriangleCircularGeometry.GetValueShift(coordinates, 4); |
| | 2094 | 54 | | } |
| | | 55 | | } |