From e6a40525fed1659023d67f4783e178d13e3232f1 Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Dec 28 2017 10:16:33 +0000 Subject: assistance: improve guidelines tracking --- diff --git a/mono/Assistance/Workarea.cs b/mono/Assistance/Workarea.cs index 65d79c2..970ee20 100644 --- a/mono/Assistance/Workarea.cs +++ b/mono/Assistance/Workarea.cs @@ -32,16 +32,23 @@ namespace Assistance { List guidelines = new List(); if (track != null && track.points.Count > 0) { getGuidelines(guidelines, track.points[0]); + Guideline guideline = Guideline.findBest(guidelines, track); + Track modifiedTrack = guideline == null + ? track.createChildAndBuild(Geometry.noTransform) + : track.createChildAndBuild(guideline.transformPoint); + + if (modifiedTrack.points.Count > 0) { + guidelines.Clear(); + getGuidelines(guidelines, modifiedTrack.points.Last()); + } foreach(Guideline gl in guidelines) gl.draw(g); - Guideline guideline = Guideline.findBest(guidelines, track); + if (guideline != null) { track.draw(g, true); - track.createChildAndBuild(guideline.transformPoint).draw(g); guideline.draw(g, true); - } else { - track.createChildAndBuild(Geometry.noTransform).draw(g); } + modifiedTrack.draw(g); } else { getGuidelines(guidelines, target); foreach(Guideline guideline in guidelines) diff --git a/mono/Autospline/Autospline.csproj b/mono/Autospline/Autospline.csproj new file mode 100644 index 0000000..c4023d4 --- /dev/null +++ b/mono/Autospline/Autospline.csproj @@ -0,0 +1,42 @@ + + + + Debug + x86 + 10.0.0 + 2.0 + {77CD6953-34F0-4125-9DF5-957ECF0E23F0} + Exe + Autospline + Autospline + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + x86 + false + + + none + true + bin\Release + prompt + 4 + x86 + false + + + + + + + + + + + \ No newline at end of file diff --git a/mono/Autospline/Autospline.sln b/mono/Autospline/Autospline.sln new file mode 100644 index 0000000..1d546f6 --- /dev/null +++ b/mono/Autospline/Autospline.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Autospline", "Autospline.csproj", "{77CD6953-34F0-4125-9DF5-957ECF0E23F0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {77CD6953-34F0-4125-9DF5-957ECF0E23F0}.Debug|x86.ActiveCfg = Debug|x86 + {77CD6953-34F0-4125-9DF5-957ECF0E23F0}.Debug|x86.Build.0 = Debug|x86 + {77CD6953-34F0-4125-9DF5-957ECF0E23F0}.Release|x86.ActiveCfg = Release|x86 + {77CD6953-34F0-4125-9DF5-957ECF0E23F0}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = Autospline.csproj + EndGlobalSection +EndGlobal diff --git a/mono/Autospline/MainWindow.cs b/mono/Autospline/MainWindow.cs new file mode 100644 index 0000000..348d79d --- /dev/null +++ b/mono/Autospline/MainWindow.cs @@ -0,0 +1,172 @@ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Windows.Forms; +using System.Collections.Generic; + +namespace Autospline { + public struct Segment { + public double previous; + public double current; + public double next; + public double nextnext; + + public static double get(double s, double p0, double pm, double p1) { + return p0*(1.0-s)*(1.0-s) + 2.0*pm*(1.0-s)*s + p1*s*s; + } + + public static double get(double s, double p0, double p1, double t0, double t1) { + double h0 = 2.0*s*s*s - 3.0*s*s + 1.0; + double h1 = -2.0*s*s*s + 3.0*s*s; + double h2 = s*s*s - 2.0*s*s + s; + double h3 = s*s*s - s*s; + double p = h0*p0 + h1*p1 + h2*t0 + h3*t1; + return p; + } + + public double get(double s) { + return get(s, current, next, current - previous, next - current); + } + + public double getCool(double s) { + return get(s, current, next, 0.5*(next - previous), 0.5*(nextnext - current)); + } + + public double getCool2(double s) { + return get(s, 0.5*(previous + current), current, 0.5*(current + next)); + } + } + + public struct Segment2d { + public Segment x; + public Segment y; + } + + public class MainWindow : Form { + static public void Main() { Application.Run(new MainWindow()); } + + bool pressed = false; + List segments = new List(); + Bitmap buffer; + + void newCurve(double x, double y) { + Segment2d segment; + segment.x.previous = segment.x.current = segment.x.next = segment.x.nextnext = x; + segment.y.previous = segment.y.current = segment.y.next = segment.y.nextnext = y; + segments.Add(segment); + } + + void addPoint(double x, double y) { + Segment2d previous = segments[segments.Count - 1]; + previous.x.nextnext = x; + previous.y.nextnext = y; + segments[segments.Count - 1] = previous; + + Segment2d segment; + segment.y.nextnext = y; + segment.x.next = segment.x.nextnext = x; + segment.y.next = segment.y.nextnext = y; + segment.x.current = previous.x.next; + segment.y.current = previous.y.next; + segment.x.previous = previous.x.current; + segment.y.previous = previous.y.current; + segments.Add(segment); + } + + public MainWindow() { + OnResize(this, new EventArgs()); + Paint += OnPaint; + MouseMove += OnMouseMove; + MouseDown += OnMouseDown; + MouseUp += OnMouseUp; + Resize += OnResize; + WindowState = FormWindowState.Maximized; + } + + public void OnResize(Object sender, EventArgs e) { + buffer = new Bitmap(ClientSize.Width, ClientSize.Height); + } + + public void OnPaint(Object sender, PaintEventArgs e) { + Graphics g = Graphics.FromImage(buffer); + Draw(g); + g.Flush(); + e.Graphics.DrawImageUnscaled(buffer, 0, 0); + } + + public void OnMouseDown(Object sender, MouseEventArgs e) { + if (e.Button == MouseButtons.Left) { + newCurve(e.X, e.Y); + pressed = true; + Invalidate(); + } else + if (e.Button == MouseButtons.Right) { + segments.Clear(); + if (pressed) newCurve(e.X, e.Y); + Invalidate(); + } + } + + public void OnMouseUp(Object sender, MouseEventArgs e) { + if (e.Button == MouseButtons.Left && pressed) { + addPoint(e.X, e.Y); + pressed = false; + Invalidate(); + } + } + + public void OnMouseMove(Object sender, MouseEventArgs e) { + if (pressed) { + addPoint(e.X, e.Y); + Invalidate(); + } + } + + public void Draw(Graphics g) { + g.Clear(Color.White); + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + int count = 100; + double r = 2.0; + double l = 2.0; + + Pen pen = new Pen(Color.FromArgb(128, 128, 128, 128)); + Pen cool = new Pen(Color.FromArgb(128, 0, 0, 255)); + + foreach(Segment2d segment in segments) { + double x0 = segment.x.get(0.0); + double y0 = segment.y.get(0.0); + for(int i = 1; i <= count; ++i) { + double x1 = segment.x.get((double)i/(double)count); + double y1 = segment.y.get((double)i/(double)count); + if (i == count || (x1 - x0)*(x1 - x0) + (y1 - y0)*(y1 - y0) > l*l) { + g.DrawLine(pen, (float)x0, (float)y0, (float)x1, (float)y1); + x0 = x1; + y0 = y1; + } + } + + x0 = segment.x.getCool2(0.0); + y0 = segment.y.getCool2(0.0); + for(int i = 1; i <= count; ++i) { + double x1 = segment.x.getCool2((double)i/(double)count); + double y1 = segment.y.getCool2((double)i/(double)count); + if (i == count || (x1 - x0)*(x1 - x0) + (y1 - y0)*(y1 - y0) > l*l) { + g.DrawLine(cool, (float)x0, (float)y0, (float)x1, (float)y1); + x0 = x1; + y0 = y1; + } + } + + g.FillEllipse( + Brushes.Black, + (float)(segment.x.current - r), (float)(segment.y.current - r), + (float)(2.0*r), (float)(2.0*r) ); + g.FillEllipse( + Brushes.Black, + (float)(segment.x.next - r), (float)(segment.y.next - r), + (float)(2.0*r), (float)(2.0*r) ); + } + } + } +} +