我已成立了一個不大不小的反射向量模擬器在這裏:https://jsfiddle.net/ahvonenj/1re5n8jg/不工作的反思矢量計算正確
我使用Vectorious我的矢量計算和對象。
我從對鼠標光標的畫布中間鑄造射線。我可以成功檢測與牆壁和牆上交點(紅點)的交點。我也能夠得到牆的中間點(藍點)。我想,當我正常化中點矢量時,這是牆的法線。
這裏是聽鼠標移動,投射射線,得到交點並試圖計算反射向量的部分(我已經添加了關於反射向量的實際計算和我認爲我正在計算的一些註釋) :
Global.$canvas.addEventListener('mousemove', function(e)
{
\t var ctx = Global.ctx;
\t var rect = canvas.getBoundingClientRect();
\t Global.Mouse = new Vector([e.clientX - rect.left, e.clientY - rect.top]);
\t
\t var v1 = Vector.subtract(Global.Mouse, Global.Canvas.Center).normalize();
\t var mag = Vector.subtract(Global.Canvas.Center, Global.Mouse).magnitude();
\t var ray = Vector.scale(v1, mag * 3).add(Global.Canvas.Center);
\t
\t ctx.clearRect(0, 0, 600, 600);
\t ctx.beginPath();
\t
\t for(var i = 0; i < Global.Canvas.Walls.length; i++)
\t {
\t \t var wall = Global.Canvas.Walls[i];
\t \t
\t \t if(rayIntersectsWith(wall, [Global.Canvas.Center, ray]))
\t \t {
\t \t \t // x_1' - x_0 = v - 2(v dot ñ)ñ
\t \t \t // Where ñ = Normal of the wall
\t \t \t // and v = Vector from center to the point of intersection with the wall
\t \t \t // http://mathworld.wolfram.com/Reflection.html
\t \t
\t \t \t // This is the point on wall where the intersection happens
\t \t \t var point = rayIntersectionPoint(wall, [Global.Canvas.Center, ray])
\t \t \t
\t \t \t // This is the full ray cast from center towards the mouse
\t \t \t var d = ray;
\t \t \t
\t \t \t // This (probably) is the vector from center to the intersection point on the wall
\t \t \t var v = Vector.subtract(point, Global.Canvas.Center);
\t \t \t
\t \t \t // This represents the wall vector, or a middle of the wall (blue dot on wall)
\t \t \t var wallVector = Vector.add(wall[0], wall[1]).scale(0.5);
\t \t \t
\t \t \t // This is supposed to be the normal of the wall
\t \t \t var wallNormal = Vector.normalize(wallVector);
\t \t \t
\t \t \t // This is supposed to be the 2(v dot ñ) part of the equation
\t \t \t var v_dot_n = Vector.dot(v, wallNormal) * 2;
\t \t \t
\t \t \t // This is supposed to be the v_dot_n * ñ of the equation
\t \t \t var v_dot_n_scaled_by_n = Vector.scale(wallNormal, v_dot_n);
\t \t \t
\t \t \t // This is supposed to be the v - v_dot_n_scale_by_n part of the equation
\t \t \t var dot_vector = Vector.subtract(v, v_dot_n_scaled_by_n);
\t \t \t
\t \t \t console.log('w1', wall[0].x, wall[0].y, ", w2", wall[1].x, wall[1].y)
\t \t \t
\t \t \t var bounceVector = dot_vector
\t \t \t console.log(wallVector.x, wallVector.y, wallVector.magnitude()) \t \t \t
\t \t \t console.log(wallNormal.x, wallNormal.y, wallNormal.magnitude())
\t \t \t ctx.beginPath();
\t \t \t ctx.arc(wallVector.x, wallVector.y, Global.isecRadius, 0, 2 * Math.PI, false);
\t \t \t ctx.fillStyle = 'blue';
\t \t \t ctx.fill();
\t \t \t ctx.lineWidth = 0;
\t \t \t ctx.strokeStyle = 'blue';
\t \t \t
\t \t \t ctx.beginPath();
\t \t \t ctx.arc(dot_vector.x, dot_vector.y, Global.isecRadius * 1.5, 0, 2 * Math.PI, false);
\t \t \t ctx.fillStyle = 'blue';
\t \t \t ctx.fill();
\t \t \t ctx.lineWidth = 0;
\t \t \t ctx.strokeStyle = 'blue';
\t \t \t ctx.beginPath();
\t \t \t ctx.lineWidth = 3;
\t \t \t ctx.strokeStyle = '#00FF00';
\t \t \t ctx.moveTo(wall[0].x, wall[0].y);
\t \t \t ctx.lineTo(wall[1].x, wall[1].y);
\t \t \t ctx.stroke();
\t \t \t console.log(bounceVector.x, bounceVector.y)
\t \t \t ctx.beginPath();
\t \t \t ctx.arc(bounceVector.x, bounceVector.y, Global.isecRadius, 0, 2 * Math.PI, false);
\t \t \t ctx.fillStyle = 'red';
\t \t \t ctx.fill();
\t \t \t ctx.lineWidth = 0;
\t \t \t ctx.strokeStyle = 'red';
\t \t \t ctx.beginPath();
\t \t \t ctx.lineWidth = 1;
\t \t \t ctx.strokeStyle = '#000000';
\t \t \t ctx.moveTo(point.x, point.y);
\t \t \t ctx.lineTo(bounceVector.x, bounceVector.y);
\t \t \t ctx.stroke();
\t \t \t ctx.beginPath();
\t \t \t ctx.arc(point.x, point.y, Global.isecRadius, 0, 2 * Math.PI, false);
\t \t \t ctx.fillStyle = 'red';
\t \t \t ctx.fill();
\t \t \t ctx.lineWidth = 0;
\t \t \t ctx.strokeStyle = 'red';
\t \t }
\t }
\t
\t ctx.stroke();
\t
\t ctx.beginPath();
\t ctx.lineWidth = 1;
\t ctx.strokeStyle = '#000000';
ctx.moveTo(Global.Canvas.Center.x, Global.Canvas.Center.y);
ctx.lineTo(ray.x, ray.y);
\t ctx.stroke();
});
我的計算是基於這裏找到方程:http://mathworld.wolfram.com/Reflection.html
但是如果你試圖日你會注意到反射計算幾乎不能用於傾斜牆,目前根本不能用於外牆,所以這是我需要幫助的地方。
的計算公式如下:
x_1'- x_0 = v - 2(v·ñ)ñ.
凡x_1' - X_0是從牆上的交點反射向量到以往任何時候都應該指向。 v可能與v的相同長度
v是從x_1到牆的交點的向量,所以在我的代碼中它被命名爲v並從中心到牆相交。
ñ是牆的正常。
其餘的方程也應該在我的代碼和我希望相應命名的變量中註釋。
我對這個等式中從v減去的東西有點困惑。 v dot - 返回一個標量,然後乘以2.但是 - 是一個向量,所以2(v dot - )必須意味着標量向量ñ由標量值2(v dotñ)?
最佳猜測我已經能夠從調試這個事情得出結論,牆壁正常是最有可能注意正確計算。
*「我認爲,當我正常化中點矢量時,這是牆的法線。」*不,它不是。我知道矢量,但我不知道JavaScript;如果你能告訴我如何旋轉一個向量90度,或者使用X和Y分量構造一個向量,我可以給你構造法線的代碼。 – Beta