dpc / hex2d-rs

Helper library for working with 2d hex-grid maps
MIT License
64 stars 16 forks source link

Collision detection? #22

Open cheako opened 4 years ago

cheako commented 4 years ago

I'm working on a project that at it's heart is hex2d, but it doesn't look that way to the users. You might have played Bubble Shooter.

The issue I'm trying to tackle is that I have a line segment(in pixels as f32/origin, direction in radians, and distance) that represents movement in the given frame. This creates a rectangle and I would like to generate a list of the new Coordinates that this rectangle clips.

dpc commented 4 years ago

Oh, wow. IIRC there was a function to get hex from pair of f32, but how to do the area ... Hmmm.. You could run this function in a nested loop for every point with some delta_x and delta_y... if you know what delta would make sense.

cheako commented 4 years ago

I was able to more accurately describe what I'm looking for. https://www.reddit.com/r/theydidthemath/comments/dyqr1o/request_hexgrid2d_moving_circle_collision/

The issue with testing only a subset of locations is that a collision could occur in between two, say if the circles would just barely not touch at both points but definitely collide. For the normal case a line segment's normal will intersect with hex center and at those points collision should be calculated as that's specifically the point of closest approach. So the question becomes at what point does this vector(origin and direction)'s normal next intersect a hex center and is that distance longer than the remaining distance to travel.

I have discovered that I may need to test collision explicitly at the end point of the movement, to avoid drawing the circles overlapping. For that I'm open to precalculating a 2d btreemap(search_linear?) containing a vector of will intersect and might intersect neighbors where distance calculation occurs only on might hit.

cheako commented 4 years ago

I've been thinking about using const fn to calculate a Btree<height at center: f32/f64, Btree<radians: f32/f64, T>>. The idea is to get an approximate answer, by chosing first less than. Name suggestions for T welcome.

struct T {
    \\! The lowest coordinate on the tile.
    bottom: [f32/f64; 2],
    \\! The intersections to check.
    perpendiculars: Vec<(Direction, [f32/f64; 2])>,
    \\! The first coordinate above the tile.
    above: [f32/f64; 2],
    \\! The directions next tile is.
    above_direction: Direction,
    \\! The directions to check from next tile
    above_ways: Vec<Direction>,
    \\! The new above height
    above_height: f32/f64,
}

With this it should be easy to resolve any collisions. above_ways is used to check for collisions that doesn't intersect a perpendicular.