how to detect the 2d normals of a 2d shape (image) ?

Started by RemiD, November 23, 2022, 22:19:00

Previous topic - Next topic

RemiD

hi, :)

how to detect the 2d normals of a 2d shape (image) ?

for example, i have a 2d shape, but there are no triangle normals on a 2d shape (image)...

so my idea is to use a 'collider' 2d image, with the same shape of the 'render' 2d image, but with its outline marked with different colors, each color representing a 2d normal value, so that i can know the 2d normals of the shape.

and when the ball collides with the outline of the shape, i can read the color of the texel of the collision, to know what is the 2d normal (to calculate a reflection vector for example)

your thoughts ?

Matty

There kind of is....

If you take a line of equation y = mx + c, good old straight line equation, then a line that is perpendicular to that is a line with gradient of -1/m

That's for a straight line, but the general principle holds for other lines too:

if y = f(x), then the gradient of the line or slope is y = f'(x), and the perpendicular equation can be derived from -1 / f'(x)

The only problem is - most images aren't representable by a simple mathematical equation, or at least their edge isn't.

However if you have fairly simple geometric shapes that you can represent the edges with an equation - such as rectangles and circles and triangles, then it's not too hard to simply find the gradient of the edge in question, then invert it and multiply by -1. That will give you the slope of the perpendicular to that edge, or the normal

RemiD

@Matty>> ah i see, so the approach would be to store the points making the outline of the shape so that i can check collisions between the ball translation vector and the lines of the shape ?
and for each line i can derive a 2d normal...

i am going to try that.

thanks !

Matty

While that would work and is a good way to do it - since I know you like using blitz3d - if you want to do it in 3d but look 2d, simply use an orthographic view, make your shapes as per normal but give them a height/depth or thickness and then use the collision routine as per normal.

eg if your shape being struck is a rectangle then instead make it a rectangle with depth, but have it facing the orthographic camera such that you can't actually see the sides of the rectangle - only the face of the rectangle that is facing the camera. Then collisonnx() etc will do it all for you.

that's another way that makes blitz do all the math for you.

RemiD

yes i know that i can do it in 3d with flat meshes made of triangles, but i want to code a game with orientations, movements, collision detection and repositionning, all in 2D with pixels and images, and learn the maths formulas required. just for the challenge ;D


then i am going to make a version of the game in 3d (breakout 3d).

STEVIE G

I'd start with creating a signed distance field version of the image so that you can check penetration depth easily and move out of collisions. I don't think there'd be an easy way to determine a normal and assign the x,y vector in the color channels too (similar to normal maps) but you could raycast a sample of the pixels around the moving object, , check dot products and calculate a cumulative reflection vector.

RemiD

for not turning shapes, it is easy to predraw the colors of the pixels of the outline. (each color corresponding to a 2d normal)

but for turning shapes, it would not work, so it is better to store the points making the lines of the outline. and then calculate the 2d normal of the 2d line, outwards.

blinkok

AGK lets you set a polygon collision shape for an image

RemiD

i use blitz3d...

and i want to learn the math formulas...

RemiD

so i have the math formula to calculate if 2 lines intersect (or not) and the intersection point.

i know the points of the lines making the outline of the collider of the shape (image).

i can calculate the normal of each line, but for each line there are 2 normals (one on each side).

so in order to choose the normal pointing outward of the shape, my idea was to project a point along the 2 normals (of the line), and check which projected point is nearest to the start point of the other line (the line which has intersected with the line of the outline).

this should work...

your thoughts ?

Matty

A really simple method works for convex shapes:

Find the centre point of the shape, x1,y1.

As you are correct there are two normals.

Project along that normal a tiny amount from the collision point - if it brings you closer to the centre then it's the negative normal, if it takes you further away it's the positive normal.

RemiD

all right, i figured out how to calculate the 2 2d normals of a 2d line (using crossproduct and inversed cross product).