public override void MouseDown(Canvas canvas, PointO location) { switch (Mode) { case ToolMode.Create: Curve = new DrawableCurve(location, location); canvas.Drawables.AddLast(Curve); Mode = ToolMode.Resize; break; case ToolMode.AddCurve: if (Curve.Intersect(location)) { Curve.AddCurve(location); CurvePoint = location; Mode = ToolMode.MoveCurve; } else { Curve.State = LockState.Instance; Mode = ToolMode.Create; } break; } }
public override void Move(PointO offset) { foreach (var point in points) { point.Offset(offset); } }
private double PythagorasDistance(PointO a, PointO b) { var dx = a.X - b.X; var dy = a.Y - b.Y; return(Math.Sqrt(dx * dx + dy * dy)); }
public override void Move(PointO offset) { foreach (var drawable in drawables) { drawable.Move(offset); } }
private bool InBetween(PointO start, PointO mid, PointO end) { var alpha = FindAngle(mid, start, end); var beta = FindAngle(mid, end, start); return(alpha <= 90 && beta <= 90); }
public override void MouseDown(Canvas canvas, PointO location) { var drawable = GetDrawableAtLocation(canvas, location); switch (Mode) { case ToolMode.Select: if (drawable == null) { canvas.LockDrawables(); } else if (drawable.State == EditState.Instance) { moveDrawables = GetDrawableWithState(canvas, EditState.Instance); moveStartLocation = location; Mode = ToolMode.Move; } else { canvas.LockDrawables(); drawable.State = EditState.Instance; } break; case ToolMode.MultiSelect: if (drawable == null) { break; } ToggleDrawableState(drawable); break; } }
public override bool Intersect(PointO point) { var minDistance = double.MaxValue; // distance from curve point for (var i = 0; i < points.Count; i++) { var distance = PythagorasDistance(point, points[i]); minDistance = Math.Min(minDistance, distance); if (minDistance < IntersectDistanceLimit) { return(true); } } // distance from curve line for (var i = 1; i < points.Count; i++) { var a = points[i - 1]; var b = points[i]; if (InBetween(a, point, b)) { var distance = PerpendicularDistance(point, a, b); minDistance = Math.Min(minDistance, distance); if (minDistance < IntersectDistanceLimit) { return(true); } } } return(false); }
public override void DrawGuide(Graphics graphics) { graphics.DrawLines(LineGuidePen, PointO.ToPrimitiveArray(points.ToArray())); foreach (var point in points) { graphics.DrawEllipse(CurvePointGuidePen, point.X - 2, point.Y - 2, 4, 4); } }
public override void MouseUp(Canvas canvas, PointO location) { switch (Mode) { case ToolMode.Move: Mode = ToolMode.Select; break; } }
private double PerpendicularDistance(PointO point, PointO lineA, PointO lineB) { // reference: https://math.stackexchange.com/questions/637922/how-can-i-find-coefficients-a-b-c-given-two-points var a = lineA.Y - lineB.Y; var b = -(lineA.X - lineB.X); var c = lineA.X * lineB.Y - lineB.X * lineA.Y; return(PerpendicularDistance(point, a, b, c)); }
public override bool Intersect(PointO point) { foreach (var drawable in drawables) { if (drawable.Intersect(point)) { return(true); } } return(false); }
private static Drawable GetDrawableAtLocation(Canvas canvas, PointO location) { foreach (var drawable in canvas.Drawables) { if (drawable.Intersect(location)) { return(drawable); } } return(null); }
public override void MouseUp(Canvas canvas, PointO location) { switch (Mode) { case ToolMode.Resize: Mode = ToolMode.AddCurve; break; case ToolMode.MoveCurve: Mode = ToolMode.AddCurve; break; } }
private double FindAngle(PointO a, PointO b, PointO c) { // reference: https://stackoverflow.com/questions/19729831/angle-between-3-points-in-3d-space var v1 = new double[] { a.X - b.X, a.Y - b.Y }; var v2 = new double[] { c.X - b.X, c.Y - b.Y }; var v1Mag = Math.Sqrt(v1[0] * v1[0] + v1[1] * v1[1]); var v2Mag = Math.Sqrt(v2[0] * v2[0] + v2[1] * v2[1]); var v1Norm = new[] { v1[0] / v1Mag, v1[1] / v1Mag }; var v2Norm = new[] { v2[0] / v2Mag, v2[1] / v2Mag }; var res = v1Norm[0] * v2Norm[0] + v1Norm[1] * v2Norm[1]; return(Math.Acos(res) * 180.0 / 3.141592653589793); }
public override void MouseMove(Canvas canvas, PointO location) { switch (Mode) { case ToolMode.Move: foreach (var drawable in moveDrawables) { var offset = PointO.FromOffset(moveStartLocation, location); drawable.Move(offset); } moveStartLocation = location; break; } }
public override void MouseMove(Canvas canvas, PointO location) { switch (Mode) { case ToolMode.Resize: Curve.SetEndPoint(location); break; case ToolMode.MoveCurve: var offset = PointO.FromOffset(CurvePoint, location); CurvePoint.Offset(offset); break; } }
private int FindBestPointPosition(PointO point) { var bestPointPosition = -1; var minDistance = double.MaxValue; for (var i = 0; i < points.Count; i++) { var distance = PythagorasDistance(point, points[i]); if (distance < IntersectDistanceLimit && distance < minDistance) { bestPointPosition = i; minDistance = distance; } } return(bestPointPosition); }
public void AddCurve(PointO point) { // try use old curve var position = FindBestPointPosition(point); if (position != -1) { points[position] = point; } else { // try add curve between 2 point position = FindBestPosition(point); if (position != -1) { points.Insert(position, point); } } }
private int FindBestPosition(PointO point) { var bestPosition = -1; var minDistance = double.MaxValue; for (var i = 1; i < points.Count; i++) { var a = points[i - 1]; var b = points[i]; if (!InBetween(a, point, b)) { continue; } var distance = PerpendicularDistance(point, a, b); if (!(distance < minDistance)) { continue; } bestPosition = i; minDistance = distance; } return(bestPosition); }
public virtual void MouseMove(Canvas canvas, PointO location) { }
public virtual void MouseDown(Canvas canvas, PointO location) { }
public DrawableCurve(PointO from, PointO to) { points.Add(from); points.Add(to); }
private double PerpendicularDistance(PointO p, float a, float b, float c) { // reference: https://www.geeksforgeeks.org/perpendicular-distance-between-a-point-and-a-line-in-2-d/ return(Math.Abs(a * p.X + b * p.Y + c) / Math.Sqrt(a * a + b * b)); }
public void SetStartPoint(PointO newStartPoint) { points[0] = newStartPoint; }
public void SetEndPoint(PointO newEndPoint) { points[points.Count - 1] = newEndPoint; }
public abstract void Move(PointO offset);
public abstract bool Intersect(PointO point);
public override void DrawItem(Graphics graphics) { graphics.DrawCurve(DrawPen, PointO.ToPrimitiveArray(points.ToArray())); }