schteppe / p2.js

JavaScript 2D physics library
Other
2.64k stars 330 forks source link

Raycast reflection #159

Closed wojciak closed 9 years ago

wojciak commented 9 years ago

Hello,

I've been struggling for the past few days with drawing the reflection of a rayCastResult. I can easily draw the line from the start to the end. But when I try to use the hitNormalWorld result it gives me weird effects :)

Would it be possible to include a function like reflectRay() to ease the life of our math-handicapped folk? :) (coronasdk has something like that https://docs.coronalabs.com/api/library/physics/reflectRay.html)

Cheers, Lukasz

schteppe commented 9 years ago

Math-handicapped... lol :P

Maybe such method could be added, but I think it's more common to have the method among the vector ops to begin with. Like this:

function reflect(out, vector, normal){
  var dot = vector[0]*normal[0] + vector[1]*normal[1];
  out[0] = vector[0] - 2 * normal[0] * dot;
  out[1] = vector[1] - 2 * normal[1] * dot;
};

var direction = [to[0] - from[0], to[1] - from[1]];
var reflectedVector = [];
reflect(reflectedVector, direction, hitNormalWorld);
wojciak commented 9 years ago

Cool - thx :+1: it doesn't take rotation into account, but this I can do I think ;D

schteppe commented 9 years ago

Had a stab at a ray reflection example, but the first bounce only works sometimes.. Did you get this problem too?

Might be a bug in p2. Will look deeper into it.

schteppe commented 9 years ago

Fixed the bug, added a reflection demo, and added the vec2.reflect method to the lib. https://github.com/schteppe/p2.js/commit/dfe572a7d5e9109808cdff0f4179d5c6a9396caf https://github.com/schteppe/p2.js/commit/ea9b6d53a6cafc3b6faad0556b16307ed27ae277

Also see this Vine ;) https://twitter.com/schteppe/status/611860365505363968

This is the most important part of the demo:

var hits=0;
while(world.raycastClosest(start, end, {}, result) && hits++ < 10){

  // Get ray direction
  result.getDirection(direction);

  // reflect the direction
  p2.vec2.reflect(direction, direction, result.hitNormalWorld);

  // move start to the hit point
  p2.vec2.copy(start, result.hitPointWorld);

  // move out a bit, so we don't get another hit on the same shape
  start[0] += direction[0] * 0.001;
  start[1] += direction[1] * 0.001;

  // get new end point
  end[0] = start[0] + direction[0] * 100;
  end[1] = start[1] + direction[1] * 100;

  result.reset();
}

I hope this is enough to get you started. I've tested the raycasting code a bit more, it should work properly for circles, rectangles and convexes now.

wojciak commented 9 years ago

Wow - awesome work - thx! :)

2015-06-19 13:55 GMT+02:00 Stefan Hedman notifications@github.com:

Fixed the bug, added a reflection demo, and added the vec2.reflect method to the lib. dfe572a https://github.com/schteppe/p2.js/commit/dfe572a7d5e9109808cdff0f4179d5c6a9396caf ea9b6d5 https://github.com/schteppe/p2.js/commit/ea9b6d53a6cafc3b6faad0556b16307ed27ae277

Also see this Vine ;) https://twitter.com/schteppe/status/611860365505363968

This is the most important part of the demo:

var hits=0;while(world.raycastClosest(start, end, {}, result) && hits++ < 10){

// Get ray direction result.getDirection(direction);

// reflect the direction p2.vec2.reflect(direction, direction, result.hitNormalWorld);

// move start to the hit point p2.vec2.copy(start, result.hitPointWorld);

// move out a bit, so we don't get another hit on the same shape start[0] += direction[0] * 0.001; start[1] += direction[1] * 0.001;

// get new end point end[0] = start[0] + direction[0] * 100; end[1] = start[1] + direction[1] * 100;

result.reset(); }

I hope this is enough to get you started. I've tested the raycasting code a bit more, it should work properly for circles, rectangles and convexes now.

— Reply to this email directly or view it on GitHub https://github.com/schteppe/p2.js/issues/159#issuecomment-113488457.