From acf87b533008c05223eddfb7da07939c18506204 Mon Sep 17 00:00:00 2001 From: Evan Hemsley Date: Sat, 14 Sep 2019 21:24:36 -0700 Subject: [PATCH] shapes and hashing --- content/broad_phase/introduction.md | 1 + content/broad_phase/spatial_hash.md | 46 +++++++++++++++++++++++-- content/getting_started/installation.md | 4 ++- content/shapes/circle.md | 6 ++-- content/shapes/introduction.md | 10 +++--- content/shapes/polygon.md | 19 ++++++++++ content/shapes/rectangle.md | 16 +++++++++ 7 files changed, 90 insertions(+), 12 deletions(-) create mode 100644 content/shapes/polygon.md create mode 100644 content/shapes/rectangle.md diff --git a/content/broad_phase/introduction.md b/content/broad_phase/introduction.md index 56da65d..7dab1ec 100644 --- a/content/broad_phase/introduction.md +++ b/content/broad_phase/introduction.md @@ -1,6 +1,7 @@ --- title: "Introduction" date: 2019-09-14T18:36:07-07:00 +weight: 5 --- Let's say we have a room with 100 objects. How do we know if any of those 100 objects are touching one another? diff --git a/content/broad_phase/spatial_hash.md b/content/broad_phase/spatial_hash.md index 6da9dac..87f3ed0 100644 --- a/content/broad_phase/spatial_hash.md +++ b/content/broad_phase/spatial_hash.md @@ -1,6 +1,48 @@ --- -title: "Spatial_hash" +title: "Spatial Hash" date: 2019-09-14T18:35:33-07:00 -draft: true +weight: 10 --- +In spatial hashing, we place each object into one or more "buckets". Think of a grid covering 2D space. When an object's bounding box covers one of the cells in this grid, it is placed into that cell. Any two unique objects that occupy the same cell are determined to be *potentially colliding*. + +In Bonk, a spatial hash is defined by its ID type and a cell size. The ID type is used to filter objects. Any two objects with the same ID are assumed to not be colliding. + +```cs +var hash = new SpatialHash(32); +``` + +This spatial hash will use C# **GUID**s as its ID type and a cell size of 32. + +To insert an object into the hash, use the **Insert** method and give an ID, an IShape2D, and a Transform2D. + +```cs +var hash = new SpatialHash(16); + +var circle = new MoonTools.Core.Bonk.Circle(8); +var circleTransform = new Transform2D(new Vector2(16, 16)); + +var rect = new Rectangle(-2, -2, 2, 2); +var rectTransform = new Transform2D(new Vector2(8, 8)); + +hash.Insert(0, circle, circleTransform); +hash.Insert(1, rect, rectTransform); +``` + +To find potential collisions, use the **Retrieve** method and give an ID, an IShape2D, and a Transform2D. + +```cs +spatialHash.Retrieve(1, rectB, rectBTransform); +``` + +In this example, the above method call returns an *IEnumerable<(T, IShape2D, Transform)>* containing the circle information we inserted. + +What if we want to update our SpatialHash based on the movements of objects? Simply clear the hash and insert all the objects again. + +```cs +hash.Clear(); + +// Re-insert objects here +``` + +That's it! This is everything you need to use a spatial hash for broad-phase collision. \ No newline at end of file diff --git a/content/getting_started/installation.md b/content/getting_started/installation.md index 0a58974..731549f 100644 --- a/content/getting_started/installation.md +++ b/content/getting_started/installation.md @@ -23,4 +23,6 @@ Once you have done this, you may access Bonk functionality by including using MoonTools.Core.Bonk; ``` -in any C# file. \ No newline at end of file +in any C# file. + +Of course, you are free to include the source code directly in your project as well, but this is less convenient. \ No newline at end of file diff --git a/content/shapes/circle.md b/content/shapes/circle.md index 812a6c7..3dc1a8d 100644 --- a/content/shapes/circle.md +++ b/content/shapes/circle.md @@ -4,10 +4,8 @@ date: 2019-09-14T19:46:44-07:00 weight: 20 --- -To define a circle, give a center point and radius. +To define a circle, give a radius. ```cs -var center = new Position2D(5, 5); -var radius = 3; -var circle = new Circle(center, radius); +var circle = new Circle(3); ``` \ No newline at end of file diff --git a/content/shapes/introduction.md b/content/shapes/introduction.md index 709d78c..1ccd6b8 100644 --- a/content/shapes/introduction.md +++ b/content/shapes/introduction.md @@ -4,14 +4,14 @@ date: 2019-09-14T19:19:03-07:00 weight: 5 --- -In Bonk, a **Shape2D** is defined by two methods. +In Bonk, an **IShape2D** is defined by two methods. -1) A *support function*, which is a method that returns the farthest possible position **Vector2** in a given **Vector2** direction defined by the shape with its vertices transformed by a **Transform2D** +1) A *support function*, which is a method that returns the farthest possible point in the shape in a given **Vector2** direction. The shape vertices are transformed by a **Transform2D**. -2) A method for creating an axis-aligned bounding box from the shape. +2) A method for creating an axis-aligned bounding box from the shape that takes a **Transform2D** to transform the shape vertices. -Bonk provides you with 4 built-in common 2D shapes, but you can implement these methods to create custom **Shape2D** structs. +Bonk provides you with tested implementations of four common 2D shapes, but you can implement these methods to create custom **IShape2D** structs. -Note that these shapes should be defined with zero-centered **Position2D** structs. You will use a **Transform2D** to manipulate the shape's position, rotation, and scale in 2D space. +Note that shapes themselves do not contain absolute position data. You will use a **Transform2D** to manipulate the shape's position, rotation, and scale in 2D space. A final restriction to note: Defining concave shapes is an error. The collision solving algorithm that Bonk uses does not support concave shapes. If you wish to define concave shapes, define them as a composition of multiple convex shapes. \ No newline at end of file diff --git a/content/shapes/polygon.md b/content/shapes/polygon.md new file mode 100644 index 0000000..e35f628 --- /dev/null +++ b/content/shapes/polygon.md @@ -0,0 +1,19 @@ +--- +title: "Polygon" +date: 2019-09-14T20:55:54-07:00 +weight: 40 +--- + +To define a polygon, pass a variable number of **Position2D** structs representing the points of the polygon. + +```cs + var polygon = new Polygon( + new Position2D(0, 0), + new Position2D(-1, -1), + new Position2D(1, -1), + new Position2D(1, 1), + new Position2D(-1, 1) + ); +``` + +Be careful not to define a concave Polygon, as this will cause the results of collision detection to be incorrect. \ No newline at end of file diff --git a/content/shapes/rectangle.md b/content/shapes/rectangle.md new file mode 100644 index 0000000..124c2e9 --- /dev/null +++ b/content/shapes/rectangle.md @@ -0,0 +1,16 @@ +--- +title: "Rectangle" +date: 2019-09-14T20:37:23-07:00 +weight: 30 +--- + +To define a rectangle, give a minimum X and Y and a maximum X and Y. + +```cs +var minX = -1; +var minY = -1; +var maxX = 1; +var maxY = 1; +var rectangle = new Rectangle(minX, minY, maxX, maxY); +``` +