public GregoryPatch(PatchCycle cycle, SceneData data) { this.cycle = cycle; this.data = data; centerPoint = data.CreateHiddenCatPoint(new Vector3()); adjacentPatches = new List <AdjacentHalfPatch>(cycle.Patches.Count); for (int i = 0; i < cycle.Patches.Count; i++) { adjacentPatches.Add(new AdjacentHalfPatch(cycle.Patches[i].GetDataBetweenPoints(cycle.Points[i], cycle.Points[(i + 1) % cycle.Points.Count]), data, centerPoint)); } for (int i = 0; i < adjacentPatches.Count; i++) { int l = i - 1; if (l < 0) { l += adjacentPatches.Count; } adjacentPatches[i].leftP1 = adjacentPatches[l].P1I; adjacentPatches[i].rightP1 = adjacentPatches[(i + 1) % adjacentPatches.Count].P1I; } Vector3 sum = new Vector3(); adjacentPatches.ForEach(x => sum += x.Q); sum /= adjacentPatches.Count; centerPoint.Position = sum; adjacentPatches.ForEach(x => x.CalculateP1()); gregoryPatches = new List <SingleGregoryPatch>(cycle.Patches.Count); for (int i = 0; i < adjacentPatches.Count; i++) { gregoryPatches.Add(new SingleGregoryPatch(this, adjacentPatches[i], adjacentPatches[(i + 1) % adjacentPatches.Count], centerPoint)); } }
public CuttingCurve(List <Vector4> points, IIntersectable P, IIntersectable Q, SceneData scene, bool cyclic, double minimumStep = 0.1) { this.Q = Q; this.P = P; this.scene = scene; this.cyclic = cyclic; this.points = new List <Vector4>(points.Count / 2); Vector3 prevPoint = P.GetPosition(points[0].X, points[0].Y); for (int i = 1; i < points.Count; i++) { var actualPoint = P.GetPosition(points[i].X, points[i].Y); if ((actualPoint - prevPoint).Length() > minimumStep) { prevPoint = actualPoint; this.points.Add(points[i]); } } if (this.points.Count < 2) { this.points.Add(points[points.Count - 1]); } catPoints = new List <CatPoint>(this.points.Count); foreach (var point in this.points) { var pos = P.GetPosition(point.X, point.Y); catPoints.Add(scene.CreateHiddenCatPoint(pos)); } indices.Clear(); indices.Add(0); for (int i = 1; i < this.points.Count - 1; i++) { indices.Add(i); indices.Add(i); } indices.Add(this.points.Count - 1); Console.WriteLine($"Cyclic: {cyclic}"); if (cyclic) { indices.Add(this.points.Count - 1); indices.Add(0); } IsIntersectableP = CalculatePolygon(true, out pPolygon, out pPolygonBoundary); IsIntersectableQ = CalculatePolygon(false, out qPolygon, out qPolygonBoundary); if (IsIntersectableQ) { QtestSet = new bool[100, 100]; for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { QtestSet[i, j] = true; } } PointsContainedByCurve(QtestSet, true, Q, 0, Q.FirstParamLimit, 0, Q.SecondParamLimit, true); } }
//private static SceneData _data; public static List <Vector4> Intersect(IIntersectable P, IIntersectable Q, SceneData scene, double newtonStep, out bool cycleIntersection) { if (P == null) { throw new ArgumentNullException(nameof(P)); } if (Q == null) { throw new ArgumentNullException(nameof(Q)); } double d = newtonStep; cycleIntersection = false; //_data = scene; int number = 32; var pPoints = P.GetPointsForSearch(number, number).ToList(); var qPoints = Q.GetPointsForSearch(number, number).ToList(); var closestDistance = double.MaxValue; var pPoint = new ParametrizedPoint(); var qPoint = new ParametrizedPoint(); if (scene.Cursor.Visible) { var cursorPos = scene.Cursor.Transform.Position; foreach (var pP in pPoints) { if ((pP.Position - cursorPos).LengthSquared() < closestDistance) { closestDistance = (pP.Position - cursorPos).LengthSquared(); pPoint = pP; } } closestDistance = double.MaxValue; foreach (var qP in qPoints) { if ((qP.Position - cursorPos).LengthSquared() < closestDistance) { closestDistance = (qP.Position - cursorPos).LengthSquared(); qPoint = qP; } } } else { foreach (var pP in pPoints) { foreach (var qP in qPoints) { if ((qP.Position - pP.Position).LengthSquared() < closestDistance) { closestDistance = (qP.Position - pP.Position).LengthSquared(); pPoint = pP; qPoint = qP; } } } } Func <Vector4, double> distanceFun = arg => (P.GetPosition(arg.X, arg.Y) - Q.GetPosition(arg.Z, arg.W)).LengthSquared(); Func <Vector4, Vector4> distanceGradient = arg => { var diff = P.GetPosition(arg.X, arg.Y) - Q.GetPosition(arg.Z, arg.W); var du = P.GetFirstParamDerivative(arg.X, arg.Y); var dv = P.GetSecondParamDerivative(arg.X, arg.Y); var ds = Q.GetFirstParamDerivative(arg.Z, arg.W); var dt = Q.GetSecondParamDerivative(arg.Z, arg.W); return(new Vector4(Vector3.DotProduct(diff, du), Vector3.DotProduct(diff, dv), -Vector3.DotProduct(diff, ds), -Vector3.DotProduct(diff, dt)) * 2.0); }; var startPoint = SimpleGradient(scene, distanceFun, distanceGradient, pPoint, qPoint, P, Q); if (startPoint == null) { return(null); } scene.CreateHiddenCatPoint(P.GetPosition(startPoint.Value.X, startPoint.Value.Y)); Func <Vector4, bool, Tuple <Matrix4, Vector3> > jacobian = (arg, invert) => { var du = P.GetFirstParamDerivative(arg.X, arg.Y); var dv = P.GetSecondParamDerivative(arg.X, arg.Y); var ds = Q.GetFirstParamDerivative(arg.Z, arg.W); var dt = Q.GetSecondParamDerivative(arg.Z, arg.W); Matrix4 jacob = new Matrix4 {
public AdjacentHalfPatch(HalfPatchData halfPatch, SceneData scene, CatPoint centerPoint) { this.data = halfPatch; this.scene = scene; this.centerPoint = centerPoint; LeftNearest = new CatPoint[4]; LeftBack = new CatPoint[3]; RightNearest = new CatPoint[4]; RightBack = new CatPoint[3]; LeftNearest[0] = halfPatch.Nearest[0]; RightNearest[3] = halfPatch.Nearest[3]; for (int i = 0; i < 3; i++) { LeftNearest[i + 1] = scene.CreateHiddenCatPoint(new Vector3()); } RightNearest[0] = LeftNearest[3]; for (int i = 0; i < 2; i++) { RightNearest[i + 1] = scene.CreateHiddenCatPoint(new Vector3()); } for (int i = 0; i < 2; i++) { LeftBack[i] = scene.CreateHiddenCatPoint(new Vector3()); RightBack[i + 1] = scene.CreateHiddenCatPoint(new Vector3()); } LeftBack[2] = RightBack[0] = scene.CreateHiddenCatPoint(new Vector3()); for (int i = 0; i < 4; i++) { halfPatch.Nearest[i].OnChanged += AdjacentHalfPatch_OnChanged; halfPatch.Back[i].OnChanged += AdjacentHalfPatch_OnChanged; } centerPoint.OnChanged += AdjacentHalfPatch_OnChanged; P1I = scene.CreateHiddenCatPoint(new Vector3()); //P1I.W = 6; changed = true; ActualizePositions(); NormalL1 = scene.CreateHiddenCatPoint(new Vector3()); NormalR1 = scene.CreateHiddenCatPoint(new Vector3()); renderPoints = new List <CatPoint> { LeftNearest[0], LeftNearest[1], LeftBack[0], LeftNearest[2], LeftBack[1], LeftNearest[3], LeftBack[2], RightNearest[1], RightBack[1], RightNearest[2], RightBack[2], RightNearest[3], P1I, centerPoint, NormalL1, NormalR1, }; }