private Vector2?BestApproximation(double startIndex, double endIndex) { // Make sure start index is before end index // The results will be the same for flipped indices if (startIndex > endIndex) { var tempEndIndex = endIndex; endIndex = startIndex; startIndex = tempEndIndex; } var p1 = GetContinuousPosition(startIndex); var p2 = GetContinuousPosition(endIndex); const int numTestPoints = 100; var labels = _path.GetRange((int)startIndex, (int)Math.Ceiling(endIndex) - (int)startIndex + 1); Vector2?[] middles = { TangentIntersectionApproximation(startIndex, endIndex), DoubleMiddleApproximation(startIndex, endIndex) }; Vector2?bestMiddle = null; double bestLoss = double.PositiveInfinity; foreach (var middle in middles) { var bezier = new BezierCurveQuadric(p1, p2, middle ?? (p2 - p1) / 2); var interpolatedPoints = new Vector2[numTestPoints]; for (int i = 0; i < numTestPoints; i++) { double t = (double)i / (numTestPoints - 1); interpolatedPoints[i] = bezier.CalculatePoint(t); } var loss = SliderPathUtil.CalculateLoss(interpolatedPoints, labels); if (loss < bestLoss) { bestLoss = loss; bestMiddle = middle; } } return(bestMiddle); }
public bool MouseMoveOnSkin(ColorGrabber pixels, Skin skin, int x, int y) { if (_done) { return(false); } var curve = new BezierCurveQuadric(new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 2)); _threshold = (byte)((1 - (curve.CalculatePoint(Threshold)).X) * 255); //(byte)((1 - Math.Sin((1 - Threshold) * (Math.PI / 2))) * 255); ColorPixel c = pixels[x, y]; Color oldColor = Color.FromArgb(c.Alpha, c.Red, c.Green, c.Blue); ColorManager newColor = ((Control.ModifierKeys & Keys.Shift) != 0) ? Editor.MainForm.ColorPanel.UnselectedColor : Editor.MainForm.ColorPanel.SelectedColor; FloodFill(x, y, oldColor, newColor, pixels); _done = true; return(true); }
public void DrawPath(Path path, VBO vbo) { List <List <Vector2> > shapes = new List <List <Vector2> >(); List <Vector2> positions = new List <Vector2>(); List <Vector2> tesselated = new List <Vector2>(); Point position = new Point(); foreach (var op in path.Operations) { var mt = op as MoveTo; if (mt != null) { shapes.Add(positions); positions = new List <Vector2>(); positions.Add(Vec2(mt.Point)); position = mt.Point; continue; } var lt = op as LineTo; if (lt != null) { positions.Add(Vec2(lt.Point)); position = lt.Point; continue; } var at = op as ArcTo; if (at != null) { var p = nsvg.nsvg__pathArcTo((Vector2d)Vec2(position), at); positions.AddRange(p); position = at.Point; continue; } var ct = op as CurveTo; if (ct != null) { if (double.IsNaN(ct.Control1.X) && double.IsNaN(ct.Control1.Y)) { BezierCurveQuadric b = new BezierCurveQuadric(Vec2(position), Vec2(ct.EndPoint), Vec2(ct.Control2)); Vector2 old = b.CalculatePoint(0f); positions.Add(old); var precision = 0.05f; for (float i = precision; i < 1f + precision; i += precision) { Vector2 j = b.CalculatePoint(i); positions.Add(j); old = j; } } else { BezierCurveCubic b = new BezierCurveCubic(Vec2(position), Vec2(ct.EndPoint), Vec2(ct.Control1), Vec2(ct.Control2)); Vector2 old = b.CalculatePoint(0f); positions.Add(old); var precision = 0.05f; for (float i = precision; i < 1f + precision; i += precision) { Vector2 j = b.CalculatePoint(i); positions.Add(j); } } position = ct.EndPoint; } var cp = op as ClosePath; if (cp != null) { if (positions.Count > 0) { positions.Add(positions[0]); shapes.Add(positions); } positions = new List <Vector2>(); position = new Point(); continue; } } shapes.Add(positions); brushcheck(path.Brush); LibTessDotNet.Tess t = new LibTessDotNet.Tess(); List <Vec3> vertices = new List <Vec3>(); foreach (var s in shapes) { ContourVertex[] cv = new ContourVertex[s.Count]; for (int i = 0; i < s.Count; i++) { var v = s[i]; cv[i] = new ContourVertex() { Position = new Vec3() { X = v.X, Y = v.Y } }; } t.AddContour(cv); } var rule = LibTessDotNet.WindingRule.NonZero; if (path.Brush != null) { rule = path.Brush.FillMode == FillMode.EvenOdd ? LibTessDotNet.WindingRule.EvenOdd : LibTessDotNet.WindingRule.NonZero; } t.Tessellate(rule, LibTessDotNet.ElementType.Polygons, 3); for (var i = 0; i < t.ElementCount; i++) { for (var tri = 0; tri < 3; tri++) { vertices.Add(t.Vertices[t.Elements[(i * 3) + tri]].Position); } } for (int i = 0; i < vertices.Count; i++) { tesselated.Add(new Vector2(vertices[i].X, vertices[i].Y)); } var lineshapes = new List <List <Vector2> >(); foreach (var s in shapes) { if (s.Count == 0) { continue; } List <Vector2> add = new List <Vector2>(); for (int i = 0; i < s.Count; i++) { add.Add(new Vector2(s[i].X, s[i].Y)); } lineshapes.Add(add); } if (path.Brush is SolidBrush || path.Pen != null) { if (path.Brush is SolidBrush) { var sb = path.Brush as SolidBrush; for (int i = 0; i < tesselated.Count; i++) { vbo.AddVertex(new Vertex(tesselated[i], color(sb.Color))); } } if (path.Pen != null) { foreach (var list in lineshapes) { foreach (var v in TesselateLines(list, path.Pen)) { vbo.AddVertex(v); } } } } }
private void DrawCircleSmooth() { var anchors = new List <Vector2>(); var screenOffset = new Vector2(MyGameWindow.main.Width / 2f, MyGameWindow.main.Height / 2f); for (int i = 0; i < SAMPLE_SIZE / 3f; ++i) { var startPercent = i / (SAMPLE_SIZE / 3f); var start = CalculatePoint(startPercent, INNER_MIN_RADIUS + m_RadiusValue, screenOffset); var barValue = OUTER_MAX_RADIUS * (m_SpectrumTotal[i] / m_MaxValue); if (m_SpectrumTotal[i] <= SPECTRUM_MIN) { barValue = OUTER_MIN_RADIUS; } if (barValue >= m_CurrentBarValue[i]) { if (m_SpectrumTotal[i] - m_OldSpectrumTotal[i] > 0.0025f && m_OldSpectrumTotal[i] < 0.005f) { barValue *= 2f; } m_CurrentBarValue[i] = barValue; } else { m_CurrentBarValue[i] -= SPECTRUM_DECAY * Time.deltaTime; } if (m_CurrentBarValue[i] < OUTER_MIN_RADIUS) { m_CurrentBarValue[i] = OUTER_MIN_RADIUS; } var endPercent = (i + 0.5f) / (SAMPLE_SIZE / 3f); var end = CalculatePoint( endPercent, INNER_MIN_RADIUS + m_RadiusValue + m_CurrentBarValue[i], screenOffset); anchors.Add(end); } var vertexes = new List <Vector2>(); var colors = new List <Color4>(); for (var i = 0; i < anchors.Count; ++i) { var startAnchor = i - 1 >= 0 ? anchors[i - 1] : anchors.Last(); var startBarValue = i - 1 >= 0 ? m_CurrentBarValue[i - 1] : m_CurrentBarValue.Last(); var controlPoint = startBarValue > m_CurrentBarValue[i] ? CalculatePoint((float)i / anchors.Count, INNER_MIN_RADIUS + m_RadiusValue + startBarValue, screenOffset) : CalculatePoint((float)i / anchors.Count, INNER_MIN_RADIUS + m_RadiusValue + m_CurrentBarValue[i], screenOffset); var bezier = new BezierCurveQuadric(startAnchor, anchors[i], controlPoint); var endColor = new Color4( Color4.White.R + m_CurrentBarValue[i] / 100f * (Color4.BlueViolet.R - Color4.White.R), Color4.White.G + m_CurrentBarValue[i] / 100f * (Color4.BlueViolet.G - Color4.White.G), Color4.White.B + m_CurrentBarValue[i] / 100f * (Color4.BlueViolet.B - Color4.White.B), 1f); for (var j = 0f; j < 1f; j += 0.005f) { colors.Add(endColor); vertexes.Add(bezier.CalculatePoint(j)); colors.Add(Color4.White); vertexes.Add(screenOffset); } } colors.Add(colors.First()); vertexes.Add(vertexes.First()); Gizmos.DrawCustomShape(vertexes, colors, PrimitiveType.TriangleStrip); }