|
|
ebcc4f |
using System;
|
|
|
ebcc4f |
|
|
|
ebcc4f |
namespace Assistance {
|
|
|
ebcc4f |
public class VanishingPoint: Assistant {
|
|
|
ebcc4f |
public ActivePoint center;
|
|
|
ebcc4f |
public ActivePoint a0;
|
|
|
ebcc4f |
public ActivePoint a1;
|
|
|
ebcc4f |
public ActivePoint b0;
|
|
|
ebcc4f |
public ActivePoint b1;
|
|
|
ebcc4f |
public ActivePoint step;
|
|
|
ebcc4f |
|
|
|
b1ff53 |
public VanishingPoint(Workarea canvas, Point center): base(canvas) {
|
|
|
ebcc4f |
this.center = new ActivePoint(this, ActivePoint.Type.CircleCross, center);
|
|
|
ebcc4f |
a0 = new ActivePoint(this, ActivePoint.Type.CircleFill, center + new Point(-100.0, 0.0));
|
|
|
ebcc4f |
a1 = new ActivePoint(this, ActivePoint.Type.Circle, center + new Point(-200.0, 0.0));
|
|
|
ebcc4f |
b0 = new ActivePoint(this, ActivePoint.Type.CircleFill, center + new Point(100.0, 0.0));
|
|
|
ebcc4f |
b1 = new ActivePoint(this, ActivePoint.Type.Circle, center + new Point(200.0, 0.0));
|
|
|
ebcc4f |
step = new ActivePoint(this, ActivePoint.Type.Circle, (a0.position + a1.position)/2);
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
|
|
|
ebcc4f |
private void fixCenter() {
|
|
|
ebcc4f |
if (!a0.position.isEqual(a1.position) && !b0.position.isEqual(b1.position)) {
|
|
|
ebcc4f |
Point a = a0.position;
|
|
|
ebcc4f |
Point b = b0.position;
|
|
|
ebcc4f |
Point da = a1.position - a;
|
|
|
ebcc4f |
Point db = b1.position - b;
|
|
|
ebcc4f |
Point ab = b - a;
|
|
|
ebcc4f |
double k = db.x*da.y - db.y*da.x;
|
|
|
ebcc4f |
if (Math.Abs(k) > 0.00001) {
|
|
|
ebcc4f |
double lb = (da.x*ab.y - da.y*ab.x)/k;
|
|
|
ebcc4f |
center.position.x = lb*db.x + b.x;
|
|
|
ebcc4f |
center.position.y = lb*db.y + b.y;
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
|
|
|
ebcc4f |
private void fixSidePoint(ActivePoint p0, ActivePoint p1, Point previousP0) {
|
|
|
ebcc4f |
if (!p0.position.isEqual(center.position)) {
|
|
|
ebcc4f |
Point dp0 = p0.position - center.position;
|
|
|
ebcc4f |
Point dp1 = p1.position - previousP0;
|
|
|
ebcc4f |
p1.position = center.position + dp0*(dp0.len() + dp1.len())/dp0.len();
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
|
|
|
ebcc4f |
private void fixSidePoint(ActivePoint p0, ActivePoint p1) {
|
|
|
ebcc4f |
fixSidePoint(p0, p1, p0.position);
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
|
|
|
ebcc4f |
public void fixPoints() {
|
|
|
ebcc4f |
fixSidePoint(a0, a1);
|
|
|
ebcc4f |
fixSidePoint(a0, step);
|
|
|
ebcc4f |
fixSidePoint(b0, b1);
|
|
|
ebcc4f |
fixCenter();
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
|
|
|
ebcc4f |
public override void onMovePoint(ActivePoint point, Point position) {
|
|
|
ebcc4f |
Point previous = point.position;
|
|
|
ebcc4f |
point.position = position;
|
|
|
ebcc4f |
if (point == center) {
|
|
|
ebcc4f |
a0.position += point.position - previous;
|
|
|
ebcc4f |
a1.position += point.position - previous;
|
|
|
ebcc4f |
step.position += point.position - previous;
|
|
|
ebcc4f |
b0.position += point.position - previous;
|
|
|
ebcc4f |
b1.position += point.position - previous;
|
|
|
ebcc4f |
} else
|
|
|
ebcc4f |
if (point == a0) {
|
|
|
ebcc4f |
fixSidePoint(a0, a1, previous);
|
|
|
ebcc4f |
fixSidePoint(a0, step, previous);
|
|
|
ebcc4f |
fixSidePoint(b0, b1);
|
|
|
ebcc4f |
} else
|
|
|
ebcc4f |
if (point == b0) {
|
|
|
ebcc4f |
fixSidePoint(a0, a1);
|
|
|
ebcc4f |
fixSidePoint(a0, step);
|
|
|
ebcc4f |
fixSidePoint(b0, b1, previous);
|
|
|
ebcc4f |
} else {
|
|
|
ebcc4f |
fixCenter();
|
|
|
ebcc4f |
fixSidePoint(a0, a1);
|
|
|
ebcc4f |
fixSidePoint(a0, step);
|
|
|
ebcc4f |
fixSidePoint(b0, b1);
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
|
|
|
ebcc4f |
public override Point[] getGridPoints(Point target, bool truncate) {
|
|
|
ebcc4f |
double k = (a0.position - center.position).len();
|
|
|
ebcc4f |
if (k < 0.00001)
|
|
|
ebcc4f |
return new Point[0];
|
|
|
ebcc4f |
k = (step.position - center.position).len()/k;
|
|
|
ebcc4f |
|
|
|
b1ff53 |
//if (Math.Abs(k - 1.0) < 0.1) return new Point[0];
|
|
|
b1ff53 |
|
|
|
ebcc4f |
Point[] points = new Point[truncate ? gridPointsCount + 1 : gridPointsCount*2 + 1];
|
|
|
ebcc4f |
Point a = target - center.position;
|
|
|
ebcc4f |
Point b = a;
|
|
|
ebcc4f |
points[gridPointsCount] = a + center.position;
|
|
|
ebcc4f |
for(int i = 1; i <= gridPointsCount; ++i) {
|
|
|
ebcc4f |
a /= k;
|
|
|
ebcc4f |
b *= k;
|
|
|
ebcc4f |
points[gridPointsCount - i] = a + center.position;
|
|
|
ebcc4f |
if (!truncate)
|
|
|
ebcc4f |
points[gridPointsCount + i] = b + center.position;
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
return points;
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
|
|
|
ebcc4f |
public override void draw(System.Drawing.Graphics g) {
|
|
|
ebcc4f |
g.DrawLine(pen, center.position.toFloat(), a0.position.toFloat());
|
|
|
ebcc4f |
g.DrawLine(pen, center.position.toFloat(), a1.position.toFloat());
|
|
|
ebcc4f |
g.DrawLine(pen, center.position.toFloat(), b0.position.toFloat());
|
|
|
ebcc4f |
g.DrawLine(pen, center.position.toFloat(), b1.position.toFloat());
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
|
|
|
ebcc4f |
public override void drawGuidlines(System.Drawing.Graphics g, Point target, bool truncate) {
|
|
|
ebcc4f |
if (truncate) {
|
|
|
ebcc4f |
g.DrawLine(guidePen, center.position.toFloat(), target.toFloat());
|
|
|
ebcc4f |
} else {
|
|
|
ebcc4f |
Point p = (target - center.position).normalize()*getMaxLen() + center.position;
|
|
|
ebcc4f |
g.DrawLine(guidePen, center.position.toFloat(), p.toFloat());
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
}
|
|
|
b1ff53 |
|
|
|
b1ff53 |
public override double calcTrackWeight(Track track) {
|
|
|
b1ff53 |
if (track.points.Count < 2)
|
|
|
b1ff53 |
return 0.0;
|
|
|
b1ff53 |
|
|
|
b1ff53 |
Point point = track.points[0];
|
|
|
b1ff53 |
Point d = (point - center.position).normalize();
|
|
|
b1ff53 |
d = new Point(-d.y, d.x);
|
|
|
b1ff53 |
double weight = 0.0;
|
|
|
b1ff53 |
foreach(Point p in track.points)
|
|
|
b1ff53 |
weight += Math.Abs((p.x - point.x)*d.x + (p.y - point.y)*d.y);
|
|
|
b1ff53 |
weight /= track.points.Count;
|
|
|
b1ff53 |
|
|
|
b1ff53 |
return weight;
|
|
|
b1ff53 |
}
|
|
|
b1ff53 |
|
|
|
b1ff53 |
public override Track modifyTrack(Track track) {
|
|
|
b1ff53 |
Track t = new Track();
|
|
|
b1ff53 |
if (track.points.Count < 1)
|
|
|
b1ff53 |
return t;
|
|
|
b1ff53 |
|
|
|
b1ff53 |
Point point = track.points[0];
|
|
|
b1ff53 |
Point d = (point - center.position).normalize();
|
|
|
b1ff53 |
foreach(Point p in track.points) {
|
|
|
b1ff53 |
double l = (p.x - point.x)*d.x + (p.y - point.y)*d.y;
|
|
|
b1ff53 |
t.points.Add(l*d + point);
|
|
|
b1ff53 |
}
|
|
|
b1ff53 |
return t;
|
|
|
b1ff53 |
}
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
|