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 Seg2F(new Vec2F(1.1f, 2.2f), new Vec2F(3.3f, 4.4f)); 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; } }
/// <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); }
/// <summary> /// Tests if a segment intersects a rectangle</summary> /// <param name="seg">The segment</param> /// <param name="rect">Rectangle, in Windows coordinates, such that the top y has /// a lower value than the bottom Y</param> /// <returns>True iff the segment intersects the rectangle</returns> public static bool Intersects(Seg2F seg, RectangleF rect) { // Quick acceptance if (rect.Contains(seg.P1) || rect.Contains(seg.P2)) { return(true); } // Check if both segment points are on same side of rectangle. if (seg.P1.X < rect.Left && seg.P2.X < rect.Left) { return(false); } if (seg.P1.Y < rect.Top && seg.P2.Y < rect.Top) { return(false); } if (seg.P1.X > rect.Right && seg.P2.X > rect.Right) { return(false); } if (seg.P1.Y > rect.Bottom && seg.P2.Y > rect.Bottom) { return(false); } // Check if all four rectangle points are on the same side of the line. Vec2F dir = new Vec2F(seg.P2.X - seg.P1.X, seg.P2.Y - seg.P1.Y); if (dir.LengthSquared > Seg2F.DegenerateLength * Seg2F.DegenerateLength) { Vec2F normal = dir.Perp; float dot1 = Vec2F.Dot(new Vec2F(rect.Left, rect.Top) - seg.P1, normal); float dot2 = Vec2F.Dot(new Vec2F(rect.Right, rect.Top) - seg.P1, normal); if (dot1 * dot2 > 0) // both are < 0 or both are > 0 { dot2 = Vec2F.Dot(new Vec2F(rect.Left, rect.Bottom) - seg.P1, normal); if (dot1 * dot2 > 0) // both are < 0 or both are > 0 { dot2 = Vec2F.Dot(new Vec2F(rect.Right, rect.Bottom) - seg.P1, normal); if (dot1 * dot2 > 0) // both are < 0 or both are > 0 { return(false); } } } } // Must intersect. return(true); }
private void TestToStringResults(Seg2F o, string s, string listSeparator, string decimalSeparator) { string[] results = s.Split(new[] { listSeparator }, StringSplitOptions.RemoveEmptyEntries); Assert.AreEqual(results.Length, 4); 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); }
public Line(int index, MapLinedef linedef, Vec2F start, Vec2F end, Side front, Side back = null) { Index = index; Front = front; Back = new Optional <Side>(back); Segment = new Seg2F(start, end); Unpegged = ToUnpegged(linedef); front.Line = this; if (back != null) { back.Line = this; } }
private bool Pick(TEdge edge, Vec2F p) { bool result = false; Vec2F nearest = new Vec2F(); Vec2F startPoint = new Vec2F(); Vec2F endPoint = new Vec2F(); CircleF c = new CircleF(); bool moreThan180 = false; int route = edge.FromRoute.Index; if (GetEdgeGeometry(edge, route, ref startPoint, ref endPoint, ref c, ref moreThan180)) { Seg2F seg = new Seg2F(startPoint, endPoint); nearest = Seg2F.Project(seg, p); if (Vec2F.Distance(nearest, p) < m_theme.PickTolerance) { result = true; } } else { if (CircleF.Project(p, c, ref nearest)) { if (Vec2F.Distance(nearest, p) < m_theme.PickTolerance) { Vec2F startToEnd = endPoint - startPoint; Vec2F startToCenter = c.Center - startPoint; Vec2F startToP = p - startPoint; float pdp1 = Vec2F.PerpDot(startToCenter, startToEnd); float pdp2 = Vec2F.PerpDot(startToP, startToEnd); bool side = pdp1 * pdp2 < 0; result = moreThan180 ^ side; } } } return(result); }
public BoxCornerTracers(Seg2F first, Seg2F second, Seg2F third) { First = first; Second = second; Third = third; }
public CompactBspNode(uint leftChildBits, uint rightChildBits, Seg2F splitter) { LeftChildBits = leftChildBits; RightChildBits = rightChildBits; Splitter = splitter; }
/// <summary> /// Picks one or more control points within given rectangle</summary> /// <param name="curves">Curves on which to pick points</param> /// <param name="pickRect">Rectangle bounding picked control points</param> /// <param name="points">Points picked</param> /// <param name="regions">PointSelectionRegions of picked points</param> public void PickPoints(ReadOnlyCollection <ICurve> curves, RectangleF pickRect, List <IControlPoint> points, List <PointSelectionRegions> regions) { points.Clear(); regions.Clear(); if (curves == null) { return; } foreach (ICurve curve in curves) { if (!curve.Visible) { continue; } ReadOnlyCollection <IControlPoint> curvePoints = curve.ControlPoints; for (int i = 0; i < curvePoints.Count; i++) { IControlPoint cpt = curvePoints[i]; Vec2F clientcpt = m_canvas.GraphToClient(cpt.X, cpt.Y); if (pickRect.Contains(clientcpt)) { points.Add(cpt); regions.Add(PointSelectionRegions.Point); } else if (curve.CurveInterpolation != InterpolationTypes.Linear && cpt.EditorData.SelectedRegion != PointSelectionRegions.None) { bool pickTanOut = cpt.TangentOutType != CurveTangentTypes.Stepped && cpt.TangentOutType != CurveTangentTypes.SteppedNext; if (pickTanOut) { Vec2F tangOut = Vec2F.Normalize(m_canvas.GraphToClientTangent(cpt.TangentOut)); Seg2F seg = new Seg2F(clientcpt, (clientcpt + tangOut * m_tangentLength)); if (GdiUtil.Intersects(seg, pickRect)) { points.Add(cpt); regions.Add(PointSelectionRegions.TangentOut); continue; } } bool pickTanIn = true; if (i > 0) { IControlPoint prevCpt = curvePoints[i - 1]; pickTanIn = prevCpt.TangentOutType != CurveTangentTypes.Stepped && prevCpt.TangentOutType != CurveTangentTypes.SteppedNext; } if (pickTanIn) { // pick tangentIn. Vec2F tangIn = Vec2F.Normalize(m_canvas.GraphToClientTangent(cpt.TangentIn)); tangIn.X = -tangIn.X; tangIn.Y = -tangIn.Y; Seg2F seg = new Seg2F(clientcpt, (clientcpt + tangIn * m_tangentLength)); if (GdiUtil.Intersects(seg, pickRect)) { points.Add(cpt); regions.Add(PointSelectionRegions.TangentIn); } } } } } // foreach curve in curves }