private void AssertNoOverlap(LineSeg la, LineSeg lb, double av, double dv) { LineSeg o, b, a; bool ab, aa; OverlayFn(la, lb, av, dv, out b, out ab, out o, out a, out aa); Assert.IsNull(o); }
private void DrawEdge(Edge e, Pen pen, Graphics graphics) { ICurve curve = e.Curve; Curve c = curve as Curve; if (c != null) { foreach (ICurve s in c.Segs) { LineSeg l = s as LineSeg; if (l != null) { graphics.DrawLine(pen, GleePointToDrawingPoint(l.Start), GleePointToDrawingPoint(l.End)); } CubicBezierSeg cs = s as CubicBezierSeg; if (cs != null) { graphics.DrawBezier(pen, GleePointToDrawingPoint(cs.B(0)), GleePointToDrawingPoint(cs.B(1)), GleePointToDrawingPoint(cs.B(2)), GleePointToDrawingPoint(cs.B(3))); } } if (e.ArrowHeadAtSource) { DrawArrow(e, pen, graphics, e.Curve.Start, e.ArrowHeadAtSourcePosition); } if (e.ArrowHeadAtTarget) { DrawArrow(e, pen, graphics, e.Curve.End, e.ArrowHeadAtTargetPosition); } } }
public LineSeg[] GenerateLineSegs(float height, Vertex2D tangent, IItem item) { if (_gateData.TwoWay) { return(new LineSeg[0]); } var halfLength = _gateData.Length * 0.5f; var angleMin = MathF.Min(_gateData.AngleMin, _gateData.AngleMax); // correct angle inversions var angleMax = MathF.Max(_gateData.AngleMin, _gateData.AngleMax); _gateData.AngleMin = angleMin; _gateData.AngleMax = angleMax; // oversize by the ball's radius to prevent the ball from clipping through var rgv = new[] { _gateData.Center.Clone().Add(tangent.Clone().MultiplyScalar(halfLength + PhysicsConstants.PhysSkin)), _gateData.Center.Clone().Sub(tangent.Clone().MultiplyScalar(halfLength + PhysicsConstants.PhysSkin)), }; var lineSeg = new LineSeg(rgv[0], rgv[1], height, height + 2.0f * PhysicsConstants.PhysSkin, ItemType.Gate, item); //!! = ball diameter lineSeg.SetElasticity(_gateData.Elasticity); lineSeg.SetFriction(_gateData.Friction); return(new[] { lineSeg }); }
public GOTileCell(Vector3 center, GameObject marker, Vector2 arrayPosition, float edge_x, float edge_z) { this.center = center; this.marker = marker; this.arrayPosition = arrayPosition; this.edge_x = edge_x; this.edge_z = edge_z; LineSeg top_edge = new LineSeg( new Vector2(center.x - (edge_x / 2), center.z + (edge_z / 2)), new Vector2(center.x + (edge_x / 2), center.z + (edge_z / 2))); LineSeg right_edge = new LineSeg( new Vector2(center.x + (edge_x / 2), center.z + (edge_z / 2)), new Vector2(center.x + (edge_x / 2), center.z - (edge_z / 2))); LineSeg bottom_edge = new LineSeg( new Vector2(center.x + (edge_x / 2), center.z - (edge_z / 2)), new Vector2(center.x - (edge_x / 2), center.z - (edge_z / 2))); LineSeg left_edge = new LineSeg( new Vector2(center.x - (edge_x / 2), center.z - (edge_z / 2)), new Vector2(center.x - (edge_x / 2), center.z + (edge_x / 2))); edges = new List <LineSeg> { top_edge, right_edge, bottom_edge, left_edge }; }
public override void Search(LineSeg s, double dist, Dictionary <int, LSeg> r) { foreach (Pair <LSeg, LinkedListNode <LNode> > l in m_segs.Values) { r[l.First.Keyval] = l.First; } }
public PlungerHit(PlungerData data, float zHeight) : base(ItemType.Plunger) { _data = data; _zHeight = zHeight; _x = _data.Center.X - _data.Width; _y = _data.Center.Y + _data.Height; _x2 = _data.Center.X + _data.Width; FrameTop = data.Center.Y - data.Stroke; FrameBottom = data.Center.Y; FrameLen = FrameBottom - FrameTop; RestPos = data.ParkPosition; Position = FrameTop + RestPos * FrameLen; // static LineSegBase = new LineSeg(new Vertex2D(_x, _y), new Vertex2D(_x2, _y), zHeight, zHeight + Plunger.PlungerHeight, ItemType.Plunger); JointBase[0] = new HitLineZ(new Vertex2D(_x, _y), zHeight, zHeight + Plunger.PlungerHeight, ItemType.Plunger); JointBase[1] = new HitLineZ(new Vertex2D(_x2, _y), zHeight, zHeight + Plunger.PlungerHeight, ItemType.Plunger); // dynamic LineSegSide[0] = new LineSeg(new Vertex2D(_x + 0.0001f, Position), new Vertex2D(_x, _y), zHeight, zHeight + Plunger.PlungerHeight, ItemType.Plunger); LineSegSide[1] = new LineSeg(new Vertex2D(_x2, _y), new Vertex2D(_x2 + 0.0001f, Position), zHeight, zHeight + Plunger.PlungerHeight, ItemType.Plunger); LineSegEnd = new LineSeg(new Vertex2D(_x2, Position), new Vertex2D(_x, Position), zHeight, zHeight + Plunger.PlungerHeight, ItemType.Plunger); JointEnd[0] = new HitLineZ(new Vertex2D(_x, Position), zHeight, zHeight + Plunger.PlungerHeight, ItemType.Plunger); JointEnd[1] = new HitLineZ(new Vertex2D(_x2, Position), zHeight, zHeight + Plunger.PlungerHeight, ItemType.Plunger); }
public override void Search(LineSeg s, double dist, Dictionary <int, LSeg> res) { if (m_s != null) { m_s.Search(s, dist, res); } }
public void TestNonOverlaps() { foreach (LineSeg l in Take(1000, LineSegs)) { double t = Double(); // 0..1 Vector dir = l.Dir; if (Boolean()) { t *= -1; dir = dir * -1.0; } else { t += 1.001; } LineSeg ll = new LineSeg(l.Start + (l.Dir * t), dir); LineSeg o = null; LineSeg before = null; LineSeg after = null; bool ab, af; OverlayFn(l, ll, 0.0001, l.Dir.LengthSq * 0.000001, out before, out ab, out o, out after, out af); Assert.IsNull(o); Assert.IsNull(before); Assert.IsNull(after); } }
private IPolyline assemblePolyLine(List <LineSeg> segs) { IPolyline ln = new PolylineClass(); double dsq = m_dtol * m_dtol; ISegmentCollection path = new PathClass(); // List<LineSeg> sorted = new List<LineSeg>();; // for (int i = 0; i < segs.Count; i++) { // LineSeg prior = (i > 0 ? sorted[i-1] : null); // LineSeg next = (i < segs.Count-1 ? segs[i+1] : null); // sorted.Add(appropriatelySwapped(dsq,prior,segs[i],next)); // } // for (int i = 0; i < /*sorted*/ segs.Count; i++) { LineSeg l = /*sorted*/ segs[i]; ILine part = new LineClass(); IPoint fromp = new PointClass(); fromp.X = l.Start.X; fromp.Y = l.Start.Y; IPoint top = new PointClass(); top.X = l.End.X; top.Y = l.End.Y; part.FromPoint = fromp; part.ToPoint = top; object ignored = System.Reflection.Missing.Value; path.AddSegment((ISegment)part, ref __missing, ref __missing); } (ln as IGeometryCollection).AddGeometry((IGeometry)path, ref __missing, ref __missing); ln.SpatialReference = m_spref; return(ln); }
public override List <LineSeg> GetLineSegs() { List <LineSeg> lineSeg = new List <LineSeg>(); foreach (Hitable hitable in Substraction) { lineSeg.AddRange(hitable.GetLineSegs()); } for (int i = 0; i < lineSeg.Count; i++) { LineSeg seg = lineSeg[i]; seg.Normal = -lineSeg[i].Normal; lineSeg[i] = seg; } lineSeg.AddRange(Minuend.GetLineSegs()); lineSeg = LineSeg.DivideByIntersection(lineSeg); for (int i = 0; i < lineSeg.Count; i++) { if (!Minuend.IsInside(lineSeg[i].Position) || IsInSubstraction(lineSeg[i].Position)) { lineSeg.RemoveAt(i--); } } return(lineSeg); }
public GateHit(GateData data, float height) : base(ItemType.Gate) { var data1 = data; var height1 = height; var halfLength = data1.Length * 0.5f; var radAngle = MathF.DegToRad(data1.Rotation); var sn = MathF.Sin(radAngle); var cs = MathF.Cos(radAngle); LineSeg0 = new LineSeg( new Vertex2D( data1.Center.X - cs * (halfLength + PhysicsConstants.PhysSkin), data1.Center.Y - sn * (halfLength + PhysicsConstants.PhysSkin) ), new Vertex2D( data1.Center.X + cs * (halfLength + PhysicsConstants.PhysSkin), data1.Center.Y + sn * (halfLength + PhysicsConstants.PhysSkin) ), height1, height1 + 2.0f * PhysicsConstants.PhysSkin, ItemType.Gate ); LineSeg1 = new LineSeg( new Vertex2D(LineSeg0.V2.X, LineSeg0.V2.Y), new Vertex2D(LineSeg0.V1.X, LineSeg0.V1.Y), height, height + 2.0f * PhysicsConstants.PhysSkin, ItemType.Gate ); TwoWay = false; }
public override List <LineSeg> GetLineSegs() { List <LineSeg> lineSeg1 = new List <LineSeg>(); List <LineSeg> lineSeg2 = new List <LineSeg>(); List <LineSeg> lineSeg = new List <LineSeg>(); lineSeg1.AddRange(O1.GetLineSegs()); lineSeg1 = LineSeg.DivideByIntersection(lineSeg1); for (int i = 0; i < lineSeg1.Count; i++) { if (O2.IsInside(lineSeg1[i].Position)) { lineSeg.Add(lineSeg1[i]); } } lineSeg2.AddRange(O2.GetLineSegs()); lineSeg2 = LineSeg.DivideByIntersection(lineSeg2); for (int i = 0; i < lineSeg2.Count; i++) { if (O1.IsInside(lineSeg2[i].Position)) { lineSeg.Add(lineSeg2[i]); } } return(lineSeg); }
private List <GOTileCell> CellsIntersectedAround(GOTileCell c, LineSeg l, List <GOTileCell> cells = null, List <GOTileCell> tagged = null, NodeVert v1 = null, NodeVert v2 = null) { // init if (cells == null) { cells = new List <GOTileCell>(); } if (tagged == null) { tagged = new List <GOTileCell>(); } foreach (var cell in SurroundingCellsOf(c)) { if (cell != null && !cells.Contains(cell)) { if (cell.marker.GetComponent <MeshRenderer>().material.color != Color.green) { cell.marker.GetComponent <MeshRenderer>().material.color = Color.black; } cells.Add(cell); //cell.marker.GetComponent<NodeMarker>().LineTestedFrom(v1, v2, cell.edges); if (CellIntersectedBy(cell, l)) // && !tagged.Contains(cell) { tagged.Add(cell); CellsIntersectedAround(cell, l, cells, tagged, v1, v2); // recursion } } } return(tagged); }
private void checkBox(Aabb box) { IEnumerable <LineSeg> segs = Gen <LineSeg>(delegate() { return(LineSeg.FromEndpoints(PointInside(box), PointOutside(box))); }); foreach (LineSeg ls in Take(100, segs)) { Assert.IsTrue(box.Intersects(ls)); LineSeg outline = new LineSeg(ls.End, ls.Dir); Assert.IsFalse(box.Intersects(outline)); LineSeg swapped = LineSeg.FromEndpoints(ls.End, ls.Start); Assert.IsTrue(box.Intersects(swapped)); // neither endpoint is inside but the line def. crosses LineSeg crossing = new LineSeg(ls.Start - ls.Dir, ls.Dir * 2.0); Assert.IsTrue(box.Intersects(crossing)); // Shift it outside of the box by moving it sideways a min amt... double shift_length = Math.Sqrt(box.W * box.W + box.H * box.H); Vector shift = shift_length * crossing.Dir.Normalize().Perp; LineSeg out1 = new LineSeg(crossing.Start + shift, crossing.Dir); Assert.IsFalse(box.Intersects(out1)); } }
public Fragment Next; // next connected fragment public void Split(out Fragment a, LineSeg aseg, out Fragment b, LineSeg bseg) { a = new Fragment(); a.m_l = aseg; a.Sources = this.Sources; b = new Fragment(); b.m_l = bseg; b.Sources = this.Sources; a.Prev = Prev; a.Next = b; b.Prev = a; a.Next = Next; }
public LineVerts(NodeVert a, NodeVert b, List <LineSeg> edges) { this.a = a; this.b = b; lineSeg = new LineSeg(a.transform.position, b.transform.position); this.edgesTested = edges; }
public OverlapSegment(LineSeg s, ArcSegInf m, ArcSegInf o) { Seg = s; Fid = m.SrcFid; OFid = o == null ? -1 : o.SrcFid; Shell = m.ShellNum; OShell = o == null ? -1 : o.ShellNum; SegNum = m.SegNum; OSegNum = o == null ? -1 : o.SegNum; }
public override void Search(LineSeg s, double dist, Dictionary <int, LSeg> res) { foreach (Node n in Children) { if (n.Intersects(s, dist)) { n.Search(s, dist, res); } } }
public IEnumerable <IIndexedSeg> SearchByLineSeg(LineSeg o, double dist) { LinkedListNode <IHasLine> cur = m_segments.First; while (cur != null) { yield return(new Handle(cur)); cur = cur.Next; } }
/// Return all segements that might lie w/in a given distance. public IEnumerable <IIndexedSeg> SearchByLineSeg(LineSeg o, double dist) { Dictionary <int, LSeg> r = new Dictionary <int, LSeg>(); m_root.Search(o, dist, r); foreach (LSeg l in r.Values) { yield return(l); } }
public override List <LineSeg> GetLineSegs() { List <LineSeg> lineSeg = new List <LineSeg>(); lineSeg.AddRange(O1.GetLineSegs()); lineSeg.AddRange(O2.GetLineSegs()); lineSeg = LineSeg.DivideByIntersection(lineSeg); //for (int i = 0; i < lineSeg.Count; i++) // if (O1.IsInside(lineSeg[i].Position) && O1.IsOnBoundary(lineSeg[i].Position) || // O2.IsInside(lineSeg[i].Position) && O2.IsOnBoundary(lineSeg[i].Position)) lineSeg.RemoveAt(i); return(lineSeg); }
/// 如果端点在前,返回true,否则是false /// <param name="ray"></param> /// <param name="p1">端点</param> /// <param name="p2">交点</param> private static void HitLineSeg(Ray ray, uint line, out Point p1, out Point p2, out bool b1, out bool b2) { LineSeg lineSeg = new LineSeg(ray.Origin, ray.NormalDirection * (float.MaxValue / 10000) + ray.Origin, LineSegs[line].Normal, 0); float p1l = ray.Direction.Magnitude(); float p2l = float.MaxValue; p1 = new Point(LineSegs[line].Material, line, ray.Direction + ray.Origin); p2 = new Point(); b1 = true; b2 = false; for (uint i = 0; i < LineSegs.Length; i++) { if (line == i) { continue; } if (!LineSeg.IsIntersect(lineSeg, LineSegs[i], out Vector2 vector2)) { continue; } if (vector2 == p1.Position) { continue; } if (vector2 == LineSegs[i].P1 || vector2 == LineSegs[i].P2) { continue; } float l = (ray.Origin - vector2).Magnitude(); if (l < p1l && b1) { b1 = false; } if (l < p2l) { p2l = l; if (l < p1l || LineSegs[i].Normal * (ray.Origin - LineSegs[i].Position) < 0) { b2 = false; continue; } p2 = new Point(LineSegs[i].Material, i, vector2); b2 = true; } } if (b2 && (p2.Position == LineSegs[p2.Line].P1 || p2.Position == LineSegs[p2.Line].P2)) { b2 = false; } }
protected virtual void OverlayFn(LineSeg a, LineSeg b, double ang_tol, double distsqtol, out LineSeg before, out bool a_before, out LineSeg overlap, out LineSeg after, out bool a_after) { LineSeg.Overlay(a, b, Vector.GetParTolerance(ang_tol), distsqtol, out before, out a_before, out overlap, out after, out a_after); }
public void TestRotated() { double max_rotang = 10.0 / 180.0 * Math.PI; double ang_tol = max_rotang; foreach (LineSeg l in Take(1000, LineSegs)) { double ang = Double() * max_rotang; if (Boolean()) { ang = -ang; } LineSeg ll = new LineSeg(l.Start, l.Dir.Rotate(ang)); // Come up w/ an appropriate distance threshold // (that ll will pass.) double threshdist = Math.Sin(ang) * l.Dir.Length * 2.0; threshdist *= threshdist; LineSeg o = null; LineSeg before = null; LineSeg after = null; bool ab, af; OverlayFn(l, ll, ang_tol, threshdist, out before, out ab, out o, out after, out af); Assert.IsNull(before); Assert.IsNotNull(o); if (after != null) { Assert.Greater(after.Dir.LengthSq, threshdist); // Measure the expected length... double nlength = Math.Cos(ang) * o.Dir.Length; Assert.Less(o.Dir.Length, nlength * 1.001); Assert.Greater(o.Dir.Length, nlength * 0.9999); } else { Assert.Less(o.Dir.LengthSq, l.Dir.LengthSq * 1.0001); } //Assert.Greater(o.Dir.LengthSq, nlength * 0.99); } }
public void TestOverlapsShifted() { double ang_tol = (0.001 / 180.0 * Math.PI); foreach (LineSeg l in Take(1000, LineSegs)) { double dist = Double(); double dist_sq = (dist * dist) * 1.00001; while (dist_sq > l.Dir.LengthSq) { dist = Double(); dist_sq = (dist * dist) * 1.00001; } Vector shift = l.Dir.Perp.Normalize() * dist; LineSeg ll = new LineSeg(l.Start + shift, l.Dir); LineSeg o = null; LineSeg before = null; LineSeg after = null; bool ab, af; // First, with itself: OverlayFn(l, l, ang_tol, dist_sq, out before, out ab, out o, out after, out af); Assert.IsNull(before); Assert.IsNull(after); Assert.IsNotNull(o); // same length modulo epsilon Assert.Less(o.Dir.LengthSq, l.Dir.LengthSq * 1.00001); // Now with the shifted version: OverlayFn(l, ll, ang_tol, dist_sq, out before, out ab, out o, out after, out af); Assert.IsNull(before); Assert.IsNull(after); Assert.IsNotNull(o); Assert.Less(o.Dir.LengthSq, l.Dir.LengthSq * 1.00001); Assert.Greater(o.Dir.LengthSq, l.Dir.LengthSq * 0.9999); } }
public SpinnerHit(SpinnerData data, float height) : base(ItemType.Spinner) { var halfLength = data.Length * 0.5f; var radAngle = MathF.DegToRad(data.Rotation); var sn = MathF.Sin(radAngle); var cs = MathF.Cos(radAngle); var v1 = new Vertex2D( data.Center.X - cs * (halfLength + PhysicsConstants.PhysSkin), // through the edge of the data.Center.Y - sn * (halfLength + PhysicsConstants.PhysSkin) // spinner ); var v2 = new Vertex2D( data.Center.X + cs * (halfLength + PhysicsConstants.PhysSkin), // oversize by the ball radius data.Center.Y + sn * (halfLength + PhysicsConstants.PhysSkin) // this will prevent clipping ); LineSeg0 = new LineSeg(v1, v2, height, height + 2.0f * PhysicsConstants.PhysSkin, ItemType.Spinner); LineSeg1 = new LineSeg(v2.Clone(), v1.Clone(), height, height + 2.0f * PhysicsConstants.PhysSkin, ItemType.Spinner); }
// tag cell by line segment private void TagCellsOnLine(Vector3 a, Vector3 b, string name = null, NodeVert v1 = null, NodeVert v2 = null) { // start at a GOTileCell starting_cell = ClosestCellTo(a); LineSeg line = new LineSeg(a, b); if (v1 == null || v2 == null) { Debug.LogWarning("no verts in TagCellsOnLine"); } foreach (var cell in CellsIntersectedAround(starting_cell, line, null, null, v1, v2)) { cell.marker.GetComponent <NodeMarker>().IntersectsWithLine(name); // update marker if (!taggedCells.Contains(cell)) { taggedCells.Add(cell); // add tagged cell } } }
// IEnumerable< starting and ending SegNum, Connected-line-segments > for a given feature & shell public IEnumerable <Pair <Pair <int, int>, List <LineSeg> > > GetStrings(Pair <Pair <int, int>, Pair <int, int> > key) { List <OverlapSegment> vs = m_parts[key]; // Sort by segment #. vs.Sort(delegate(OverlapSegment a, OverlapSegment b) { return(a.SegNum.CompareTo(b.SegNum)); }); LineSeg last_seg = null; int start_segnum = -1; int cur_segnum = -1; List <LineSeg> cur_seg = null; foreach (OverlapSegment s in vs) { // if there is a 'jump'! if (last_seg != null && s.SegNum - cur_segnum != 1) { Pair <int, int> range = new Pair <int, int>(start_segnum, cur_segnum); yield return(new Pair <Pair <int, int>, List <LineSeg> >(range, cur_seg)); last_seg = null; } if (last_seg == null) { last_seg = s.Seg; start_segnum = s.SegNum; cur_seg = new List <LineSeg>(); } cur_segnum = s.SegNum; cur_seg.Add(s.Seg); } if (cur_seg != null && cur_seg.Count > 0) { Pair <int, int> range = new Pair <int, int>(start_segnum, cur_segnum); yield return(new Pair <Pair <int, int>, List <LineSeg> >(range, cur_seg)); } }
private List <PointString> DivOnePoly(int index) { PointString poly = _roadPolys[index]; List <double> divs = new List <double>(); for (int i = 0; i < _roadPolys.Count; i++) { if (i != index) { PointString poly2 = _roadPolys[i]; for (int j = 0; j < poly.Points.Count - 1; j++) { LineSeg seg = poly.GetSegAt(j); for (int k = 0; k < poly2.Points.Count - 1; k++) { LineSeg seg2 = poly2.GetSegAt(k); LineSegIntersect intr = new LineSegIntersect(seg, seg2); if (intr.Intersect()) { divs.Add(j + intr.RatioAB); } } } } } divs.Insert(0, 0); divs.Add(poly.Points.Count - 1); divs = divs.Distinct().OrderBy(x => x).ToList(); List <PointString> result = new List <PointString>(); for (int i = 0; i < divs.Count - 1; i++) { PointString subPoly = poly.GetSubPoly(divs[i], divs[i + 1]); if (subPoly.Length() > 0.1) // subtle { result.Add(subPoly); } } return(result); }
private void DrawNode(Node n, Pen pen, Graphics graphics) { ICurve curve = n.MovedBoundaryCurve; Ellipse el = curve as Ellipse; if (el != null) { graphics.DrawEllipse(pen, new RectangleF((float)el.BBox.Left, (float)el.BBox.Bottom, (float)el.BBox.Width, (float)el.BBox.Height)); } else { Curve c = curve as Curve; foreach (ICurve seg in c.Segs) { LineSeg l = seg as LineSeg; if (l != null) { graphics.DrawLine(pen, GleePointToDrawingPoint(l.Start), GleePointToDrawingPoint(l.End)); } } } }