public static double Distance(GuidePoint point0, GuidePoint point1) { double dx = point0.X - point1.X; double dy = point0.Y - point1.Y; return(Math.Sqrt(dx * dx + dy * dy)); }
public static bool LineLineIntersection(GuidePoint point0, GuidePoint point1, GuidePoint point2, GuidePoint point3, out GuidePoint intersection) { double A1 = point1.Y - point0.Y; double B1 = point0.X - point1.X; double C1 = A1 * point0.X + B1 * point0.Y; double A2 = point3.Y - point2.Y; double B2 = point2.X - point3.X; double C2 = A2 * point2.X + B2 * point2.Y; double det = A1 * B2 - A2 * B1; if (det != 0.0) { double x = (B2 * C1 - B1 * C2) / det; double y = (A1 * C2 - A2 * C1) / det; var point = new GuidePoint(x, y); if (PointIsOnLineSegment(point0, point1, point) && PointIsOnLineSegment(point2, point3, point)) { intersection = point; return true; } } intersection = default(GuidePoint); return false; }
public static bool LineLineIntersection(GuidePoint point0, GuidePoint point1, GuidePoint point2, GuidePoint point3, out GuidePoint intersection) { double A1 = point1.Y - point0.Y; double B1 = point0.X - point1.X; double C1 = A1 * point0.X + B1 * point0.Y; double A2 = point3.Y - point2.Y; double B2 = point2.X - point3.X; double C2 = A2 * point2.X + B2 * point2.Y; double det = A1 * B2 - A2 * B1; if (det != 0.0) { double x = (B2 * C1 - B1 * C2) / det; double y = (A1 * C2 - A2 * C1) / det; var point = new GuidePoint(x, y); if (PointIsOnLineSegment(point0, point1, point) && PointIsOnLineSegment(point2, point3, point)) { intersection = point; return(true); } } intersection = default(GuidePoint); return(false); }
public EditorState() { _tool = EditorTool.Spiro; _mode = EditorMode.Create; _displayKnots = true; _displayGuides = true; _snapX = 15.0; _snapY = 15.0; _enableSnap = true; _shape = null; _hitTreshold = 7; _hitTresholdSquared = 49; _hitSetShapes = new HashSet <SpiroShape>(); _hitSetPoints = new HashSet <int>(); _hitListShapes = new ObservableCollection <SpiroShape>(); _hitListPoints = new ObservableCollection <int>(); _isStroked = true; _isFilled = false; _isClosed = true; _isTagged = false; _pointType = SpiroPointType.G4; _isCaptured = false; _snapTreshold = 10.0; _snapMode = GuideSnapMode.Point | GuideSnapMode.Middle | GuideSnapMode.Intersection | GuideSnapMode.Horizontal | GuideSnapMode.Vertical; _snapPointRadius = 3.5; _snapPoint = default(GuidePoint); _haveSnapPoint = false; }
public static double LineSegmentAngle(GuidePoint point0, GuidePoint point1) { double angle = Math.Atan2(point0.Y - point1.Y, point0.X - point1.X); double result = angle * 180.0 / Math.PI; if (result < 0.0) result += 360.0; return result; }
public static bool PointIsOnLineSegment(GuidePoint point0, GuidePoint point1, GuidePoint point) { var minX = Math.Min(point0.X, point1.X); var maxX = Math.Max(point0.X, point1.X); var minY = Math.Min(point0.Y, point1.Y); var maxY = Math.Max(point0.Y, point1.Y); return(minX <= point.X && point.X <= maxX && minY <= point.Y && point.Y <= maxY); }
public static double LineSegmentsAngle(GuidePoint point0, GuidePoint point1, GuidePoint point2, GuidePoint point3) { double angle1 = Math.Atan2(point0.Y - point1.Y, point0.X - point1.X); double angle2 = Math.Atan2(point2.Y - point3.Y, point2.X - point3.X); double result = (angle2 - angle1) * 180.0 / Math.PI; if (result < 0.0) result += 360.0; return result; }
public static double LineSegmentAngle(GuidePoint point0, GuidePoint point1) { double angle = Math.Atan2(point0.Y - point1.Y, point0.X - point1.X); double result = angle * 180.0 / Math.PI; if (result < 0.0) { result += 360.0; } return(result); }
public static double LineSegmentsAngle(GuidePoint point0, GuidePoint point1, GuidePoint point2, GuidePoint point3) { double angle1 = Math.Atan2(point0.Y - point1.Y, point0.X - point1.X); double angle2 = Math.Atan2(point2.Y - point3.Y, point2.X - point3.X); double result = (angle2 - angle1) * 180.0 / Math.PI; if (result < 0.0) { result += 360.0; } return(result); }
private static bool HitTestForGuideLine(IList <GuideLine> guides, double x, double y, double treshold, out GuideLine hitGuide) { var point = new GuidePoint(x, y); foreach (var guide in guides) { var nearest = GuideHelpers.NearestPointOnLine(guide.Point0, guide.Point1, point); var distance = GuideHelpers.Distance(nearest, point); if (distance < treshold) { hitGuide = guide; return(true); } } hitGuide = null; return(false); }
public static GuidePoint NearestPointOnLine(GuidePoint a, GuidePoint b, GuidePoint p) { double ax = p.X - a.X; double ay = p.Y - a.Y; double bx = b.X - a.X; double by = b.Y - a.Y; double t = (ax * bx + ay * by) / (bx * bx + by * by); if (t < 0.0) { return(new GuidePoint(a.X, a.Y)); } else if (t > 1.0) { return(new GuidePoint(b.X, b.Y)); } return(new GuidePoint(bx * t + a.X, by * t + a.Y)); }
public static double Distance(GuidePoint point0, GuidePoint point1) { double dx = point0.X - point1.X; double dy = point0.Y - point1.Y; return Math.Sqrt(dx * dx + dy * dy); }
public static bool PointIsOnLineSegment(GuidePoint point0, GuidePoint point1, GuidePoint point) { var minX = Math.Min(point0.X, point1.X); var maxX = Math.Max(point0.X, point1.X); var minY = Math.Min(point0.Y, point1.Y); var maxY = Math.Max(point0.Y, point1.Y); return minX <= point.X && point.X <= maxX && minY <= point.Y && point.Y <= maxY; }
public static bool TryToSnapToGuideLine(IList<GuideLine> guides, GuideSnapMode mode, double treshold, GuidePoint point, out GuidePoint snap, out GuideSnapMode result) { snap = default(GuidePoint); result = default(GuideSnapMode); if (guides.Count == 0 || mode == GuideSnapMode.None) { return false; } if (mode.HasFlag(GuideSnapMode.Point)) { foreach (var guide in guides) { var distance0 = GuideHelpers.Distance(guide.Point0, point); if (distance0 < treshold) { snap = new GuidePoint(guide.Point0.X, guide.Point0.Y); result = GuideSnapMode.Point; return true; } var distance1 = GuideHelpers.Distance(guide.Point1, point); if (distance1 < treshold) { snap = new GuidePoint(guide.Point1.X, guide.Point1.Y); result = GuideSnapMode.Point; return true; } } } if (mode.HasFlag(GuideSnapMode.Middle)) { foreach (var guide in guides) { var middle = GuideHelpers.Middle(guide.Point0, guide.Point1); var distance = GuideHelpers.Distance(middle, point); if (distance < treshold) { snap = middle; result = GuideSnapMode.Middle; return true; } } } if (mode.HasFlag(GuideSnapMode.Nearest)) { foreach (var guide in guides) { var nearest = GuideHelpers.NearestPointOnLine(guide.Point0, guide.Point1, point); var distance = GuideHelpers.Distance(nearest, point); if (distance < treshold) { snap = nearest; result = GuideSnapMode.Nearest; return true; } } } if (mode.HasFlag(GuideSnapMode.Intersection)) { foreach (var guide0 in guides) { foreach (var guide1 in guides) { if (guide0 == guide1) continue; GuidePoint intersection; if (GuideHelpers.LineLineIntersection(guide0.Point0, guide0.Point1, guide1.Point0, guide1.Point1, out intersection)) { var distance = GuideHelpers.Distance(intersection, point); if (distance < treshold) { snap = intersection; result = GuideSnapMode.Intersection; return true; } } } } } double horizontal = default(double); double vertical = default(double); if (mode.HasFlag(GuideSnapMode.Horizontal)) { foreach (var guide in guides) { if (point.Y >= guide.Point0.Y - treshold && point.Y <= guide.Point0.Y + treshold) { snap = new GuidePoint(point.X, guide.Point0.Y); result |= GuideSnapMode.Horizontal; horizontal = guide.Point0.Y; break; } if (point.Y >= guide.Point1.Y - treshold && point.Y <= guide.Point1.Y + treshold) { snap = new GuidePoint(point.X, guide.Point1.Y); result |= GuideSnapMode.Horizontal; horizontal = guide.Point1.Y; break; } } } if (mode.HasFlag(GuideSnapMode.Vertical)) { foreach (var guide in guides) { if (point.X >= guide.Point0.X - treshold && point.X <= guide.Point0.X + treshold) { snap = new GuidePoint(guide.Point0.X, point.Y); result |= GuideSnapMode.Vertical; vertical = guide.Point0.X; break; } if (point.X >= guide.Point1.X - treshold && point.X <= guide.Point1.X + treshold) { snap = new GuidePoint(guide.Point1.X, point.Y); result |= GuideSnapMode.Vertical; vertical = guide.Point1.X; break; } } } if (result.HasFlag(GuideSnapMode.Horizontal) || result.HasFlag(GuideSnapMode.Vertical)) { snap = new GuidePoint( result.HasFlag(GuideSnapMode.Vertical) ? vertical : point.X, result.HasFlag(GuideSnapMode.Horizontal) ? horizontal : point.Y); return true; } return false; }
public static GuidePoint NearestPointOnLine(GuidePoint a, GuidePoint b, GuidePoint p) { double ax = p.X - a.X; double ay = p.Y - a.Y; double bx = b.X - a.X; double by = b.Y - a.Y; double t = (ax * bx + ay * by) / (bx * bx + by * by); if (t < 0.0) { return new GuidePoint(a.X, a.Y); } else if (t > 1.0) { return new GuidePoint(b.X, b.Y); } return new GuidePoint(bx * t + a.X, by * t + a.Y); }
public static GuidePoint Middle(GuidePoint point0, GuidePoint point1) { return(new GuidePoint((point0.X + point1.X) / 2.0, (point0.Y + point1.Y) / 2.0)); }
public static GuidePoint Middle(GuidePoint point0, GuidePoint point1) { return new GuidePoint((point0.X + point1.X) / 2.0, (point0.Y + point1.Y) / 2.0); }
private static bool HitTestForGuideLine(IList<GuideLine> guides, double x, double y, double treshold, out GuideLine hitGuide) { var point = new GuidePoint(x, y); foreach (var guide in guides) { var nearest = GuideHelpers.NearestPointOnLine(guide.Point0, guide.Point1, point); var distance = GuideHelpers.Distance(nearest, point); if (distance < treshold) { hitGuide = guide; return true; } } hitGuide = null; return false; }
public EditorState() { _tool = EditorTool.Spiro; _mode = EditorMode.Create; _displayKnots = true; _displayGuides = true; _snapX = 15.0; _snapY = 15.0; _enableSnap = true; _shape = null; _hitTreshold = 7; _hitTresholdSquared = 49; _hitSetShapes = new HashSet<SpiroShape>(); _hitSetPoints = new HashSet<int>(); _hitListShapes = new ObservableCollection<SpiroShape>(); _hitListPoints = new ObservableCollection<int>(); _isStroked = true; _isFilled = false; _isClosed = true; _isTagged = false; _pointType = SpiroPointType.G4; _isCaptured = false; _snapTreshold = 10.0; _snapMode = GuideSnapMode.Point | GuideSnapMode.Middle | GuideSnapMode.Intersection | GuideSnapMode.Horizontal | GuideSnapMode.Vertical; _snapPointRadius = 3.5; _snapPoint = default(GuidePoint); _haveSnapPoint = false; }
public static bool TryToSnapToGuideLine(IList <GuideLine> guides, GuideSnapMode mode, double treshold, GuidePoint point, out GuidePoint snap, out GuideSnapMode result) { snap = default(GuidePoint); result = default(GuideSnapMode); if (guides.Count == 0 || mode == GuideSnapMode.None) { return(false); } if (mode.HasFlag(GuideSnapMode.Point)) { foreach (var guide in guides) { var distance0 = GuideHelpers.Distance(guide.Point0, point); if (distance0 < treshold) { snap = new GuidePoint(guide.Point0.X, guide.Point0.Y); result = GuideSnapMode.Point; return(true); } var distance1 = GuideHelpers.Distance(guide.Point1, point); if (distance1 < treshold) { snap = new GuidePoint(guide.Point1.X, guide.Point1.Y); result = GuideSnapMode.Point; return(true); } } } if (mode.HasFlag(GuideSnapMode.Middle)) { foreach (var guide in guides) { var middle = GuideHelpers.Middle(guide.Point0, guide.Point1); var distance = GuideHelpers.Distance(middle, point); if (distance < treshold) { snap = middle; result = GuideSnapMode.Middle; return(true); } } } if (mode.HasFlag(GuideSnapMode.Nearest)) { foreach (var guide in guides) { var nearest = GuideHelpers.NearestPointOnLine(guide.Point0, guide.Point1, point); var distance = GuideHelpers.Distance(nearest, point); if (distance < treshold) { snap = nearest; result = GuideSnapMode.Nearest; return(true); } } } if (mode.HasFlag(GuideSnapMode.Intersection)) { foreach (var guide0 in guides) { foreach (var guide1 in guides) { if (guide0 == guide1) { continue; } GuidePoint intersection; if (GuideHelpers.LineLineIntersection(guide0.Point0, guide0.Point1, guide1.Point0, guide1.Point1, out intersection)) { var distance = GuideHelpers.Distance(intersection, point); if (distance < treshold) { snap = intersection; result = GuideSnapMode.Intersection; return(true); } } } } } double horizontal = default(double); double vertical = default(double); if (mode.HasFlag(GuideSnapMode.Horizontal)) { foreach (var guide in guides) { if (point.Y >= guide.Point0.Y - treshold && point.Y <= guide.Point0.Y + treshold) { snap = new GuidePoint(point.X, guide.Point0.Y); result |= GuideSnapMode.Horizontal; horizontal = guide.Point0.Y; break; } if (point.Y >= guide.Point1.Y - treshold && point.Y <= guide.Point1.Y + treshold) { snap = new GuidePoint(point.X, guide.Point1.Y); result |= GuideSnapMode.Horizontal; horizontal = guide.Point1.Y; break; } } } if (mode.HasFlag(GuideSnapMode.Vertical)) { foreach (var guide in guides) { if (point.X >= guide.Point0.X - treshold && point.X <= guide.Point0.X + treshold) { snap = new GuidePoint(guide.Point0.X, point.Y); result |= GuideSnapMode.Vertical; vertical = guide.Point0.X; break; } if (point.X >= guide.Point1.X - treshold && point.X <= guide.Point1.X + treshold) { snap = new GuidePoint(guide.Point1.X, point.Y); result |= GuideSnapMode.Vertical; vertical = guide.Point1.X; break; } } } if (result.HasFlag(GuideSnapMode.Horizontal) || result.HasFlag(GuideSnapMode.Vertical)) { snap = new GuidePoint( result.HasFlag(GuideSnapMode.Vertical) ? vertical : point.X, result.HasFlag(GuideSnapMode.Horizontal) ? horizontal : point.Y); return(true); } return(false); }