Skip to content

Commit

Permalink
Add Rectangle
Browse files Browse the repository at this point in the history
  • Loading branch information
Twinki14 committed Jan 15, 2024
1 parent 79adb2e commit 04d256e
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 57 deletions.
42 changes: 0 additions & 42 deletions src/PolyZone/Shapes/Box.cs

This file was deleted.

6 changes: 0 additions & 6 deletions src/PolyZone/Shapes/Interfaces/IBox.cs

This file was deleted.

6 changes: 6 additions & 0 deletions src/PolyZone/Shapes/Interfaces/IRectangle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace PolyZone.Shapes.Interfaces;

/// <summary>
/// A 2d rectangle / box
/// </summary>
public interface IRectangle : ISpatial2dShape;
15 changes: 6 additions & 9 deletions src/PolyZone/Shapes/Polygon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ namespace PolyZone.Shapes;
/// <param name="points">A list of <see cref="Vector2"/> in sequential order, to make-up a polygonal shape</param>
public class Polygon(IReadOnlyList<Vector2> points) : IPolygon
{
private Vector2? _min;
private Vector2? _max;
private Rectangle? _boundingBox = null;

public IReadOnlyList<Vector2> Points { get; } = points;

/// <inheritdoc cref="ISpatial2dShape.Contains"/>
public bool Contains(in Vector2 point)
{
if (_min is null || _max is null)
if (_boundingBox is null)
{
float minX = float.MaxValue, minY = float.MaxValue;
float maxX = float.MinValue, maxY = float.MinValue;
Expand All @@ -30,22 +29,20 @@ public bool Contains(in Vector2 point)
maxY = Math.Max(maxY, vertex.Y);
}

_min = new Vector2 { X = minX, Y = minY };
_max = new Vector2 { X = maxX, Y = maxY };
_boundingBox = new Rectangle(new Vector2 { X = minX, Y = minY }, new Vector2 { X = maxX, Y = maxY });
}

return Contains(point, Points, _min.Value, _max.Value);
return Contains(point, Points, _boundingBox);
}

/// <inheritdoc cref="ISpatial2dShape.DistanceFrom"/>
public float DistanceFrom(in Vector2 point) => DistanceFrom(point, Points);

// https://web.archive.org/web/20210225074947/http://geomalgorithms.com/a03-_inclusion.html
private static bool Contains(in Vector2 point, IReadOnlyList<Vector2> polygon, in Vector2 boundingBoxMin, in Vector2 boundingBoxMax)
private static bool Contains(in Vector2 point, IReadOnlyList<Vector2> polygon, in Rectangle boundingBox)
{
if (point.X < boundingBoxMin.X || point.X > boundingBoxMax.X || point.Y < boundingBoxMin.Y || point.Y > boundingBoxMax.Y)
if (!boundingBox.Contains(point))
{
// Point is outside the bounding box, so it's definitely outside the polygon
return false;
}

Expand Down
27 changes: 27 additions & 0 deletions src/PolyZone/Shapes/Rectangle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using CitizenFX.Core;
using PolyZone.Shapes.Interfaces;

namespace PolyZone.Shapes;

public class Rectangle(in Vector2 upperLeft, in Vector2 bottomRight) : IRectangle
{
public Vector2 UpperLeft { get; } = upperLeft;
public Vector2 BottomRight { get; } = bottomRight;

/// <inheritdoc cref="ISpatial2dShape.Contains"/>
public bool Contains(in Vector2 point)
{
return point.X >= UpperLeft.X && point.X <= BottomRight.X &&
point.Y >= UpperLeft.Y && point.Y <= BottomRight.Y;
}

/// <inheritdoc cref="ISpatial2dShape.DistanceFrom"/>
public float DistanceFrom(in Vector2 point)
{
// Calculate the distance using Euclidean distance formula
var dx = Math.Max(Math.Max(UpperLeft.X - point.X, 0), point.X - BottomRight.X);
var dy = Math.Max(Math.Max(UpperLeft.Y - point.Y, 0), point.Y - BottomRight.Y);

return (float) Math.Sqrt(dx * dx + dy * dy);
}
}

0 comments on commit 04d256e

Please sign in to comment.