/// <summary> /// Tests whether or not the rectangle intersects a Bezier curve</summary> /// <param name="curve">Bezier curve</param> /// <param name="rect">Rectangle, in Windows coordinates, such that the top y has /// a lower value than the bottom y</param> /// <param name="tolerance">The picking tolerance</param> /// <returns>True iff the rectangle intersects the Bezier curve</returns> public static bool Intersects(BezierCurve2F curve, RectangleF rect, float tolerance) { //Note that the convex hull around the 4 control points always contains the curve. // Subdivide until we have line segments. if (curve.Flatness <= tolerance) { // Test as a line segment from P1 to P4 for simplicity's sake. This could have // some false negatives if the tangent points are far away and colinear. Seg2F segment = new Seg2F(curve.P1, curve.P4); if (Intersects(segment, rect)) { return(true); } } else { // Subdivide and try again. BezierCurve2F left, right; curve.Subdivide(0.5f, out left, out right); if (Intersects(left, rect, tolerance)) { return(true); } if (Intersects(right, rect, tolerance)) { return(true); } } return(false); }
private void TestToStringWithCulture(CultureInfo culture) { CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = culture; try { string listSeparator = culture.TextInfo.ListSeparator; string decimalSeparator = culture.NumberFormat.NumberDecimalSeparator; var o = new BezierCurve2F( new Vec2F(1.1f, 2.2f), new Vec2F(4.4f, 5.5f), new Vec2F(7.7f, 8.8f), new Vec2F(10.10f, 11.11f)); string s = o.ToString(null, null); TestToStringResults(o, s, listSeparator, decimalSeparator); string s2 = o.ToString(); Assert.AreEqual(s, s2); s = o.ToString("G", culture); TestToStringResults(o, s, listSeparator, decimalSeparator); s = o.ToString("R", culture); TestToStringResults(o, s, listSeparator, decimalSeparator); } finally { Thread.CurrentThread.CurrentCulture = originalCulture; } }
private bool PickEdge(TWire edge, Point p, Graphics g) { ElementTypeInfo fromInfo = GetElementTypeInfo(edge.FromNode, g); TPin inputPin = edge.ToRoute; TPin outputPin = edge.FromRoute; Point p1 = edge.FromNode.Bounds.Location; int x1 = p1.X + fromInfo.Size.Width; int y1 = p1.Y + GetPinOffset(outputPin.Index); Point p2 = edge.ToNode.Bounds.Location; int x2 = p2.X; int y2 = p2.Y + GetPinOffset(inputPin.Index); int tanLen = GetTangentLength(x1, x2); BezierCurve2F curve = new BezierCurve2F( new Vec2F(x1, y1), new Vec2F(x1 + tanLen, y1), new Vec2F(x2 - tanLen, y2), new Vec2F(x2, y2)); Vec2F hitPoint = new Vec2F(); return(BezierCurve2F.Pick(curve, new Vec2F(p.X, p.Y), m_theme.PickTolerance, ref hitPoint)); }
/// <summary> /// Draws a partially defined graph edge</summary> /// <param name="fromNode">Source node, or null</param> /// <param name="fromRoute">Source route, or null</param> /// <param name="toNode">Destination node, or null</param> /// <param name="toRoute">Destination route, or null</param> /// <param name="label">Edge label</param> /// <param name="endPoint">Endpoint to substitute for source or destination, if either is null</param> /// <param name="g">Graphics object</param> public override void Draw( TNode fromNode, BoundaryRoute fromRoute, TNode toNode, BoundaryRoute toRoute, string label, Point endPoint, D2dGraphics g) { // put endpoint into statechart space var inverse = g.Transform; inverse.Invert(); PointF end = Matrix3x2F.TransformPoint(inverse, endPoint); PointF p1; PointF normal1; if (fromNode != null) { p1 = ParameterToPoint(fromNode.Bounds, fromRoute.Position, out normal1); } else { p1 = end; normal1 = new Point(); } PointF p4; PointF normal2; if (toNode != null) { p4 = ParameterToPoint(toNode.Bounds, toRoute.Position, out normal2); } else { p4 = end; normal2 = new Point(); } PointF p2, p3; float d = GetTransitionPoints(p1, normal1, p4, normal2, out p2, out p3); DrawEdgeSpline(p1, p2, p3, p4, d, m_theme.OutlineBrush, g); if (!string.IsNullOrEmpty(label)) { BezierCurve2F curve = new BezierCurve2F(p1, p2, p3, p4); Vec2F midpoint = curve.Evaluate(0.5f); g.DrawText(label, m_centerText, new PointF(midpoint.X, midpoint.Y), m_theme.TextBrush); } }
private void Draw(TEdge edge, Pen pen, Graphics g) { Point p1, p2, p3, p4; float d = GetTransitionPoints(edge, out p1, out p2, out p3, out p4); DrawEdgeSpline(p1, p2, p3, p4, d, pen, g); BezierCurve2F curve = new BezierCurve2F(p1, p2, p3, p4); Vec2F midpoint = curve.Evaluate(0.5f); midpoint.X += 2; g.DrawString(edge.Label, m_theme.Font, m_theme.TextBrush, new PointF(midpoint.X, midpoint.Y)); }
private bool Pick(TEdge edge, Vec2F v) { int tolerance = m_theme.PickTolerance; Point p1, p2, p3, p4; GetTransitionPoints(edge, out p1, out p2, out p3, out p4); // check for hit on transition, away from endpoints BezierCurve2F curve = new BezierCurve2F(p1, p2, p3, p4); Vec2F hitPoint = new Vec2F(); return(BezierCurve2F.Pick(curve, v, m_theme.PickTolerance, ref hitPoint)); }
/// <summary> /// Draws a partially defined graph edge</summary> /// <param name="fromNode">Source node, or null</param> /// <param name="fromRoute">Source route, or null</param> /// <param name="toNode">Destination node, or null</param> /// <param name="toRoute">Destination route, or null</param> /// <param name="label">Edge label</param> /// <param name="endPoint">Endpoint to substitute for source or destination, if either is null</param> /// <param name="g">Graphics object</param> public override void Draw( TNode fromNode, BoundaryRoute fromRoute, TNode toNode, BoundaryRoute toRoute, string label, Point endPoint, Graphics g) { // put endpoint into statechart space endPoint = GdiUtil.InverseTransform(g.Transform, endPoint); Point p1; Point normal1; if (fromNode != null) { p1 = ParameterToPoint(fromNode.Bounds, fromRoute.Position, out normal1); } else { p1 = endPoint; normal1 = new Point(); } Point p4; Point normal2; if (toNode != null) { p4 = ParameterToPoint(toNode.Bounds, toRoute.Position, out normal2); } else { p4 = endPoint; normal2 = new Point(); } Point p2, p3; float d = GetTransitionPoints(p1, normal1, p4, normal2, out p2, out p3); DrawEdgeSpline(p1, p2, p3, p4, d, m_theme.OutlinePen, g); BezierCurve2F curve = new BezierCurve2F(p1, p2, p3, p4); Vec2F midpoint = curve.Evaluate(0.5f); midpoint.X += 2; g.DrawString(label, m_theme.Font, m_theme.TextBrush, new PointF(midpoint.X, midpoint.Y)); }
private void Draw(TEdge edge, D2dBrush brush, D2dGraphics g) { PointF p1, p2, p3, p4; float d = GetTransitionPoints(edge, out p1, out p2, out p3, out p4); DrawEdgeSpline(p1, p2, p3, p4, d, brush, g); GdiUtil.MakeRectangle(p1, p2); BezierCurve2F curve = new BezierCurve2F(p1, p2, p3, p4); Vec2F midpoint = curve.Evaluate(0.5f); midpoint.X += 2; string label = edge.Label; if (!string.IsNullOrEmpty(label)) { g.DrawText(edge.Label, m_theme.TextFormat, new PointF(midpoint.X, midpoint.Y), m_theme.TextBrush); } }
private void TestToStringResults(BezierCurve2F o, string s, string listSeparator, string decimalSeparator) { string[] results = s.Split(new[] { listSeparator }, StringSplitOptions.RemoveEmptyEntries); Assert.AreEqual(results.Length, 8); foreach (string oneFloatString in results) { Assert.True(oneFloatString.Contains(decimalSeparator)); } Assert.AreEqual(float.Parse(results[0]), o.P1.X); Assert.AreEqual(float.Parse(results[1]), o.P1.Y); Assert.AreEqual(float.Parse(results[2]), o.P2.X); Assert.AreEqual(float.Parse(results[3]), o.P2.Y); Assert.AreEqual(float.Parse(results[4]), o.P3.X); Assert.AreEqual(float.Parse(results[5]), o.P3.Y); Assert.AreEqual(float.Parse(results[6]), o.P4.X); Assert.AreEqual(float.Parse(results[7]), o.P4.Y); }