Jump to content
  • Advertisement
Sign in to follow this  
Kurt-olsson

Back to basic Sliding response in 2D

This topic is 2127 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi!
I have made some simple collision detection and response in 2D.
i have made it like this.

move player
iterate all obstacles
push player out the amout it has penetrated
cut velocity with slide vector for each plane/line

it works with all sorts on angles, i still have to check which line that is closest for better result.
But it seems that when i set the new speed it overbounces on the lines.
If i go slow, i slide along the lines as long as i have push on the speed with my keybord but if i approach a line fast then the sphere bounces away.
i think that something is wrong with my slide vector...

vx -= nx * ((vx * nx) + (vy * ny));
vy -= ny * ((vx * nx) + (vy * ny));

vx = speed x
vy = speed y
nx = normal from spherePos - closestPoint on Lines
ny = normal from spherePos - closestPoint on Lines

i don´t know how the formula for 2D slide. In 3D i use v-= -n * dot(v.n) but how can i do this in 2D?


[source lang="java"]

var moveBall = function () {
pos_x += vx;
pos_y += vy;
//Iterate and find all lines/planes that are to close, then push player out. TODO: sort this and find closest first!
for (var i = 0; i < lines.length; i++) {
var closestpoint = new ClosetPointOnLine(lines.x, lines.y, lines.x2, lines.y2, pos_x, pos_y);
var l = lineLength(pos_x, pos_y, closestpoint.x, closestpoint.y)

ctx.fillText("length: " + l, 150, 60);
if (l < SPHERE_RADIUS) {
pos_x += ((pos_x - closestpoint.x) / l) * (SPHERE_RADIUS - l);
pos_y += ((pos_y - closestpoint.y) / l) * (SPHERE_RADIUS - l);
var nx = (pos_x - closestpoint.x) / l;
var ny = (pos_y - closestpoint.y) / l;
vx -= nx * ((vx * nx) + (vy * ny));
vy -= ny * ((vx * nx) + (vy * ny));

}
}
[/source] Edited by KurtO

Share this post


Link to post
Share on other sites
Advertisement
You should precompute ((vx * nx) + (vy * ny)) for two reasons. Firstly, your code will be faster and secondly (which is also where your bug is), when computing vy -= ny * ((vx * nx) + (vy * ny)), you are using the new value of vx, computed on the previous line!

So, just do this:
[source lang="java"]dot = ((vx * nx) + (vy * ny));
vx -= nx * dot;
vy -= ny * dot;[/source]
Basically, the 2D formula is the same as the 3D formula, but simplified because z = 0.

Share this post


Link to post
Share on other sites
Wow! i am impressed how you can see my bug so clearly! Of course now when i know i have to precompute! Sometimes i am just stupid! =)
And then i have to recalt my sliding vector AFTER i moved my sphere of course.
My little demo is now complete except one detail (of course as always)

The sliding pushes the sphere outside the lines in tight spaces. i think i need to solve time t of impace before movement or do the updates recursive with 6-8 times to solve this problem, but i really dont know how.

thanks again faelnor! Edited by KurtO

Share this post


Link to post
Share on other sites
Yeah, resolving collisions in tight spaces is not an easy problem. You can prevent some of the problems by avoiding acute angles between lines and a having a minimum distance between your lines of at least the diameter of the sphere. You may also pass through walls if your sphere is moving too fast. Good luck!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!