private static BezierSegment3D[] TestAxeSimple2_Segments(Curves_AxeSimple2 arg) { Point3D[] points = arg.GetAllPoints(); // Top BezierSegment3D top = new BezierSegment3D(arg.IndexTL, arg.IndexTR, null, points); // Edge Point3D controlTR = BezierUtil.GetControlPoint_End(arg.EndTR, arg.EndBR, arg.EndBL_1, true, arg.EdgeAngleT, arg.EdgePercentT); Point3D controlBR = BezierUtil.GetControlPoint_End(arg.EndBR, arg.EndTR, arg.EndTL, true, arg.EdgeAngleB, arg.EdgePercentB); BezierSegment3D edge = new BezierSegment3D(arg.IndexTR, arg.IndexBR, new[] { controlTR, controlBR }, points); // Bottom (right portion) BezierSegment3D bottomRight = null; if (arg.EndBL_2 == null) { Point3D controlR = BezierUtil.GetControlPoint_End(arg.EndBR, arg.EndBL_1, arg.EndTR, false, arg.B1AngleR, arg.B1PercentR); Point3D controlL = BezierUtil.GetControlPoint_End(arg.EndBL_1, arg.EndBR, arg.EndTR, false, arg.B1AngleL, arg.B1PercentL); bottomRight = new BezierSegment3D(arg.IndexBR, arg.IndexBL_1, new[] { controlR, controlL }, points); } else { bottomRight = new BezierSegment3D(arg.IndexBR, arg.IndexBL_1, null, points); } // Bottom (left portion) BezierSegment3D bottomLeft = null; if (arg.EndBL_2 != null) { Point3D controlR = BezierUtil.GetControlPoint_End(arg.EndBL_1, arg.EndBL_2.Value, arg.EndTR, false, arg.B2AngleR, arg.B2PercentR); Point3D controlL = BezierUtil.GetControlPoint_End(arg.EndBL_2.Value, arg.EndBL_1, arg.EndTR, false, arg.B2AngleL, arg.B2PercentL); bottomLeft = new BezierSegment3D(arg.IndexBL_1, arg.IndexBL_2, new[] { controlR, controlL }, points); } return UtilityCore.Iterate<BezierSegment3D>(top, edge, bottomRight, bottomLeft).ToArray(); }
private void TestAxeSimple2(Curves_AxeSimple2 arg) { BezierSegment3D[][] segmentSets = new BezierSegment3D[5][]; Curves_AxeSimple2[] argLevels = new Curves_AxeSimple2[5]; argLevels[2] = arg; // Edge #region Middle argLevels[1] = UtilityCore.Clone(arg); // Right argLevels[1].EndTR = new Point3D(argLevels[1].EndTR.X * .8, argLevels[1].EndTR.Y * .9, .15); Vector3D offsetTR = new Point3D(argLevels[1].EndTR.X, argLevels[1].EndTR.Y, 0) - arg.EndTR; Quaternion angleTR = Math3D.GetRotation((arg.EndTL - arg.EndTR), offsetTR); Vector3D rotated = (arg.EndBL_1 - arg.EndBR).ToUnit() * offsetTR.Length; rotated = rotated.GetRotatedVector(angleTR.Axis, angleTR.Angle * -1.3); argLevels[1].EndBR = new Point3D(argLevels[1].EndBR.X + rotated.X, argLevels[1].EndBR.Y + rotated.Y, .15); // can't just use percents of coordinates. Instead use the same offset angle,distance that top left had // Left argLevels[1].EndTL = new Point3D(argLevels[1].EndTL.X, argLevels[1].EndTL.Y * .95, .3); if (argLevels[1].EndBL_2 == null) { argLevels[1].EndBL_1 = new Point3D(argLevels[1].EndBL_1.X, argLevels[1].EndBL_1.Y * .9, .3); } else { Vector3D offsetBL1 = arg.EndBR - arg.EndBL_1; double lengthBL1 = (new Point3D(argLevels[1].EndBR.X, argLevels[1].EndBR.Y, 0) - arg.EndBR).Length; offsetBL1 = offsetBL1.ToUnit() * (offsetBL1.Length - lengthBL1); argLevels[1].EndBL_1 = argLevels[1].EndBR - offsetBL1; argLevels[1].EndBL_1 = new Point3D(argLevels[1].EndBL_1.X, argLevels[1].EndBL_1.Y, .18); argLevels[1].EndBL_2 = new Point3D(argLevels[1].EndBL_2.Value.X, argLevels[1].EndBL_2.Value.Y * .9, .3); } argLevels[3] = argLevels[1].CloneNegateZ(); #endregion #region Far argLevels[0] = UtilityCore.Clone(arg); argLevels[0].EndTL = new Point3D(argLevels[0].EndTL.X, argLevels[0].EndTL.Y * .7, .4); argLevels[0].EndTR = new Point3D(argLevels[0].EndTR.X * .5, argLevels[0].EndTR.Y * .6, .25); if (argLevels[0].EndBL_2 == null) { argLevels[0].EndBR = new Point3D(argLevels[0].EndBR.X * .5, argLevels[0].EndBR.Y * .6, .25); argLevels[0].EndBL_1 = new Point3D(argLevels[0].EndBL_1.X, argLevels[0].EndBL_1.Y * .6, .4); } else { // Bottom Right Vector3D offset = (argLevels[1].EndBR - argLevels[1].EndBL_1) * .5; Point3D startPoint = argLevels[1].EndBL_1 + offset; // midway along bottom edge offset = argLevels[1].EndTR - startPoint; argLevels[0].EndBR = startPoint + (offset * .15); // from midway point toward upper right point argLevels[0].EndBR = new Point3D(argLevels[0].EndBR.X, argLevels[0].EndBR.Y, .25); // fix z // Left of bottom right (where the circle cutout ends) offset = argLevels[1].EndBR - argLevels[1].EndBL_1; argLevels[0].EndBL_1 = Math3D.GetClosestPoint_Line_Point(argLevels[0].EndBR, offset, argLevels[0].EndBL_1); offset *= .05; Point3D minBL1 = argLevels[0].EndBR - offset; Vector3D testOffset = argLevels[0].EndBL_1 - argLevels[0].EndBR; if (Vector3D.DotProduct(testOffset, offset) < 0 || testOffset.LengthSquared < offset.LengthSquared) { argLevels[0].EndBL_1 = minBL1; } // Bottom Left argLevels[0].EndBL_2 = new Point3D(argLevels[0].EndBL_2.Value.X, argLevels[0].EndBL_2.Value.Y * .6, .4); // Reduce the curve a bit argLevels[0].B2AngleL = argLevels[0].B2AngleL * .9; argLevels[0].B2PercentL = argLevels[0].B2PercentL * .95; argLevels[0].B2AngleR = argLevels[0].B2AngleR * .85; argLevels[0].B2PercentR = argLevels[0].B2PercentR * .95; } argLevels[4] = argLevels[0].CloneNegateZ(); #endregion PrepFor3D(); #region Lines for (int cntr = 0; cntr < 5; cntr++) { if (!chkAxe3D.IsChecked.Value && cntr != 2) { continue; } Curves_AxeSimple2 argCurrent = argLevels[cntr]; BezierSegment3D[] segments = TestAxeSimple2_Segments(argCurrent); segmentSets[cntr] = segments; DrawBezierLines(segments, chkAxeLine.IsChecked.Value, chkAxeControl.IsChecked.Value, chkAxeEnd.IsChecked.Value); } #endregion #region Plates if (chkAxe3D.IsChecked.Value) { Color edgeColor = Colors.GhostWhite; Color middleColor = Colors.DimGray; int numSegments = segmentSets[0].Length; int squareCount = 20; // Z to Z DrawBezierPlates(squareCount, segmentSets[0], segmentSets[1], middleColor, false); if (numSegments == 3) { DrawBezierPlates(squareCount, new[] { segmentSets[1][0], segmentSets[1][2] }, new[] { segmentSets[2][0], segmentSets[2][2] }, middleColor, false); DrawBezierPlate(squareCount, segmentSets[1][1], segmentSets[2][1], edgeColor, true); DrawBezierPlates(squareCount, new[] { segmentSets[2][0], segmentSets[2][2] }, new[] { segmentSets[3][0], segmentSets[3][2] }, middleColor, false); DrawBezierPlate(squareCount, segmentSets[2][1], segmentSets[3][1], edgeColor, true); } else { DrawBezierPlates(squareCount, new[] { segmentSets[1][0], segmentSets[1][3] }, new[] { segmentSets[2][0], segmentSets[2][3] }, middleColor, false); DrawBezierPlates(squareCount, new[] { segmentSets[1][1], segmentSets[1][2] }, new[] { segmentSets[2][1], segmentSets[2][2] }, edgeColor, true); DrawBezierPlates(squareCount, new[] { segmentSets[2][0], segmentSets[2][3] }, new[] { segmentSets[3][0], segmentSets[3][3] }, middleColor, false); DrawBezierPlates(squareCount, new[] { segmentSets[2][1], segmentSets[2][2] }, new[] { segmentSets[3][1], segmentSets[3][2] }, edgeColor, true); } DrawBezierPlates(squareCount, segmentSets[3], segmentSets[4], middleColor, false); // End cap plates for (int cntr = 0; cntr < 2; cntr++) { int index = cntr == 0 ? 0 : 4; // Turn the end cap into a polygon, then triangulate it Point3D[] endCapPoly = BezierUtil.GetPath(squareCount, segmentSets[index].Select(o => new[] { o }).ToArray()); // Call the jagged array overload so that the individual bezier end points don't get smoothed out TriangleIndexed[] endCapTriangles = Math2D.GetTrianglesFromConcavePoly3D(endCapPoly); if (cntr == 0) { endCapTriangles = endCapTriangles.Select(o => new TriangleIndexed(o.Index0, o.Index2, o.Index1, o.AllPoints)).ToArray(); // need to do this so the normals point in the proper direction } DrawPolyPlate(endCapTriangles, middleColor, false); //AddLines(endCapTriangles.Select(o => Tuple.Create(o.GetCenterPoint(), o.GetCenterPoint() + o.Normal)), _controlLineC, 2); } } #endregion }
private void btnAvgPlane_Click(object sender, RoutedEventArgs e) { try { Curves_AxeSimple2 arg = new Curves_AxeSimple2(false); Curves_AxeSimple2[] argLevels = new Curves_AxeSimple2[5]; argLevels[2] = arg; // Edge #region Middle argLevels[1] = UtilityCore.Clone(arg); // Right argLevels[1].EndTR = new Point3D(argLevels[1].EndTR.X * .8, argLevels[1].EndTR.Y * .9, .15); Vector3D offsetTR = new Point3D(argLevels[1].EndTR.X, argLevels[1].EndTR.Y, 0) - arg.EndTR; Quaternion angleTR = Math3D.GetRotation((arg.EndTL - arg.EndTR), offsetTR); Vector3D rotated = (arg.EndBL_1 - arg.EndBR).ToUnit() * offsetTR.Length; rotated = rotated.GetRotatedVector(angleTR.Axis, angleTR.Angle * -1.3); argLevels[1].EndBR = new Point3D(argLevels[1].EndBR.X + rotated.X, argLevels[1].EndBR.Y + rotated.Y, .15); // can't just use percents of coordinates. Instead use the same offset angle,distance that top left had // Left argLevels[1].EndTL = new Point3D(argLevels[1].EndTL.X, argLevels[1].EndTL.Y * .95, .3); if (argLevels[1].EndBL_2 == null) { argLevels[1].EndBL_1 = new Point3D(argLevels[1].EndBL_1.X, argLevels[1].EndBL_1.Y * .9, .3); } else { Vector3D offsetBL1 = arg.EndBR - arg.EndBL_1; double lengthBL1 = (new Point3D(argLevels[1].EndBR.X, argLevels[1].EndBR.Y, 0) - arg.EndBR).Length; offsetBL1 = offsetBL1.ToUnit() * (offsetBL1.Length - lengthBL1); argLevels[1].EndBL_1 = argLevels[1].EndBR - offsetBL1; argLevels[1].EndBL_1 = new Point3D(argLevels[1].EndBL_1.X, argLevels[1].EndBL_1.Y, .18); argLevels[1].EndBL_2 = new Point3D(argLevels[1].EndBL_2.Value.X, argLevels[1].EndBL_2.Value.Y * .9, .3); } argLevels[3] = argLevels[1].CloneNegateZ(); #endregion #region Far argLevels[0] = UtilityCore.Clone(arg); //argLevels[0].EndTL = new Point3D(argLevels[0].EndTL.X, argLevels[0].EndTL.Y * .7, .4); argLevels[0].EndTL = new Point3D(argLevels[0].EndTL.X, argLevels[0].EndTL.Y * .7, .5); //argLevels[0].EndTR = new Point3D(argLevels[0].EndTR.X * .5, argLevels[0].EndTR.Y * .6, .25); argLevels[0].EndTR = new Point3D(argLevels[0].EndTR.X * .5, argLevels[0].EndTR.Y * .6, -.25); if (argLevels[0].EndBL_2 == null) { argLevels[0].EndBR = new Point3D(argLevels[0].EndBR.X * .5, argLevels[0].EndBR.Y * .6, .25); argLevels[0].EndBL_1 = new Point3D(argLevels[0].EndBL_1.X, argLevels[0].EndBL_1.Y * .6, .4); } else { // Bottom Right Vector3D offset = (argLevels[1].EndBR - argLevels[1].EndBL_1) * .5; Point3D startPoint = argLevels[1].EndBL_1 + offset; // midway along bottom edge offset = argLevels[1].EndTR - startPoint; argLevels[0].EndBR = startPoint + (offset * .15); // from midway point toward upper right point argLevels[0].EndBR = new Point3D(argLevels[0].EndBR.X, argLevels[0].EndBR.Y, .25); // fix z // Left of bottom right (where the circle cutout ends) offset = argLevels[1].EndBR - argLevels[1].EndBL_1; argLevels[0].EndBL_1 = Math3D.GetClosestPoint_Line_Point(argLevels[0].EndBR, offset, argLevels[0].EndBL_1); offset *= .05; Point3D minBL1 = argLevels[0].EndBR - offset; Vector3D testOffset = argLevels[0].EndBL_1 - argLevels[0].EndBR; if (Vector3D.DotProduct(testOffset, offset) < 0 || testOffset.LengthSquared < offset.LengthSquared) { argLevels[0].EndBL_1 = minBL1; } // Bottom Left argLevels[0].EndBL_2 = new Point3D(argLevels[0].EndBL_2.Value.X, argLevels[0].EndBL_2.Value.Y * .6, .4); // Reduce the curve a bit argLevels[0].B2AngleL = argLevels[0].B2AngleL * .9; argLevels[0].B2PercentL = argLevels[0].B2PercentL * .95; argLevels[0].B2AngleR = argLevels[0].B2AngleR * .85; argLevels[0].B2PercentR = argLevels[0].B2PercentR * .95; } argLevels[4] = argLevels[0].CloneNegateZ(); #endregion #region Get polygon points BezierSegment3D[] segments = TestAxeSimple2_Segments(argLevels[0]); List<Point3D> pointsDupes = new List<Point3D>(); foreach (BezierSegment3D bezier in segments) { pointsDupes.AddRange(BezierUtil.GetPoints(5, bezier)); } List<Point3D> points = new List<Point3D>(); points.Add(pointsDupes[0]); for (int cntr = 1; cntr < pointsDupes.Count; cntr++) { if (!Math3D.IsNearValue(pointsDupes[cntr], pointsDupes[cntr - 1])) { points.Add(pointsDupes[cntr]); } } #endregion //ITriangle plane = AveragePlaneTests.GetAveragePlane(points.ToArray()); ITriangle plane = Math2D.GetPlane_Average(points.ToArray()); PrepFor3D(); foreach (Point3D point in points) { AddDot(point, _endPointC, .0125); AddLine(point, Math3D.GetClosestPoint_Plane_Point(plane, point), _controlPointC, 2); } //------------------------- //List<Point3D> upPoints = new List<Point3D>(); //upPoints.Add(Math3D.GetCenter(points)); //upPoints.AddRange(AveragePlaneTests.GetAveragePlane_UpVectors(points.ToArray()).Select(o => upPoints[0] + o/*.ToUnit()*/)); //AddLines(Enumerable.Range(1, upPoints.Count - 1).Select(o => Tuple.Create(0, o)), upPoints.ToArray(), _otherLineC); //------------------------- //var ups = AveragePlaneTests.TestAveragePlane_UpVectors(points.ToArray()); //Point3D center = Math3D.GetCenter(points); //AddLine(center, center + ups.Item1, _controlLineC, 2); //AddLine(center, center + ups.Item2, _controlLineC, 2); //------------------------- AddPlane(plane, UtilityWPF.ColorFromHex("20A0A0A0"), 25); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void btnAvgPlane2_Click(object sender, RoutedEventArgs e) { try { Curves_AxeSimple2 arg = new Curves_AxeSimple2(false); Curves_AxeSimple2[] argLevels = new Curves_AxeSimple2[5]; argLevels[2] = arg; // Edge #region Middle argLevels[1] = UtilityCore.Clone(arg); // Right argLevels[1].EndTR = new Point3D(argLevels[1].EndTR.X * .8, argLevels[1].EndTR.Y * .9, .15); Vector3D offsetTR = new Point3D(argLevels[1].EndTR.X, argLevels[1].EndTR.Y, 0) - arg.EndTR; Quaternion angleTR = Math3D.GetRotation((arg.EndTL - arg.EndTR), offsetTR); Vector3D rotated = (arg.EndBL_1 - arg.EndBR).ToUnit() * offsetTR.Length; rotated = rotated.GetRotatedVector(angleTR.Axis, angleTR.Angle * -1.3); argLevels[1].EndBR = new Point3D(argLevels[1].EndBR.X + rotated.X, argLevels[1].EndBR.Y + rotated.Y, .15); // can't just use percents of coordinates. Instead use the same offset angle,distance that top left had // Left argLevels[1].EndTL = new Point3D(argLevels[1].EndTL.X, argLevels[1].EndTL.Y * .95, .3); if (argLevels[1].EndBL_2 == null) { argLevels[1].EndBL_1 = new Point3D(argLevels[1].EndBL_1.X, argLevels[1].EndBL_1.Y * .9, .3); } else { Vector3D offsetBL1 = arg.EndBR - arg.EndBL_1; double lengthBL1 = (new Point3D(argLevels[1].EndBR.X, argLevels[1].EndBR.Y, 0) - arg.EndBR).Length; offsetBL1 = offsetBL1.ToUnit() * (offsetBL1.Length - lengthBL1); argLevels[1].EndBL_1 = argLevels[1].EndBR - offsetBL1; argLevels[1].EndBL_1 = new Point3D(argLevels[1].EndBL_1.X, argLevels[1].EndBL_1.Y, .18); argLevels[1].EndBL_2 = new Point3D(argLevels[1].EndBL_2.Value.X, argLevels[1].EndBL_2.Value.Y * .9, .3); } argLevels[3] = argLevels[1].CloneNegateZ(); #endregion #region Far argLevels[0] = UtilityCore.Clone(arg); //argLevels[0].EndTL = new Point3D(argLevels[0].EndTL.X, argLevels[0].EndTL.Y * .7, .4); argLevels[0].EndTL = new Point3D(argLevels[0].EndTL.X, argLevels[0].EndTL.Y * .7, .5); //argLevels[0].EndTR = new Point3D(argLevels[0].EndTR.X * .5, argLevels[0].EndTR.Y * .6, .25); argLevels[0].EndTR = new Point3D(argLevels[0].EndTR.X * .5, argLevels[0].EndTR.Y * .6, -.25); if (argLevels[0].EndBL_2 == null) { argLevels[0].EndBR = new Point3D(argLevels[0].EndBR.X * .5, argLevels[0].EndBR.Y * .6, .25); argLevels[0].EndBL_1 = new Point3D(argLevels[0].EndBL_1.X, argLevels[0].EndBL_1.Y * .6, .4); } else { // Bottom Right Vector3D offset = (argLevels[1].EndBR - argLevels[1].EndBL_1) * .5; Point3D startPoint = argLevels[1].EndBL_1 + offset; // midway along bottom edge offset = argLevels[1].EndTR - startPoint; argLevels[0].EndBR = startPoint + (offset * .15); // from midway point toward upper right point argLevels[0].EndBR = new Point3D(argLevels[0].EndBR.X, argLevels[0].EndBR.Y, .25); // fix z // Left of bottom right (where the circle cutout ends) offset = argLevels[1].EndBR - argLevels[1].EndBL_1; argLevels[0].EndBL_1 = Math3D.GetClosestPoint_Line_Point(argLevels[0].EndBR, offset, argLevels[0].EndBL_1); offset *= .05; Point3D minBL1 = argLevels[0].EndBR - offset; Vector3D testOffset = argLevels[0].EndBL_1 - argLevels[0].EndBR; if (Vector3D.DotProduct(testOffset, offset) < 0 || testOffset.LengthSquared < offset.LengthSquared) { argLevels[0].EndBL_1 = minBL1; } // Bottom Left argLevels[0].EndBL_2 = new Point3D(argLevels[0].EndBL_2.Value.X, argLevels[0].EndBL_2.Value.Y * .6, .4); // Reduce the curve a bit argLevels[0].B2AngleL = argLevels[0].B2AngleL * .9; argLevels[0].B2PercentL = argLevels[0].B2PercentL * .95; argLevels[0].B2AngleR = argLevels[0].B2AngleR * .85; argLevels[0].B2PercentR = argLevels[0].B2PercentR * .95; } argLevels[4] = argLevels[0].CloneNegateZ(); #endregion #region Get polygon points BezierSegment3D[] segments = TestAxeSimple2_Segments(argLevels[0]); List<Point3D> pointsDupes = new List<Point3D>(); foreach (BezierSegment3D bezier in segments) { pointsDupes.AddRange(BezierUtil.GetPoints(5, bezier)); } List<Point3D> points = new List<Point3D>(); points.Add(pointsDupes[0]); for (int cntr = 1; cntr < pointsDupes.Count; cntr++) { if (!Math3D.IsNearValue(pointsDupes[cntr], pointsDupes[cntr - 1])) { points.Add(pointsDupes[cntr]); } } #endregion TriangleIndexed[] triangles = Math2D.GetTrianglesFromConcavePoly3D(points.ToArray()); PrepFor3D(); foreach (Point3D point in points) { AddDot(point, _endPointC, .0125); } foreach (ITriangle triangle in triangles) { DrawTrianglePlate(triangle.Point0, triangle.Point1, triangle.Point2, UtilityWPF.GetRandomColor(128, 64, 192), false); } } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void btnAxeSimple2_Click(object sender, RoutedEventArgs e) { try { _savedAxe = new Curves_AxeSimple2(false); Axe_Checked(this, new RoutedEventArgs()); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }