• Create Account

# Soundstone

Member Since 28 Jan 2013
Offline Last Active Apr 08 2014 11:40 PM

### In Topic: Linear collision question

06 February 2014 - 08:08 PM

I figured I would post the full solution in case anyone ever needs to use this again. Here is how I was able to solve the collision checks for both the ceiling and the floor - both of which are generated randomly with array of Vector3.

In the game loop I calculate if the player is close enough to the ceiling to be worthy of checking and the same goes for the floor. If the player is close enough I use a for loop to cycle through the vector3 positions of the ceiling / floor points. It continues over the points that are too far from the player. Once it finds a pair of contiguous points it sends a call out to check the ceiling or floor for collision based on these two points. Here is the cycle in game loop:

```for (int i = 0; i < NUM_POINTS; i++)
{
if (ship.shipPos.x > topPoints[i + 1].x)
continue;
if (ship.shipPos.x < topPoints[i].x)
continue;

collide = CheckCollisionsTop(ship, topPoints[i], topPoints[i + 1]);
} ```

Below you'll see the collision check for my ceiling. It takes a reference to a SpaceShip because eventually it will alter the ship's position based on collision. It also takes 2 Vector3 positions.  The line segment is just a new vector that contains the distance between pointTwo and pointOne. The shipWidthPosition alters the ship position to test based on which side of the ship we want to test. This matters for the direction of the line in question. If the line is upwards - pointTwo.y is higher than pointOne.y then we will use normal ship position since the (X,Y,Z) of shipPos is the upper left corner of the ship. For a downward line (pointOne.y is higher than pointTwo.y) then we use the other side by adding the width to the ships coords.

```bool CheckCollisionsTop(SpaceShip &ship, Vector3 pointOne, Vector3 pointTwo)
{
Vector3 lineSegment = GetVectorDistance(pointOne, pointTwo);
Vector3 shipWidthPosition(ship.shipPos.x + ship.GetWidth(), ship.shipPos.y, ship.shipPos.z);

if (pointTwo.y < pointOne.y) //upwards line
{
Vector3 lineNormal(lineSegment.y, -lineSegment.x, 0);
double u = GetVectorDistance(ship.shipPos, pointTwo) * lineNormal;

if (u > 0)
return false;
else if (u < 0)
return true;
}
else if (pointTwo.y > pointOne.y) //downwards line
{
Vector3 lineNormal(lineSegment.y, -lineSegment.x, 0);
double u = GetVectorDistance(shipWidthPosition, pointOne) * lineNormal;

if (u > 0)
return false;
else if (u < 0)
return true;
}
}
```

And here is the collision check for the floor - differs slightly in ship testing coordinates, the sign of "u" and the normal of the line is different.

```bool CheckCollisionsBottom(SpaceShip &ship, Vector3 pointOne, Vector3 pointTwo)
{
Vector3 lineSegment = GetVectorDistance(pointOne, pointTwo);
Vector3 shipHeightPosition(ship.shipPos.x, ship.shipPos.y + ship.GetHeight(), ship.shipPos.z);
Vector3 shipWidthHeightPosition(ship.shipPos.x + ship.GetWidth(), ship.shipPos.y + ship.GetHeight(), ship.shipPos.z);

if (pointTwo.y < pointOne.y) //upwards line
{
Vector3 lineNormal(-lineSegment.y, lineSegment.x, 0);
double u = GetVectorDistance(shipWidthHeightPosition, pointTwo) * lineNormal;

if (u > 0)
return false;
else if (u < 0)
return true;
}
else if (pointTwo.y > pointOne.y) //downwards line
{
Vector3 lineNormal(-lineSegment.y, lineSegment.x, 0);
double u = GetVectorDistance(shipHeightPosition, pointTwo) * lineNormal;

if (u > 0)
return false;
else if (u < 0)
return true;
}
}
```

If you have needed linear collision, then I hope this has been some help to you.

### In Topic: Linear collision question

05 February 2014 - 11:16 PM

Thanks Haegarr,

I finally got the algorithm working for the ceiling. It kind of works for the floor at this moment, but I'm sure I'm pretty close to it. Once again thanks for the help.

Regards

### In Topic: Allegro bitmaps at runtime?

25 January 2014 - 08:01 PM

Hi Fastcall,

Thanks for the reply! The information was a relief to hear. Would you recommend printing the entire thing to one bitmap and then drawing a region of that bitmap with al_draw_bitmap_region() or just keep a bitmap the size of my screen and keep clearing / drawing the new sets of points to it before blitting to the display? Thanks again.

### In Topic: Linear collision question

14 January 2014 - 09:03 PM

Hi Haegarr, thanks for the continued input. I feel like I'm really close to getting this, but there is part of it that eludes me visually. To better explain where I am getting lost, I'd like to provide an example and work the steps out here for it. As you know I am not necessarily trying to draw a perpendicular line, rather instead use the math behind the perpendicular line to decide whether or not my square has collided with a line.

I have an array of points P[0] through P[4000]. Each of these points in the array are end points for a line. They are all spaced 36 units away from each other along the X axis.

lets say P[42] = (105, 50) and P[43] = (141, 82)

The distance vector is represented by Dn = (Dx , Dy) where as in this example Dx = (141 - 105) = 36 and Dy = (82 - 50) = 32;

Thus Dn = (36, 32)

From DnI can gather that the magnitude (length) of the line L = (P[42], P[43]) is equal to sqrt(36^2 + 32^2) = 48.17

If I'm understanding everything correctly so far then Vn = either (-32, 36) or (32, -36) depending on the direction I want my perpendicular vector to go. One is good for my ceiling and the other is good for my floor.

In this example, I'm worried about the ceiling so I'll choose Vn = (32, -36).

This is where my mind loses its grasp.

I believe I normalize this new vector Vn by  (32 / -36) / sqrt(32^2 + (-36)^2) giving me -.019.

If I plot similarly scaled coords on graph paper, I can see that my perpendicular line is correct based on the point Dn but it is way off based on the coords of P[42]  and P[43].

I am not grasping how to determine the "start" point of this perpendicular line. By this I mean the perpendicular line will run infinitely parallel to itself across the line P[42], P[43] (for all the points on the line segment), How does this apply to getting the relative point on the original line?

Once I grasp this step (above), I think that all I have to do is generate the distance between the point of interest (my square) and the line, and as long as its above 0 I'll be below the line.

I apologize if this is convoluted but this is the best way I could pose a question to you to further understand it. As always thanks for your time.

Regards

### In Topic: Linear collision question

07 January 2014 - 04:08 PM

Thanks for the continued information Haegarr.

I've had some internet problems with a snow storm over the weekend so I haven't been able to get on to respond. I've made some progress but I don't believe that I've done it correctly.  I am having a little difficulty trying to determine what your variables in the formulas stand for.

I get the Pn is the a point for the line. I assume that dn is the distance between the two points. At this point, I kind of get lost. What is Dx and Dy? Are these the individual distances from x and y? Is Vn just a new point of (Distance of y, -Distance of x) for the start of the perpendicular to the point of interest? From here you have the equation    pn + t * dn + u * vn = c.

Again I understand Pn to be one of the original points (does it matter which?)  t I'm not sure about. dnI once again assume is distance calculated from point 1 to point 2 of initial line. U I'm not sure about. Same with Vn. All of this adds (add multiplies) to the point of interest c?

I apologize for sounding completely ignorant in this matter, and I thank you for the time you have already taken on this. Could you please explain the variables a little better.

Also here is a new screenshot of what I've accomplished thus far using this forum thread.

The blue lines are simply drawn from points 1 and 2 of line to point of interest. The yellow line was my initial attempt (ended up being parallel in regards to square's placement against line) and the red line is calculated as half the x and half the y difference between the two points, then drawn to the point of interest.

New Picture

Thanks again for your help thus far.

PARTNERS