Archived

This topic is now archived and is closed to further replies.

acidburned

Mouse Velocity/Collision

Recommended Posts

acidburned    122
I am currently creating a pool table simulation for a school project. Instead of using a pool stick, the velocity of the cue ball is determined by the movement of the mouse. I would like to know how I am able to convert the dragging motion of a mouse into velocity for the cue ball. I've searched the forums and I can't seem to find an answer. I also have one more problem with the collision detection. Instead of a rectangular pool table, the pool table is an equilateral triangle in shape. The collision detection for a rectangular object is relatively simple but I can't figure out how to determine a collision on an angled wall. Any help you guys can offer me would be greatly appreciated and I appoligize if this question has already been asked...it's my first day. [edited by - acidburned on May 27, 2004 6:17:18 PM]

Share this post


Link to post
Share on other sites
grhodes_at_work    1385
For the velocity, you''ll have to track the mouse position over time, e.g., how many pixels does it move in a tenth of a second? Map the screen space pixel-based velocity into a world space velocity using normal screen-to-world vector mapping and you''re there.

The collision is fairly straightforward. You''ll need to write a routine for computing the intersection of two line segments. One will be an edge of the triangle and the other will be a line segment joining the ball''s starting position to the place where it would end up if it had not wall to block it. Account for friction. If the ball stops due to friction before hitting the wall, then the two line segments won''t intersect. If it doesn''t stop, the two line segments will intersect and you have a collision. Check out the Forum FAQ for a link to an article at Gamasutra that deals with pool table physics. Also, check out Jeff Lander''s physics on the back of a cocktail napkin also at Gamasutra. It also is related and useful. You''ll have to register for Gamasutra, but its free and a good resource.

Graham Rhodes
Principal Scientist
Applied Research Associates, Inc.

Share this post


Link to post
Share on other sites
pTymN    464
#include <math.h>

#define CLOCKWISE -1
#define COUNTER_CLOCKWISE 1
#define LINE 0

typedef struct fpoint_tag
{
float x;
float y;
} fpoint;

fpoint line1_pt1 = {0.0, 3.0};
fpoint line1_pt2 = {0.0, 0.0};
fpoint line2_pt1 = {2.0, 3.0};
fpoint line2_pt2 = {-2.0, 1.0};

int check_tri_clock_dir(fpoint pt1, fpoint pt2, fpoint pt3)
{
float test;
test = (((pt2.x - pt1.x)*(pt3.y - pt1.y)) - ((pt3.x - pt1.x)*(pt2.y - pt1.y)));
if (test > 0) return COUNTER_CLOCKWISE;
else if(test < 0) return CLOCKWISE;
else return LINE;
}

int check_intersect(fpoint l1p1, fpoint l1p2, fpoint l2p1, fpoint l2p2)
{
int test1_a, test1_b, test2_a, test2_b;

test1_a = check_tri_clock_dir(l1p1, l1p2, l2p1);
test1_b = check_tri_clock_dir(l1p1, l1p2, l2p2);
if (test1_a != test1_b)
{
test2_a = check_tri_clock_dir(l2p1, l2p2, l1p1);
test2_b = check_tri_clock_dir(l2p1, l2p2, l1p2);
if (test2_a != test2_b)
{
return 1;
}
}
return 0;
}

I7Position* calculateEdgeNormal(LineSegment* currentEdge) {
static I7Position theNormal;

float p1[3], p2[3], p3[3], result[3];

// get a direction vector for the edge
p1[0] = currentEdge->p1.x - currentEdge->p2.x;
p1[1] = currentEdge->p1.y - currentEdge->p2.y;
p1[2] = 0.0f;

// set shared endpoint for both vectors to 0->
p2[0] = p2[1] = p2[2] = 0.0f;

// set other vector's endpoint to UP
p3[0] = p3[1] = 0.0f;
p3[2] = 1.0f;

CalculateCrossProduct(p1, p2, p3, &result[0]);

theNormal.x = result[0];
theNormal.y = result[1];

return &theNormal;
}

I7Velocity* calculateBounce(I7Position *edgeNormal, I7Velocity *vel) {
static I7Velocity bounce;

// dot product of the edgenormal and velocity / |velocity|^2 * velocity

// dot product
float dotProduct = edgeNormal->x * vel->dx + edgeNormal->y * vel->dy;

// amount of normal that is being projected onto
float amount = dotProduct / (edgeNormal->x*edgeNormal->x + edgeNormal->y*edgeNormal->y);

bounce.dx = -(amount*edgeNormal->x) * 2.0f + vel->dx;
bounce.dy = -(amount*edgeNormal->y) * 2.0f + vel->dy;

return &bounce;
}

void CalculateCrossProduct(float p1[3], float p2[3], float p3[3], float *result) {

// First, the two vectors must be constructed from these points.
// v1 is the vector between p1 and p2, and v2 is the vector between p2 and p3.
// Eventually, a class will be created for the vectors with overloaded operators for
// easy access and manipulation.

float v1[3];
float v2[3];

v1[0] = p1[0] - p2[0];
v1[1] = p1[1] - p2[1];
v1[2] = p1[2] - p2[2];

v2[0] = p2[0] - p3[0];
v2[1] = p2[1] - p3[1];
v2[2] = p2[2] - p3[2];

result[0] = v1[1]*v2[2] - v1[2]*v2[1];
result[1] = v1[2]*v2[0] - v1[0]*v2[2];
result[2] = v1[0]*v2[1] - v1[1]*v2[0];

float normalize = sqrt(result[0] * result[0] + result[1] * result[1] + result[2] * result[2]);

result[0] /= normalize;
result[1] /= normalize;
result[2] /= normalize;
}


If you email or IM me, i can send you the full source, it was a school project last semester. A nice minigolf game...
ICQ: 28292485

[edited by - pTymN on May 27, 2004 11:39:36 PM]

Share this post


Link to post
Share on other sites