void DrawBezier(int splineInd) { Vector3[] pnts = curve.GetSplinePoints(splineInd); Vector3 start = curve.transform.TransformPoint(BezierUtil.GetPoint(pnts, 0f)); //Vector3 start = BezierUtil.GetPoint(pnts, 0f); curve.curvePoints.Add(curve.transform.InverseTransformPoint(start)); float i = 0; while (i < 1) { Handles.color = Color.red; i += .1f; Vector3 end = curve.transform.TransformPoint(BezierUtil.GetPoint(pnts, i)); //Vector3 end = BezierUtil.GetPoint(pnts, i); curve.curvePoints.Add(curve.transform.InverseTransformPoint(end)); Handles.DrawLine(start, end); /* * Handles.color = Color.green; * Vector3 velocity = (end - start) * 15; * Handles.DrawLine(end, end + velocity); */ start = end; } if (curve.Splines - 1 != splineInd) { // Avoid overlapping of curves curve.curvePoints.RemoveAt(curve.curvePoints.Count - 1); } }
public static double NextBell(this Random rand, RandomBellArgs args) { double retVal = BezierUtil.GetPoint(rand.NextDouble(), args.Bezier).Y; if (retVal < 0) { retVal = 0; } else if (retVal > 1) { retVal = 1; } return(retVal); }
private void DrawBell3() { Point[] points = GetBellPoints(txtBell3.Text); if (points == null) { txtBell3.Effect = _errorEffect; return; } txtBell3.Effect = null; BezierSegment3D bezier = new BezierSegment3D(0, 1, points.Select(o => o.ToPoint3D()).ToArray(), new[] { new Point3D(0, 0, 0), new Point3D(1, 1, 0) }); Random rand = StaticRandom.GetRandomForThread(); IEnumerable <double> samples = Enumerable.Range(0, 100000). Select(o => BezierUtil.GetPoint(rand.NextDouble(), bezier).Y); IEnumerable <Point> idealLine = BezierUtil.GetPoints(100, bezier). Select(o => o.ToPoint2D()); DrawGraph(samples, idealLine); Rect bounds = GetBounds(); for (int cntr = 0; cntr < bezier.ControlPoints.Length - 1; cntr++) { Point from = GetScaledPoint(bezier.ControlPoints[cntr], bounds); Point to = GetScaledPoint(bezier.ControlPoints[cntr + 1], bounds); AddLine(from, to, _brushLightBlue); } if (bezier.ControlPoints.Length > 0) { Point from = GetScaledPoint(bezier.EndPoint0, bounds); Point to = GetScaledPoint(bezier.ControlPoints[0], bounds); AddLine(from, to, _brushLightBlue); from = GetScaledPoint(bezier.EndPoint1, bounds); to = GetScaledPoint(bezier.ControlPoints[bezier.ControlPoints.Length - 1], bounds); AddLine(from, to, _brushLightBlue); } }
private void DrawBell2() { Point[] points = GetBellPoints(txtBell2.Text); if (points == null) { txtBell2.Effect = _errorEffect; return; } txtBell2.Effect = null; BezierSegment3D[] bezier = BezierUtil.GetBezierSegments(points.Select(o => o.ToPoint3D()).ToArray(), trkBell2.Value); for (int cntr = 0; cntr < bezier.Length; cntr++) { bezier[cntr] = new BezierSegment3D(bezier[cntr].EndIndex0, bezier[cntr].EndIndex1, new Point3D[0], bezier[cntr].AllEndPoints); } Random rand = StaticRandom.GetRandomForThread(); IEnumerable <double> samples = Enumerable.Range(0, 50000). Select(o => BezierUtil.GetPoint(rand.NextDouble(), bezier).Y); IEnumerable <Point> idealLine = BezierUtil.GetPath(100, bezier). Select(o => o.ToPoint2D()); DrawGraph(samples, idealLine); var samples2 = Enumerable.Range(0, 1000). Select(o => { double randPercent = rand.NextDouble(); Point3D point = BezierUtil.GetPoint(randPercent, bezier); return(Tuple.Create(randPercent, point.X, point.Y, point.Z)); }). OrderBy(o => o.Item1). ToArray(); if (!samples2.All(o => o.Item4.IsNearZero())) { int three = 2; } if (!samples2.All(o => o.Item2.IsNearValue(o.Item3))) { int four = 7; } var samples2a = samples2. Select(o => Tuple.Create(o.Item1, o.Item2, o.Item1 - o.Item2)). ToArray(); //IEnumerable<Point> testLine = Enumerable.Range(0, 150). // Select(o => BezierUtil.GetPoint(o / 150d, bezier).ToPoint2D()); //Rect bounds = GetBounds(); //IEnumerable<Point> testLineFinal = idealLine // .Select(o => new Point(bounds.Left + (o.X * bounds.Width), bounds.Bottom - (o.Y * bounds.Height))); //AddLine(testLineFinal, new SolidColorBrush(UtilityWPF.ColorFromHex("FF0000")), 1, "test line"); }
private void DrawBellFail() { double midX = trkBellFailPeak.Value; BezierSegment3D[] bezier = BezierUtil.GetBezierSegments(new[] { new Point3D(0, 0, 0), new Point3D(midX, 1, 0), new Point3D(1, 0, 0) }, trkBellFailPinch.Value); // Add a control point so the curve will be attracted to the x axis at the two end points double run; if (trkBellFailLeftZero.Value > 0) { run = (bezier[0].EndPoint1.X - bezier[0].EndPoint0.X) * trkBellFailLeftZero.Value; bezier[0] = new BezierSegment3D(bezier[0].EndIndex0, bezier[0].EndIndex1, new[] { new Point3D(run, 0, 0), bezier[0].ControlPoints[0] }, bezier[0].AllEndPoints); } if (trkBellFailRightZero.Value > 0) { run = (bezier[1].EndPoint1.X - bezier[1].EndPoint0.X) * trkBellFailRightZero.Value; bezier[1] = new BezierSegment3D(bezier[1].EndIndex0, bezier[1].EndIndex1, new[] { bezier[1].ControlPoints[0], new Point3D(bezier[1].EndPoint1.X - run, 0, 0), }, bezier[1].AllEndPoints); } Random rand = StaticRandom.GetRandomForThread(); //TODO: There is still a bug with calculating percent, or something //It might be treating X as a percent. Maybe need to get the length of the lines, and take the percent of those???? - should be the same though IEnumerable <double> samples = Enumerable.Range(0, 50000). Select(o => { double percent = rand.NextDouble(); int index; if (percent < midX) { index = 0; percent = percent / midX; } else { index = 1; percent = (percent - midX) / (1d - midX); } double retVal = BezierUtil.GetPoint(percent, bezier[index]).Y; if (retVal < 0) { retVal = 0; } else if (retVal > 1) { retVal = 1; } return(retVal); }); IEnumerable <Point> idealLine = BezierUtil.GetPath(100, bezier). Select(o => o.ToPoint2D()); DrawGraph(samples, idealLine); }
private void BellFailDebug_Click(object sender, RoutedEventArgs e) { const int COUNT = 25; // The problem that this method illustrates is that rand.nextdouble() is thought of as x, but it's really % along arc length of the curve // And because there are two curves, it's some hacked up hybrid // // The original intent was to get the y coord at some fixed x. But there's no one single calculation that would get that. Samples would // need to be taken to figure out which percent along curve to use to get the desired x, and corresponding y try { double midX = trkBellFailPeak.Value; BezierSegment3D[] bezier = BezierUtil.GetBezierSegments(new[] { new Point3D(0, 0, 0), new Point3D(midX, 1, 0), new Point3D(1, 0, 0) }, trkBellFailPinch.Value); // Add a control point so the curve will be attracted to the x axis at the two end points double run; if (trkBellFailLeftZero.Value > 0) { run = (bezier[0].EndPoint1.X - bezier[0].EndPoint0.X) * trkBellFailLeftZero.Value; bezier[0] = new BezierSegment3D(bezier[0].EndIndex0, bezier[0].EndIndex1, new[] { new Point3D(run, 0, 0), bezier[0].ControlPoints[0] }, bezier[0].AllEndPoints); } if (trkBellFailRightZero.Value > 0) { run = (bezier[1].EndPoint1.X - bezier[1].EndPoint0.X) * trkBellFailRightZero.Value; bezier[1] = new BezierSegment3D(bezier[1].EndIndex0, bezier[1].EndIndex1, new[] { bezier[1].ControlPoints[0], new Point3D(bezier[1].EndPoint1.X - run, 0, 0), }, bezier[1].AllEndPoints); } //bezier[0] = new BezierSegment3D(bezier[0].EndIndex0, bezier[0].EndIndex1, new Point3D[0], bezier[0].AllEndPoints); //bezier[1] = new BezierSegment3D(bezier[1].EndIndex0, bezier[1].EndIndex1, new Point3D[0], bezier[1].AllEndPoints); var samples = Enumerable.Range(0, COUNT). Select(o => { double percentOrig = o.ToDouble() / COUNT.ToDouble(); int index; double percent; if (percentOrig < midX) { index = 0; percent = percentOrig / midX; } else { index = 1; percent = (percentOrig - midX) / (1d - midX); } Point3D point = BezierUtil.GetPoint(percent, bezier[index]); //if (retVal < 0) retVal = 0; //else if (retVal > 1) retVal = 1; return(new { PercentOrig = percentOrig, PercentSub = percent, Index = index, Point = point, }); }). ToArray(); Clear(); Rect bounds = GetBounds(); // Grid AddLine(bounds.BottomLeft, bounds.TopRight, _brushVeryLight); // diagonal AddLine(bounds.TopLeft, bounds.TopRight, _brushVeryLight); // 1 double y = bounds.Bottom - (bounds.Height * .75); AddLine(new Point(bounds.Left, y), new Point(bounds.Right, y), _brushVeryLight); // .75 y = bounds.Bottom - (bounds.Height * .5); AddLine(new Point(bounds.Left, y), new Point(bounds.Right, y), _brushVeryLight); // .5 y = bounds.Bottom - (bounds.Height * .25); AddLine(new Point(bounds.Left, y), new Point(bounds.Right, y), _brushVeryLight); // .25 AddLine(new[] { bounds.TopLeft, bounds.BottomLeft, bounds.BottomRight }, _brushDark); // axiis // Samples foreach (var sample in samples) { AddLine(new Point(bounds.Left + (sample.PercentOrig * bounds.Width), bounds.Bottom), new Point(bounds.Left + (sample.Point.X * bounds.Width), bounds.Bottom - (sample.Point.Y * bounds.Height)), Brushes.Black); } } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }