/// <summary> /// Returns all the portal intersections for a line in this path. /// TFirst is the t value for the line intersection. /// TLast is the t value for the portal intersection. /// </summary> /// <param name="line"></param> /// <returns></returns> public static IntersectCoord[] PathIntersections(PortalPath path, LineF line) { IntersectCoord[] intersections = new IntersectCoord[path.Portals.Count]; line = line.ShallowClone(); LineF[] portalLines = new LineF[path.Portals.Count]; for (int i = 0; i < path.Portals.Count; i++) { portalLines[i] = new LineF(GetWorldVerts(path.Portals[i])); } for (int i = path.Portals.Count - 1; i >= 0; i--) { Matrix4 mat = GetLinkedMatrix(path.Portals[i].Linked); line[1] = line.Transform(mat)[1]; for (int j = i + 1; j < path.Portals.Count; j++) { portalLines[j] = portalLines[j].Transform(mat); } } for (int i = 0; i < path.Portals.Count; i++) { intersections[i] = MathExt.LineLineIntersect(portalLines[i], line, true); } return intersections; }
public void IntersectTest8() { LineF line0 = new LineF(new Vector2(1f, 1f), new Vector2(2f, 2f)); LineF line1 = new LineF(new Vector2(3f, 9f), new Vector2(12f, -6f)); IntersectCoord intersect = MathExt.LineLineIntersect(line0, line1, false); IntersectCoord comparison = new IntersectCoord(); comparison.Exists = true; comparison.Position = new Vector2d(5.25, 5.25); comparison.TFirst = 4.25; comparison.TLast = 0.25; Assert.IsTrue(intersect.Equals(comparison)); }
public void IntersectTest7() { LineF line0 = new LineF(new Vector2(1f, 1f), new Vector2(2f, 2f)); LineF line1 = new LineF(new Vector2(3f, 9f), new Vector2(12f, -6f)); IntersectCoord intersect = MathExt.LineLineIntersect(line0, line1, true); IntersectCoord comparison = new IntersectCoord(); comparison.Exists = false; Assert.IsTrue(intersect.Equals(comparison)); }
public void IntersectTest6() { LineF line0 = new LineF(new Vector2(1f, 1f), new Vector2(2f, 2f)); LineF line1 = new LineF(new Vector2(1.5f, 3f), new Vector2(1.5f, -1.5f)); IntersectCoord intersect = MathExt.LineLineIntersect(line0, line1, false); IntersectCoord comparison = new IntersectCoord(); comparison.Exists = true; comparison.Position = new Vector2d(1.5, 1.5); comparison.TFirst = 0.5; comparison.TLast = 1/(double)3; Assert.IsTrue(intersect.Equals(comparison)); }
public void IntersectTest5() { LineF line0 = new LineF(new Vector2(), new Vector2(0, -1000000f)); LineF line1 = new LineF(new Vector2(-0.5f, -1000000), new Vector2(0.5f, -1000000f)); IntersectCoord intersect = MathExt.LineLineIntersect(line0, line1, true); IntersectCoord comparison = new IntersectCoord(); comparison.Exists = true; comparison.Position = new Vector2d(0, -1000000); comparison.TFirst = 1; comparison.TLast = 0.5; Assert.IsTrue(intersect.Equals(comparison)); }
private static void _rayCast(IPortalable placeable, IEnumerable<IPortal> portals, double movementLeft, IPortal portalPrevious, Action<EnterCallbackData, double> portalEnter, Settings settings, int count) { Transform2 begin = placeable.GetTransform(); Transform2 velocity = placeable.GetVelocity().Multiply(settings.TimeScale); if (settings.MaxIterations <= count) { //If we run out of iterations before running out of movement, call _rayEnd with 0 movementLeft just to make sure the AdjustEnpoint setting is handled. _rayEnd(placeable, portals, 0, portalPrevious, settings, begin, velocity); return; } if (!placeable.IsPortalable) { _rayEnd(placeable, portals, movementLeft, portalPrevious, settings, begin, velocity); return; } double distanceMin = movementLeft; IPortal portalNearest = null; IntersectCoord intersectNearest = new IntersectCoord(); LineF ray = new LineF(begin.Position, begin.Position + velocity.Position); foreach (IPortal p in portals) { if (!Portal.IsValid(p) || portalPrevious == p) { continue; } LineF portalLine = new LineF(Portal.GetWorldVerts(p)); IntersectCoord intersect = MathExt.LineLineIntersect(portalLine, ray, true); double distance = ((Vector2d)begin.Position - intersect.Position).Length; if (intersect.Exists && distance < distanceMin) { distanceMin = distance; portalNearest = p; intersectNearest = intersect; } } if (portalNearest != null) { movementLeft -= distanceMin; double t = (velocity.Position.Length - movementLeft) / velocity.Position.Length; begin.Position = (Vector2)intersectNearest.Position; placeable.SetTransform(begin); Portal.Enter(portalNearest, placeable, (float)intersectNearest.TFirst, true); portalEnter?.Invoke(new EnterCallbackData(portalNearest, placeable, intersectNearest.TFirst), t); movementLeft *= Math.Abs(placeable.GetTransform().Size / begin.Size); _rayCast(placeable, portals, movementLeft, portalNearest.Linked, portalEnter, settings, count + 1); } else { _rayEnd(placeable, portals, movementLeft, portalPrevious, settings, begin, velocity); } }