public IEnumerable <ICell> GetVisibleCells(Vector2 pov, float radius) { var visible = GetCells(); var obstacles = GetCellsOfType(CellType.Tree) .Where(x => Vector2.Distance(x.Bounds.Center.ToVector2(), pov) < radius); visible = visible .Where(x => Vector2.Distance(x.Bounds.Center.ToVector2(), pov) < radius); var notVisible = new List <ICell>(); foreach (var obstacle in obstacles) { var ray = new Ray2( pov, Vector2.Subtract(obstacle.BoundingRectangle.Center, pov)); foreach (var cell in visible) { if (cell.Equals(obstacle)) { continue; } if (ray.Intersects(cell.BoundingRectangle, out var rayNearDistance, out var rayFarDistance)) { var distanceToCell = Vector2.Distance(pov, cell.BoundingRectangle.Center); var distanceToObstacle = Vector2.Distance(pov, obstacle.BoundingRectangle.Center); if (rayNearDistance >= 0 && rayFarDistance >= 0 && distanceToCell > distanceToObstacle) { notVisible.Add(cell); } } } visible = visible.Except(notVisible); } return(visible); }
public static bool Crosses(this Ray2 ray, BoundingRectangle boundingRectangle, out float near, out float far) { if (ray.Direction.X < 0 && ray.Direction.Y < 0) { if (boundingRectangle.Center.X - boundingRectangle.HalfExtents.X > ray.Position.X || boundingRectangle.Center.Y - boundingRectangle.HalfExtents.Y > ray.Position.Y) { near = float.NaN; far = float.NaN; return(false); } BoundingRectangle dummyRect = new BoundingRectangle( new Point2(2 * ray.Position.X - boundingRectangle.Center.X, 2 * ray.Position.Y - boundingRectangle.Center.Y), boundingRectangle.HalfExtents); Ray2 dummyRay = new Ray2(ray.Position, new Vector2(-ray.Direction.X, -ray.Direction.Y)); return(dummyRay.Intersects(dummyRect, out near, out far)); } if (ray.Direction.X < 0) { if (boundingRectangle.Center.X - boundingRectangle.HalfExtents.X > ray.Position.X || boundingRectangle.Center.Y + boundingRectangle.HalfExtents.Y < ray.Position.Y) { near = float.NaN; far = float.NaN; return(false); } BoundingRectangle dummyRect = new BoundingRectangle( new Point2(2 * ray.Position.X - boundingRectangle.Center.X, boundingRectangle.Center.Y), boundingRectangle.HalfExtents); Ray2 dummyRay = new Ray2(ray.Position, new Vector2(-ray.Direction.X, ray.Direction.Y)); return(dummyRay.Intersects(dummyRect, out near, out far)); } if (ray.Direction.Y < 0) { if (boundingRectangle.Center.X + boundingRectangle.HalfExtents.X < ray.Position.X || boundingRectangle.Center.Y - boundingRectangle.HalfExtents.Y > ray.Position.Y) { near = float.NaN; far = float.NaN; return(false); } BoundingRectangle dummyRect = new BoundingRectangle( new Point2(boundingRectangle.Center.X, 2 * ray.Position.Y - boundingRectangle.Center.Y), boundingRectangle.HalfExtents); Ray2 dummyRay = new Ray2(ray.Position, new Vector2(ray.Direction.X, -ray.Direction.Y)); return(dummyRay.Intersects(dummyRect, out near, out far)); } if (boundingRectangle.Center.X + boundingRectangle.HalfExtents.X < ray.Position.X || boundingRectangle.Center.Y + boundingRectangle.HalfExtents.Y < ray.Position.Y) { near = float.NaN; far = float.NaN; return(false); } return(ray.Intersects(boundingRectangle, out near, out far)); }
public void intersects_point_test() { var ray = new Ray2(new Point2(2, 1), new Vector2(2, 1)); Assert.False(ray.Intersects(new Point2(-2, -1))); Assert.False(ray.Intersects(new Point2(0, 0))); Assert.True(ray.Intersects(new Point2(6, 3))); Assert.True(ray.Intersects(new Point2(2, 1))); Assert.True(ray.Intersects(new Point2(4, 2))); Assert.False(ray.Intersects(new Point2(1, 2))); }