Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Hey who want's to contribute to an open source project? ;D

This thread is locked; no one can reply to it. rss feed Print
Hey who want's to contribute to an open source project? ;D
Mark Oates
Member #1,146
March 2001
avatar

I have a class in AllegroFlare called placement2d. It's quite nice and I've found it to be incredibly useful again and again. Now that it's the middle of KrampusHack, I find that it's missing a bit of functionality ;)

placement2d.h
placement2d.cpp

Basically, placement2d is a wrapped ALLEGRO_TRANSFORM, but it's wrapped in such a way that you only have to specify position, size, alignment, scale, rotation, and anchor parameters directly, without having to worry about the transform itself. It can be used for the position of an object, like a sprite or GUI widgets. placement2d' s transformations can be set and restored, or even nested inside the transforms of other placement2d s. There is also a companion placement3d that operates in the same way (while placement3d can build a reverse transform and act as a camera).

Anyhoo!

The placement2d has the ability to find out if it collides with a point (placement2d::collide(float x, float y)), but it has yet do provide the ability to detect collisions with other placement2d objects.

An implementation might use the separating axis theorem, or there might be a simpler way that combines the two transformations and does some magic? I haven't had time to work it out, but maybe somebody has a magic bullet? :)

TL;DR can somebody fill this in for me, I'm lazy :-* :

bool placement2d::collide(const placement2d &other)
{
   // write your code here, kthx
}

GullRaDriel
Member #3,861
September 2003
avatar

Use an existing lib to mix with yours for the colliding part ?

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

SiegeLord
Member #7,827
October 2006
avatar

How can a matrix collide with a matrix ???

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Mark Oates
Member #1,146
March 2001
avatar

It has a width, height, x, and y. As well as rotation, anchor, and scale parameters.

Elias
Member #358
May 2000

So all you want is a function which decides whether two rectangles overlap? (Where each rectangle may be transformed by a different matrix)

[edit:] I think all you need to do is loop over the lines of each and check if they overlap the lines of the other.

So basically:

For each line of rectangle A, go through each line of rectangle B, and call line_line_collision(A.lines[i], B.lines[j]). If any of the lines collide, so do the rectangles.

If none of them collide, either your rectangles do not collide, or one of them is completely inside the other. If you want to distinguish those three cases, take any vertex of A and check if it is inside of B (just compare the sign of the dot product to all 4 half planes). If it is inside A is inside of B. Otherwise check if B is inside of A. Otherwise they are completely separate.

In short, you can reduce the problem to writing these two very simple functions:

- line_line_collision(line1, line2)
- is_vertex_inside(x, y, lines[])

--
"Either help out or stop whining" - Evert

Dizzy Egg
Member #10,824
March 2009
avatar

bool placement2d::collide(const placement2d &other)
{
   return(dizzyMagicCollision(&this, other));
}

Done.

EDIT:

Ok ok ok, I get it - a lot of you are rolling your eyes, so I'll do it properly (ie, use the proper arguments):

bool placement2d::collide(const placement2d &other)
{
   return(dizzyMagicCollision(&this, &that, &the, other));
}

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

LennyLen
Member #5,313
December 2004
avatar

bool placement2d::collide(const placement2d &other)
{
   return ((rand() % 100 > 49) ? true : false);
}

Dizzy Egg
Member #10,824
March 2009
avatar

Oh for gods sake Lenny....way to make me look stupid! >:(

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Elias
Member #358
May 2000

#SelectExpand
1private bool line_line_collision2d(float l1x1, float l1y1, float l1x2, float l1y2, float l2x1, float l2y1, float l2x2, float l2y2) { 2 float ax = l1x2 - l1x1; 3 float ay = l1y2 - l1y1; 4 float bx = l2x2 - l2x1; 5 float by = l2y2 - l2y1; 6 float cx = l2x1 - l1x1; 7 float cy = l2y1 - l1y1; 8 float ab = cross2d(ax, ay, bx, by); 9 float ca = cross2d(cx, cy, ax, ay); 10 float cb = cross2d(cx, cy, bx, by); 11 if (ab == 0) { 12 return 0; 13 } 14 if (ab < 0) { 15 if (ca > 0 || cb > 0) { 16 return 0; 17 } 18 if (ca < ab || cb < ab) { 19 return 0; 20 } 21 } 22 else { 23 if (ca < 0 || cb < 0) { 24 return 0; 25 } 26 if (ca > ab || cb > ab) { 27 return 0; 28 } 29 } 30 return 1; 31} 32 33float cross2d(float ax, float ay, float bx, float by) { 34 return ax * by - ay * bx; 35} 36 37bool placement2d::collide(const placement2d &other) 38{ 39 float l1x1 = 0, l1y1 = 0, l1x2 = w, l1y2 = 0; 40 transform_coordinates(&l1x1, &l1y1); 41 transform_coordinates(&l1x2, &l1y2); 42 float l2x1 = 0, l2y1 = 0, l2x2 = w, l2y2 = 0; 43 other.transform_coordinates(&l2x1, &l2y1); 44 other.transform_coordinates(&l2x2, &l2y2); 45 bool c1 = line_line_collision(l1x1, l1y1, l1x2, l1y2, l2x1, l2y1, l2x2, l2y2); 46 // same for all other combinations of lines 47 ... 48 return c1 || c2 || ...; 49}

--
"Either help out or stop whining" - Evert

Mark Oates
Member #1,146
March 2001
avatar

Elias said:

(mikedrop)

Wow! Thanks Elias! Dang that could take me all night to work out. :o

I feel like there might be a way to transform the 2nd transform into the 1st transform's space so that the 2nd placement2d could be tested along the coordinate plane.

There aren't enough days...

Felix-The-Ghost
Member #9,729
April 2008
avatar

There aren't enough days...

QFFT :'(

==========================
<--- The ghost with the most!
---------------------------
[Website] [Youtube]

Tyler Wrobel
Member #16,594
November 2016

You could use a sin and cos algorithm that with a function that creates an array of theoretical points alongside the exterior of the sprite/object in the game which needs to possess a boundary.

Then you could implement a secondary circumstantial function that only executes when a certain situation persist( i.e. the enemy/ other object to which the main object will interact with but only calculates the parameters for objects within a certain distance; mostly to conserve ram, process cycles etc.).

Than within this second function could calculate a rasterization of the environmental objects co-ordinates on the screen to test against.

Edit: Additional talking points.

Also,

1. You can find a lot of information on converting pixel area's (graphics) for implementation in situations like this in just about probably any books on any of the mainstream graphics platforms, ie OpenGl, Windows Graphics, or Computer
Graphics for Dummies.

2. You could use some form of initialization before your game posts, or after the main menu but before run time of the actually game play, to perform bitmap blitting on the individual sprites to obtain the data for these kind of calculations so they do not need to be all done on the fly. An implementation of both would probably provide for the highest level of flexibility and performance.

Mark Oates
Member #1,146
March 2001
avatar

Thanks everybody for your contributions :)

I haven't been able to get around to trying the different implementations. One day I will! :)

Go to: