More Collision (again)
It seems highly unlikely that distance + 45 would be less than 13... and if it were, distance most certainly would be less than 13.
What are you trying to do?
What are you trying to do?
Quote:Originally posted by Iceman
I'm still having some problems. Ok this is what I'm doing now:
Is there any way I can have distance be a continuous bubble like "if ( (0.0 < distance < 45) < 13 ?) {}" instead of having two collision bubbles where one adds 45?Code:
if (distance < 13 && distance + 45 < 13) {
// delete rock
}
Iceman
For some reason that if() statement looks like its confused like me? =)
Why not do this instead?
Code:
if(distance < 13)
{
//do stuff
}
I don't understand what you are trying to do either. Are you trying something from that Gamasutra article? I didn't read it.
Right now, it looks like what your code says can be simplified to:
I know that that cannot be right....
I just thought of something. Are you attempting to compensate for the length of your laser beam as it shows for each frame, as in the beam is 45 units long? If this is the case, which I am becoming more and more sure of as I type this, then try computing the distance from each end of the laser beam to the target separately and then making your conditional statement.
There may be some optimizations possible, but I'm about to go to bed. G'night.
Right now, it looks like what your code says can be simplified to:
Code:
if (distance < -32) {
// delete rock
}I know that that cannot be right....
I just thought of something. Are you attempting to compensate for the length of your laser beam as it shows for each frame, as in the beam is 45 units long? If this is the case, which I am becoming more and more sure of as I type this, then try computing the distance from each end of the laser beam to the target separately and then making your conditional statement.
Code:
if (distanceFromFrontOfLaser < 13 || distanceFromBackOfLaser < 13) {
// delete rock
}There may be some optimizations possible, but I'm about to go to bed. G'night.
Wait, my code above wouldn't even detect the collision if the rock was halfway down the beam as I imagined it.... Either ignore that stuff, or, if I was correct in my assumption about the length of the laser, adapt it to your own stuff with different numbers so that it is sure to detect the collision.
Since your laser beam is a segment of a line, and you are checking for intersection with a point, it is natural that you miss a collision happening midway through the beam. You would have to check for a collision with every point on your laser segment (or maybe just a few representative ones).
However you can check for a collision between a line and a sphere . I don't remember everything by heart and don't have time to calculate it right now but here is the idea.
You have the parametric equation for a line which is
Point=PointOfOrigin+var+OrientationVector
and the one for a sphere x^2+y^2+z^2=r^2
Now the trick is to insert the equation for each of the x,y and z components of a point on the line in place of the x,y,z components in the sphere equation... after that you isolate var (most likely a quadratic equation) then you can just use the equation for the line to retrieve the exact point of intersection (Well, two of them since it is a quadratic).
You can now check if it is in the laser segment of the line...
This is just a suggestion... I know it works mathematically but not how effective it can be in a game setting. Of course there are probably tons of optimizations to be done once you are done resolving these equations...
However you can check for a collision between a line and a sphere . I don't remember everything by heart and don't have time to calculate it right now but here is the idea.
You have the parametric equation for a line which is
Point=PointOfOrigin+var+OrientationVector
and the one for a sphere x^2+y^2+z^2=r^2
Now the trick is to insert the equation for each of the x,y and z components of a point on the line in place of the x,y,z components in the sphere equation... after that you isolate var (most likely a quadratic equation) then you can just use the equation for the line to retrieve the exact point of intersection (Well, two of them since it is a quadratic).
You can now check if it is in the laser segment of the line...
This is just a suggestion... I know it works mathematically but not how effective it can be in a game setting. Of course there are probably tons of optimizations to be done once you are done resolving these equations...
Since your laser beam is a segment of a line, and you are checking for intersection with a point, it is natural that you miss a collision happening midway through the beam. You would have to check for a collision with every point on your laser segment (or maybe just a few representative ones).
However you can check for a collision between a line and a sphere . I don't remember everything by heart and don't have time to calculate it right now but here is the idea.
You have the parametric equation for a line which is
Point=PointOfOrigin+var+OrientationVector
and the one for a sphere x^2+y^2+z^2=r^2
Now the trick is to insert the equation for each of the x,y and z components of a point on the line in place of the x,y,z components in the sphere equation... after that you isolate var (most likely a quadratic equation) then you can just use the equation for the line to retrieve the exact point of intersection (Well, two of them since it is a quadratic).
You can now check if it is in the laser segment of the line...
This is just a suggestion... I know it works mathematically but not how effective it can be in a game setting. Of course there are probably tons of optimizations to be done once you are done resolving these equations...
Ah.. I forgot to say... but if the equation for var doesn't have any roots, then it means there is no intersection... since it is much easier to find this than to resolve var completely (at least less expensive in CPU time) I believe it could be pretty fast.
However you can check for a collision between a line and a sphere . I don't remember everything by heart and don't have time to calculate it right now but here is the idea.
You have the parametric equation for a line which is
Point=PointOfOrigin+var+OrientationVector
and the one for a sphere x^2+y^2+z^2=r^2
Now the trick is to insert the equation for each of the x,y and z components of a point on the line in place of the x,y,z components in the sphere equation... after that you isolate var (most likely a quadratic equation) then you can just use the equation for the line to retrieve the exact point of intersection (Well, two of them since it is a quadratic).
You can now check if it is in the laser segment of the line...
This is just a suggestion... I know it works mathematically but not how effective it can be in a game setting. Of course there are probably tons of optimizations to be done once you are done resolving these equations...
Ah.. I forgot to say... but if the equation for var doesn't have any roots, then it means there is no intersection... since it is much easier to find this than to resolve var completely (at least less expensive in CPU time) I believe it could be pretty fast.
You could do that, or, if you are really lazy, you could just shorten the line segment so that it would detect a collision whether from the front or the back if the target happened to be in the middle of the beam.... Only if you're lazy.
Sorry I was a little confused on how to mathematically explain what I was trying to get. Yes geezusfreeek the distance + 45 is the end of the segment and distance is the beginning. The reason I'm using this is because the laser is pretty long and the rocks usually travel right through the back end of the laser since it's not a quake style flash
. Ok I think I can explain it this time:
laserSegment > 0.0;
laserSegment < 45.0;
if (distance + laserSegment < 13) {
// delete rock
}
Is this not possible? If so I guess I can make
if (distance < 13 && distance + 22.5 < 13 && distance + 45 < 13) {}
Iceman
. Ok I think I can explain it this time:laserSegment > 0.0;
laserSegment < 45.0;
if (distance + laserSegment < 13) {
// delete rock
}
Is this not possible? If so I guess I can make
if (distance < 13 && distance + 22.5 < 13 && distance + 45 < 13) {}
Iceman
By saying if(distance + laserSegment <13), you are taking the distance from the beginning of the laser beam to the rock and adding the length of the laser beam to it and hoping that it somehow will be less than 13. That is impossible. Your other code will not work either because you are just adding to the distance in the same way, not checking the distance from a different point in space.
To check multiple points on a segment, you will first have to find the coordinates of each one in space and get the distance from each point to the rock and test each one with if(distance<13).
To check multiple points on a segment, you will first have to find the coordinates of each one in space and get the distance from each point to the rock and test each one with if(distance<13).
Code:
// Test distance from beginning of laser beam to rock
// Test intermediate points (number of points to test determined by width of rock)
...
...
// Test distance from end of laser beam to rock
// The values in the conditional statement depend on how many points you tested. Here is a sample for three points (not enough for your case).
if(distanceFromBeginning<13 || distanceFromMiddle || distanceFromEnd<13)
{
// Delete rock
}
Oooh that was the problem all along! I just actually tried (for the first time) the "distance + 45 < 13" by its self and it didn't detect a collision. Ok sorry for my totally wacky math.
Iceman
Iceman
I know how that goes. I remember one time when I was learning Java I was getting a bit crazy with it. This was before I knew C too. I assigned x to 0, then I put if(x){...}. It took me a few hours to finally figure out what was going on.
ylaporte's way would work too, BTW. In fact, his way is what I would use because it makes the code easier to understand. It seems that you already have it worked out the other way though. It probably wouldn't be worth changing it now.
ylaporte's way would work too, BTW. In fact, his way is what I would use because it makes the code easier to understand. It seems that you already have it worked out the other way though. It probably wouldn't be worth changing it now.
I would suggest doing a raytrace. It's not "that" slow and works like a charm. You do however need to modify your code to handle "LaserDistanceTraveled" insted of LaserPos (If you do not want "real" lasers that hits instantly).
To test if the laser hits an enemy:
Also if you check over mutiple frames (e.g ship moves after shooting slow laser), you need to save the original ship position and direction.
Cheers
.johan
edit: If you don't get the math check out: http://www.magic-software.com/Documentat...n2Cir2.pdf
To test if the laser hits an enemy:
Code:
struct vec2{float x,y;};
// float testLaserHit(...)
// Returns the distance to the hit point. If returned value is negative there is no hit.
// ( note: ShipDirection needs to be normalized. )
float testLaserHit( vec2 ShipPosition, vec2 ShipDirection,
vec2 EnemyPosition, float EnemyRadius ) {
float b = ShipDirection.x * (ShipPosition.x - EnemyPosition.x) +
ShipDirection.y * (ShipPosition.y - EnemyPosition.y);
float c = (ShipPosition.x - EnemyPosition.x) * (ShipPosition.x - EnemyPosition.x) +
(ShipPosition.y - EnemyPosition.y) * (ShipPosition.y - EnemyPosition.y) -
(EnemyRadius*EnemyRadius);
float d = b * b - c;
if (d < 0.0f) return -1.0f;
return -b - sqrtf(d);
}Also if you check over mutiple frames (e.g ship moves after shooting slow laser), you need to save the original ship position and direction.
Cheers
.johan
edit: If you don't get the math check out: http://www.magic-software.com/Documentat...n2Cir2.pdf
Ok I have one last problem and my collision should work. here's the code:
distance1b = sqrt(((bullet[j].x - rockx1[k])*(bullet[j].x - rockx1[k])) +
(((bullet[j].y - 45) - rocky1[k])*((bullet[j].y -45) - rocky1[k])));
if (distance1b < 13) {
// delete rock
}
glPushMatrix();
glRotatef(angle, 0.0, 0.0, 1.0);
glTranslatef( xtrans, ytrans, -14.9); // ground movement
glTranslatef( bullet[j].x, bullet[j].y, bullet[j].z);
glRotatef(angle, 0.0, 0.0,-1.0);
[self laser];
glPopMatrix();
As you may notice the bullet[j].y -45 does not rotate with [self laser] so when you rotate the ground bullet[j].y -45 is to the left or right of the actual laser (instead of being behind it). What kind of formula do I need to calculate bullet[j].x and bullet[j].y as always being -45 behind the space ship?
Iceman
P.S. The reason I'm moving the ground is because I'm using a nanosaur type camera view.
distance1b = sqrt(((bullet[j].x - rockx1[k])*(bullet[j].x - rockx1[k])) +
(((bullet[j].y - 45) - rocky1[k])*((bullet[j].y -45) - rocky1[k])));
if (distance1b < 13) {
// delete rock
}
glPushMatrix();
glRotatef(angle, 0.0, 0.0, 1.0);
glTranslatef( xtrans, ytrans, -14.9); // ground movement
glTranslatef( bullet[j].x, bullet[j].y, bullet[j].z);
glRotatef(angle, 0.0, 0.0,-1.0);
[self laser];
glPopMatrix();
As you may notice the bullet[j].y -45 does not rotate with [self laser] so when you rotate the ground bullet[j].y -45 is to the left or right of the actual laser (instead of being behind it). What kind of formula do I need to calculate bullet[j].x and bullet[j].y as always being -45 behind the space ship?
Iceman
P.S. The reason I'm moving the ground is because I'm using a nanosaur type camera view.
Short answer:
http://chortle.ccsu.ctstateu.edu/vectorL...Index.html
Long answer:
I don't have one. I need to learn some of this stuff myself.
http://chortle.ccsu.ctstateu.edu/vectorL...Index.html
Long answer:
I don't have one. I need to learn some of this stuff myself.
Aw man. I don't think that even really answers you question at all. I just looked at my bookmarks and thought that looked right, but now that I looked at the actual site, all it does is show some matrix math without saying how to use it.
I'll just say that you need matrices to do the rotation.
I'll just say that you need matrices to do the rotation.

