|
|
cfceb0 |
using System;
|
|
|
cfceb0 |
using System.Drawing;
|
|
|
cfceb0 |
using System.Drawing.Imaging;
|
|
|
cfceb0 |
using System.Collections.Generic;
|
|
|
cfceb0 |
|
|
|
cfceb0 |
namespace Assistance {
|
|
|
cfceb0 |
public class Track {
|
|
|
cfceb0 |
public static readonly Pen pen = new Pen(Brushes.DarkGreen, 3f);
|
|
|
cfceb0 |
public static readonly Pen penPreview = new Pen(new SolidBrush(Color.FromArgb(64, Color.DarkGreen)), 1f);
|
|
|
cfceb0 |
|
|
|
cfceb0 |
public readonly List<point> points = new List<point>();</point></point>
|
|
|
cfceb0 |
|
|
|
77c1c7 |
private readonly List<track> parents = new List<track>();
|
|
|
77c1c7 |
private readonly List<geometry.transformfunc> transformFuncs = new List<geometry.transformfunc>();</geometry.transformfunc></geometry.transformfunc>
|
|
|
77c1c7 |
|
|
|
77c1c7 |
public Track() { }
|
|
|
77c1c7 |
|
|
|
77c1c7 |
public Track(Track parent, Geometry.TransformFunc transformFunc):
|
|
|
77c1c7 |
this()
|
|
|
77c1c7 |
{
|
|
|
77c1c7 |
parents.AddRange(parent.parents);
|
|
|
77c1c7 |
parents.Add(parent);
|
|
|
77c1c7 |
transformFuncs.AddRange(parent.transformFuncs);
|
|
|
77c1c7 |
transformFuncs.Add(transformFunc);
|
|
|
77c1c7 |
}
|
|
|
77c1c7 |
|
|
|
77c1c7 |
public Track(Track parent, Geometry.TransformFunc transformFunc, double precision):
|
|
|
77c1c7 |
this(parent, transformFunc)
|
|
|
77c1c7 |
{
|
|
|
77c1c7 |
rebuild(precision);
|
|
|
77c1c7 |
}
|
|
|
77c1c7 |
|
|
|
72b17c |
public Track createChild(Geometry.TransformFunc transformFunc){
|
|
|
77c1c7 |
return new Track(this, transformFunc);
|
|
|
77c1c7 |
}
|
|
|
77c1c7 |
|
|
|
77c1c7 |
public Track createChildAndBuild(Geometry.TransformFunc transformFunc, double precision = 1.0) {
|
|
|
77c1c7 |
return new Track(this, transformFunc, precision);
|
|
|
77c1c7 |
}
|
|
|
77c1c7 |
|
|
|
cfceb0 |
public Rectangle getBounds() {
|
|
|
cfceb0 |
if (points.Count == 0)
|
|
|
cfceb0 |
return new Rectangle();
|
|
|
cfceb0 |
Rectangle bounds = new Rectangle(points[0]);
|
|
|
cfceb0 |
foreach(Point p in points)
|
|
|
cfceb0 |
bounds = bounds.expand(p);
|
|
|
cfceb0 |
return bounds.inflate(Math.Max(pen.Width, penPreview.Width) + 2.0);
|
|
|
cfceb0 |
}
|
|
|
72b17c |
|
|
|
72b17c |
public Point transform(Point p) {
|
|
|
72b17c |
return Geometry.transform(transformFuncs, p);
|
|
|
72b17c |
}
|
|
|
72b17c |
|
|
|
77c1c7 |
private void addSpline(Point p0, Point p1, Point t0, Point t1, Point tp0, Point tp1, double l0, double l1, double precisionSqr) {
|
|
|
77c1c7 |
if ((tp1 - tp0).lenSqr() < precisionSqr) {
|
|
|
77c1c7 |
points.Add(tp1);
|
|
|
77c1c7 |
} else {
|
|
|
77c1c7 |
double l = 0.5*(l0 + l1);
|
|
|
77c1c7 |
Point p = Geometry.splinePoint(p0, p1, t0, t1, l);
|
|
|
72b17c |
Point tp = transform(p);
|
|
|
77c1c7 |
addSpline(p0, p1, t0, t1, tp0, tp, l0, l, precisionSqr);
|
|
|
77c1c7 |
addSpline(p0, p1, t0, t1, tp, tp1, l, l1, precisionSqr);
|
|
|
77c1c7 |
}
|
|
|
77c1c7 |
}
|
|
|
77c1c7 |
|
|
|
77c1c7 |
public void rebuild(double precision = 1.0) {
|
|
|
77c1c7 |
if (parents.Count == 0) return;
|
|
|
77c1c7 |
|
|
|
77c1c7 |
points.Clear();
|
|
|
77c1c7 |
|
|
|
77c1c7 |
Track root = parents[0];
|
|
|
77c1c7 |
if (root.points.Count < 2) {
|
|
|
77c1c7 |
foreach(Point p in root.points)
|
|
|
77c1c7 |
points.Add( Geometry.transform(transformFuncs, p) );
|
|
|
77c1c7 |
return;
|
|
|
77c1c7 |
}
|
|
|
77c1c7 |
|
|
|
77c1c7 |
double precisionSqr = precision * precision;
|
|
|
77c1c7 |
Point p0 = root.points[0];
|
|
|
77c1c7 |
Point p1 = root.points[1];
|
|
|
77c1c7 |
Point t0 = 0.5*(p1 - p0);
|
|
|
77c1c7 |
Point tp0 = Geometry.transform(transformFuncs, p0);
|
|
|
77c1c7 |
points.Add(tp0);
|
|
|
77c1c7 |
for(int i = 1; i < root.points.Count; ++i) {
|
|
|
77c1c7 |
Point p2 = root.points[i+1 < root.points.Count ? i+1 : i];
|
|
|
77c1c7 |
Point tp1 = Geometry.transform(transformFuncs, p1);
|
|
|
77c1c7 |
Point t1 = 0.5*(p2 - p0);
|
|
|
77c1c7 |
addSpline(p0, p1, t0, t1, tp0, tp1, 0.0, 1.0, precisionSqr);
|
|
|
77c1c7 |
|
|
|
77c1c7 |
p0 = p1;
|
|
|
77c1c7 |
p1 = p2;
|
|
|
77c1c7 |
tp0 = tp1;
|
|
|
77c1c7 |
t0 = t1;
|
|
|
77c1c7 |
}
|
|
|
77c1c7 |
}
|
|
|
cfceb0 |
|
|
|
cfceb0 |
public void draw(Graphics g, bool preview = false) {
|
|
|
cfceb0 |
if (points.Count < 2)
|
|
|
cfceb0 |
return;
|
|
|
cfceb0 |
PointF[] ps = new PointF[points.Count];
|
|
|
cfceb0 |
for(int i = 0; i < ps.Length; ++i)
|
|
|
cfceb0 |
ps[i] = points[i].toFloat();
|
|
|
cfceb0 |
g.DrawLines(preview ? penPreview : pen, ps);
|
|
|
cfceb0 |
}
|
|
|
cfceb0 |
}
|
|
|
cfceb0 |
}
|
|
|
cfceb0 |
|