沿垂直方向的反射矢量
在 SO 社区的大力帮助下,我创建了一个程序,其中一个球处于具有特定位置和速度的三角形中。使用参数方程,我确定了球将击中三角形的位置。然后,我找到了球将击中的三角形边的垂直线,这样我就可以将球反射到墙上,以绘制其“弹跳”轨迹。我的目标是能够绘制出 n 次迭代中球如何从墙壁上弹起的图。但我遇到了一个问题。
尽管我使用 p5.js A.reflect(B)
方法沿垂直方向反射球,但它会产生一些真正奇怪的结果。 我尝试了很多事情(即修改getPerp()
函数、单元测试等),但没有成功。任何帮助将不胜感激。 MWE 下面和 Codepen 中。
let angle = 0;
let sides = [];
let vertices = [];
const len = 100;
function setup() {
createCanvas(windowWidth, windowHeight);
angleMode(DEGREES);
angleOne = createSlider(0, 89, 60);
angleOne.position(10, 10);
angleOne.style("width", "80px");
angleTwo = createSlider(0, 89, 60);
angleTwo.position(10, 30);
angleTwo.style("width", "80px");
rotateVel = createSlider(0, 360, 60);
rotateVel.position(10, 50);
rotateVel.style("width", "80px");
// Initial vertice & side setup (these don't change)
let v1 = createVector(width / 2 - len / 2, height / 2);
let v2 = createVector(width / 2 + len / 2, height / 2);
sides[0] = new Side(v1.x, v1.y, v2.x, v2.y, "green");
vertices[0] = new Vertex(v1.x, v1.y);
vertices[1] = new Vertex(v2.x, v2.y);
}
function draw() {
background(255);
let angOne = angleOne.value();
let angTwo = angleTwo.value();
let rotVel = rotateVel.value();
fill(0);
strokeWeight(0);
textSize(15);
text(angOne, 100, 25);
text(angTwo, 100, 45);
text(rotVel, 100, 65);
let v2Offset = createVector(len * cos(-angOne), len * sin(-angOne));
let v3Offset = createVector(-len * cos(angTwo), -len * sin(angTwo));
vertices[2] = new Vertex(
vertices[0].a.x + v2Offset.x,
vertices[0].a.y + v2Offset.y
);
vertices[3] = new Vertex(
vertices[1].a.x + v3Offset.x,
vertices[1].a.y + v3Offset.y
);
// Update the sides
sides[1] = new Side(
vertices[0].a.x,
vertices[0].a.y,
vertices[2].a.x,
vertices[2].a.y
);
sides[3] = new Side(
vertices[1].a.x,
vertices[1].a.y,
vertices[3].a.x,
vertices[3].a.y
);
const m1 =
(vertices[2].a.y - vertices[0].a.y) / (vertices[2].a.x - vertices[0].a.x);
const m2 =
(vertices[3].a.y - vertices[1].a.y) / (vertices[3].a.x - vertices[1].a.x);
// Calculate the y-offset relative to vertices[0]
const b2 = (vertices[1].a.x - vertices[0].a.x) * -m2;
const xInt = b2 / (m1 - m2);
const yInt = xInt * m1;
// Note xInt and yInt are relative to vertices[0]
// draw all the things
// sides.forEach((s) => s.show());
// stroke(0, 255, 0);
// strokeWeight(20);
point(vertices[0].a.x + xInt, vertices[0].a.y + yInt);
vertices[4] = new Vertex(vertices[0].a.x + xInt, vertices[0].a.y + yInt);
sides[4] = new Side(
vertices[1].a.x,
vertices[1].a.y,
vertices[0].a.x + xInt,
vertices[0].a.y + yInt,
"blue"
);
sides[5] = new Side(
vertices[0].a.x,
vertices[0].a.y,
vertices[0].a.x + xInt,
vertices[0].a.y + yInt,
"purple"
);
scale(4); // so I can make the triangle actually *visible*
translate(-width / 3, -height / 3);
sides[0].show();
sides[4].show();
sides[5].show();
vertices[0].show();
vertices[1].show();
vertices[4].show();
strokeWeight(1);
stroke(255, 0, 0);
noFill();
arc(vertices[0].a.x, vertices[0].a.y, 40, 40, -1 * angleOne.value(), 0, PIE);
arc(
vertices[1].a.x,
vertices[1].a.y,
40,
40,
-180,
-(180 - angleTwo.value()),
PIE
);
stroke(0);
// stroke("purple"); // Change the color
strokeWeight(5); // Make the points 10 pixels in size
let P1x = vertices[0].a.x;
let P1y = vertices[0].a.y;
let P0 = createVector(P1x + 60, P1y - 40);
push();
let V0 = createVector(10 * cos(rotVel), 10 * sin(-rotVel));
pop();
point(P0.x, P0.y);
// point(P0.x + V0.x, P0.y + V0.y);
strokeWeight(2);
line(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
let hit = wallHit(P0, V0);
// print("hit[0] is", hit[0]);
hitPoint = createVector(P0.x + V0.x * hit[0], P0.y + V0.y * hit[0]);
let A = createVector(
vertices[4].a.x - vertices[1].a.x,
vertices[4].a.y - vertices[1].a.y
);
// let B = p5.Vector.sub(vertices[1].a, vertices[2].a);
// let C = p5.Vector.sub(vertices[2].a, vertices[4].a);
// findNormal(hitPoint, A);
setLineDash([5, 5]);
stroke(0);
// let perpA = getY(vertices[1].a.x - 100, hitPoint);
// let normalA = createVector(vertices[1].a.x - 100, perpA);
// let incVec = createVector(hitPoint.x, hitPoint.y);
// let refVec = normalA.reflect(incVec);
let IOne = createVector(0, 0);
let ITwo = createVector(0, 0);
let IThree = createVector(0, 0);
// line(hitPoint.x, hitPoint.y, normalA.x, normalA.y);
let AOne = createVector(P1x, P1y);
let ATwo = createVector(vertices[1].a.x, vertices[1].a.y + 0.1);
let AThree = createVector(
(P1x + vertices[1].a.x) / 2,
(P1y + vertices[1].a.y) / 2
);
// getPerp(AOne, ATwo, hitPoint);
let BOne = createVector(P1x, P1y);
let BTwo = createVector(vertices[4].a.x, vertices[4].a.y + 0.1);
let BThree = createVector(
(P1x + vertices[4].a.x) / 2,
(P1y + vertices[4].a.y) / 2
);
// getPerp(BOne, BTwo, hitPoint);
let COne = createVector(vertices[1].a.x, vertices[1].a.y);
let CTwo = createVector(vertices[4].a.x, vertices[4].a.y + 0.1);
let CThree = createVector(
(vertices[1].a.x + vertices[4].a.x) / 2,
(vertices[1].a.y + vertices[4].a.y) / 2
);
// getPerp(COne, CTwo, hitPoint);
let incVec = createVector(hitPoint.x, hitPoint.y);
line(P0.x, P0.y, incVec.x, incVec.y);
let perp = getPerp(IOne, ITwo, IThree);
let testOne = createVector(vertices[0].a.x + 20, vertices[0].a.y + 20);
let testTwo = createVector(vertices[1].a.x + 20, vertices[1].a.y + 20);
let refVec = testOne.reflect(testTwo);
// line(testOne.x, testOne.y, testTwo.x, testTwo.y);
if (hit[1] == "t3") {
perp = getPerp(AOne, ATwo, hitPoint);
refVec = perp.reflect(incVec);
} else if (hit[1] == "t1") {
perp = getPerp(BOne, BTwo, hitPoint);
refVec = perp.reflect(incVec);
} else {
perp = getPerp(COne, CTwo, hitPoint);
refVec = perp.reflect(incVec);
}
stroke("black");
line(hitPoint.x, hitPoint.y, refVec.x, refVec.y);
setLineDash([0, 0]);
}
function setLineDash(list) {
drawingContext.setLineDash(list);
}
class Side {
constructor(x1, y1, x2, y2, col = "black") {
this.a = createVector(x1, y1);
this.b = createVector(x2, y2);
this.color = col;
}
show() {
stroke(this.color);
strokeWeight(4);
line(this.a.x, this.a.y, this.b.x, this.b.y);
}
}
class Vertex {
constructor(x1, y1) {
this.a = createVector(x1, y1);
}
show() {
stroke(255, 0, 0);
strokeWeight(10);
point(this.a.x, this.a.y);
}
}
function wallHit(pos, vel) {
let P1x = vertices[0].a.x;
let P1y = vertices[0].a.y;
let P2x = vertices[1].a.x;
let P2y = vertices[1].a.y;
let P3x = vertices[4].a.x;
let P3y = vertices[4].a.y;
let A1 = P3y - P1y;
let B1 = -(P3x - P1x);
let C1 = A1 * P1x + B1 * P1y;
let A2 = -(P3y - P2y);
let B2 = P3x - P2x;
let C2 = A2 * P2x + B2 * P2y;
let A3 = -(P2y - P1y);
let B3 = P2x - P1x;
let C3 = A3 * P2x + B3 * P2y;
let t1 = (C1 - A1 * pos.x - B1 * pos.y) / (A1 * vel.x + B1 * vel.y);
let t2 = (C2 - A2 * pos.x - B2 * pos.y) / (A2 * vel.x + B2 * vel.y);
let t3 = (C3 - A3 * pos.x - B3 * pos.y) / (A3 * vel.x + B3 * vel.y);
let times = [t1, t2, t3];
let posTimes = [];
for (let i = 0; i < times.length; i++) {
times[i] = round(times[i], 2);
}
// console.log("After rounding:", times);
for (let i = 0; i < times.length; i++) {
if (times[i] > 0) {
posTimes.push(times[i]);
}
}
let hitPoint = createVector(0, 1);
// console.log("posTimes:", posTimes);
trueTime = min(posTimes);
if (trueTime == round(t1, 2)) {
// print("Hit Purple");
return [t1, "t1"];
// hitPoint = createVector(P0.x + V0.x * t1, P0.y + V0.y * t1);
// line(P0.x, P0.y, hitPoint.x, hitPoint.y);
} else if (trueTime == round(t2, 2)) {
// print("Hit Blue");
return [t2, "t2"];
// hitPoint = createVector(P0.x + V0.x * t2, P0.y + V0.y * t2);
// line(P0.x, P0.y, hitPoint.x, hitPoint.y);
} else {
// print("Hit Green");
return [t3, "t3"];
// hitPoint = createVector(P0.x + V0.x * t3, P0.y + V0.y * t3);
// line(P0.x, P0.y, hitPoint.x, hitPoint.y);
}
}
function findNormal(pos, wall) {
let perpVector = createVector(-wall.y, wall.x);
strokeWeight(2);
stroke(0);
line(pos.x, pos.y, perpVector.x, perpVector.y);
// line(P0.x, P0.y, hitPoint.x, hitPoint.y);
}
function getY(x, HP) {
let perpY =
-((vertices[4].a.x - vertices[1].a.x) / (vertices[4].a.y - vertices[1].a.y)) *
x +
(HP.y +
((vertices[4].a.x - vertices[1].a.x) / (vertices[4].a.y - vertices[1].a.y)) *
HP.x);
return perpY;
}
function getPerp(p1, p2, p3) {
x1 = p1.x;
y1 = p1.y;
x2 = p2.x;
y2 = p2.y;
x3 = p3.x;
y3 = p3.y;
stroke(0);
strokeWeight(2);
line1 = line(x1, y1, x2, y2);
m1 = (y2 - y1) / (x2 - x1);
m2 = -1 / m1;
b2 = y3 - x3 * m2;
stroke(255, 0, 0);
line(x3, m2 * x3 + b2, x1, m2 * x1 + b2);
let final = createVector(m2 * x1 + b2 - (m2 * x3 + b2), x1 - x3);
return final;
}
html,
body {
margin: 0;
padding: 0;
overflow: hidden;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.min.js"></script>
With much help from the SO community, I've created a program where a ball is in a triangle with a certain position and velocity. Using parametric equations, I've determined where the ball will hit the triangle. I then found the perpendicular to the side of the triangle where the ball would hit, so that I could reflect the ball off the wall, to plot its "bounce" trajectory. My goal is that I can plot how the ball will bounce off the walls for n iterations. But I've come up against a problem.
Even though I'm using the p5.js A.reflect(B)
method to reflect the ball along the perpendicular, it's producing some truly strange results.
I've tried many things (i.e., modifying the getPerp()
function, unit testing, etc.), but to no avail. Any help would be greatly appreciated. MWE below and in Codepen.
let angle = 0;
let sides = [];
let vertices = [];
const len = 100;
function setup() {
createCanvas(windowWidth, windowHeight);
angleMode(DEGREES);
angleOne = createSlider(0, 89, 60);
angleOne.position(10, 10);
angleOne.style("width", "80px");
angleTwo = createSlider(0, 89, 60);
angleTwo.position(10, 30);
angleTwo.style("width", "80px");
rotateVel = createSlider(0, 360, 60);
rotateVel.position(10, 50);
rotateVel.style("width", "80px");
// Initial vertice & side setup (these don't change)
let v1 = createVector(width / 2 - len / 2, height / 2);
let v2 = createVector(width / 2 + len / 2, height / 2);
sides[0] = new Side(v1.x, v1.y, v2.x, v2.y, "green");
vertices[0] = new Vertex(v1.x, v1.y);
vertices[1] = new Vertex(v2.x, v2.y);
}
function draw() {
background(255);
let angOne = angleOne.value();
let angTwo = angleTwo.value();
let rotVel = rotateVel.value();
fill(0);
strokeWeight(0);
textSize(15);
text(angOne, 100, 25);
text(angTwo, 100, 45);
text(rotVel, 100, 65);
let v2Offset = createVector(len * cos(-angOne), len * sin(-angOne));
let v3Offset = createVector(-len * cos(angTwo), -len * sin(angTwo));
vertices[2] = new Vertex(
vertices[0].a.x + v2Offset.x,
vertices[0].a.y + v2Offset.y
);
vertices[3] = new Vertex(
vertices[1].a.x + v3Offset.x,
vertices[1].a.y + v3Offset.y
);
// Update the sides
sides[1] = new Side(
vertices[0].a.x,
vertices[0].a.y,
vertices[2].a.x,
vertices[2].a.y
);
sides[3] = new Side(
vertices[1].a.x,
vertices[1].a.y,
vertices[3].a.x,
vertices[3].a.y
);
const m1 =
(vertices[2].a.y - vertices[0].a.y) / (vertices[2].a.x - vertices[0].a.x);
const m2 =
(vertices[3].a.y - vertices[1].a.y) / (vertices[3].a.x - vertices[1].a.x);
// Calculate the y-offset relative to vertices[0]
const b2 = (vertices[1].a.x - vertices[0].a.x) * -m2;
const xInt = b2 / (m1 - m2);
const yInt = xInt * m1;
// Note xInt and yInt are relative to vertices[0]
// draw all the things
// sides.forEach((s) => s.show());
// stroke(0, 255, 0);
// strokeWeight(20);
point(vertices[0].a.x + xInt, vertices[0].a.y + yInt);
vertices[4] = new Vertex(vertices[0].a.x + xInt, vertices[0].a.y + yInt);
sides[4] = new Side(
vertices[1].a.x,
vertices[1].a.y,
vertices[0].a.x + xInt,
vertices[0].a.y + yInt,
"blue"
);
sides[5] = new Side(
vertices[0].a.x,
vertices[0].a.y,
vertices[0].a.x + xInt,
vertices[0].a.y + yInt,
"purple"
);
scale(4); // so I can make the triangle actually *visible*
translate(-width / 3, -height / 3);
sides[0].show();
sides[4].show();
sides[5].show();
vertices[0].show();
vertices[1].show();
vertices[4].show();
strokeWeight(1);
stroke(255, 0, 0);
noFill();
arc(vertices[0].a.x, vertices[0].a.y, 40, 40, -1 * angleOne.value(), 0, PIE);
arc(
vertices[1].a.x,
vertices[1].a.y,
40,
40,
-180,
-(180 - angleTwo.value()),
PIE
);
stroke(0);
// stroke("purple"); // Change the color
strokeWeight(5); // Make the points 10 pixels in size
let P1x = vertices[0].a.x;
let P1y = vertices[0].a.y;
let P0 = createVector(P1x + 60, P1y - 40);
push();
let V0 = createVector(10 * cos(rotVel), 10 * sin(-rotVel));
pop();
point(P0.x, P0.y);
// point(P0.x + V0.x, P0.y + V0.y);
strokeWeight(2);
line(P0.x, P0.y, P0.x + V0.x, P0.y + V0.y);
let hit = wallHit(P0, V0);
// print("hit[0] is", hit[0]);
hitPoint = createVector(P0.x + V0.x * hit[0], P0.y + V0.y * hit[0]);
let A = createVector(
vertices[4].a.x - vertices[1].a.x,
vertices[4].a.y - vertices[1].a.y
);
// let B = p5.Vector.sub(vertices[1].a, vertices[2].a);
// let C = p5.Vector.sub(vertices[2].a, vertices[4].a);
// findNormal(hitPoint, A);
setLineDash([5, 5]);
stroke(0);
// let perpA = getY(vertices[1].a.x - 100, hitPoint);
// let normalA = createVector(vertices[1].a.x - 100, perpA);
// let incVec = createVector(hitPoint.x, hitPoint.y);
// let refVec = normalA.reflect(incVec);
let IOne = createVector(0, 0);
let ITwo = createVector(0, 0);
let IThree = createVector(0, 0);
// line(hitPoint.x, hitPoint.y, normalA.x, normalA.y);
let AOne = createVector(P1x, P1y);
let ATwo = createVector(vertices[1].a.x, vertices[1].a.y + 0.1);
let AThree = createVector(
(P1x + vertices[1].a.x) / 2,
(P1y + vertices[1].a.y) / 2
);
// getPerp(AOne, ATwo, hitPoint);
let BOne = createVector(P1x, P1y);
let BTwo = createVector(vertices[4].a.x, vertices[4].a.y + 0.1);
let BThree = createVector(
(P1x + vertices[4].a.x) / 2,
(P1y + vertices[4].a.y) / 2
);
// getPerp(BOne, BTwo, hitPoint);
let COne = createVector(vertices[1].a.x, vertices[1].a.y);
let CTwo = createVector(vertices[4].a.x, vertices[4].a.y + 0.1);
let CThree = createVector(
(vertices[1].a.x + vertices[4].a.x) / 2,
(vertices[1].a.y + vertices[4].a.y) / 2
);
// getPerp(COne, CTwo, hitPoint);
let incVec = createVector(hitPoint.x, hitPoint.y);
line(P0.x, P0.y, incVec.x, incVec.y);
let perp = getPerp(IOne, ITwo, IThree);
let testOne = createVector(vertices[0].a.x + 20, vertices[0].a.y + 20);
let testTwo = createVector(vertices[1].a.x + 20, vertices[1].a.y + 20);
let refVec = testOne.reflect(testTwo);
// line(testOne.x, testOne.y, testTwo.x, testTwo.y);
if (hit[1] == "t3") {
perp = getPerp(AOne, ATwo, hitPoint);
refVec = perp.reflect(incVec);
} else if (hit[1] == "t1") {
perp = getPerp(BOne, BTwo, hitPoint);
refVec = perp.reflect(incVec);
} else {
perp = getPerp(COne, CTwo, hitPoint);
refVec = perp.reflect(incVec);
}
stroke("black");
line(hitPoint.x, hitPoint.y, refVec.x, refVec.y);
setLineDash([0, 0]);
}
function setLineDash(list) {
drawingContext.setLineDash(list);
}
class Side {
constructor(x1, y1, x2, y2, col = "black") {
this.a = createVector(x1, y1);
this.b = createVector(x2, y2);
this.color = col;
}
show() {
stroke(this.color);
strokeWeight(4);
line(this.a.x, this.a.y, this.b.x, this.b.y);
}
}
class Vertex {
constructor(x1, y1) {
this.a = createVector(x1, y1);
}
show() {
stroke(255, 0, 0);
strokeWeight(10);
point(this.a.x, this.a.y);
}
}
function wallHit(pos, vel) {
let P1x = vertices[0].a.x;
let P1y = vertices[0].a.y;
let P2x = vertices[1].a.x;
let P2y = vertices[1].a.y;
let P3x = vertices[4].a.x;
let P3y = vertices[4].a.y;
let A1 = P3y - P1y;
let B1 = -(P3x - P1x);
let C1 = A1 * P1x + B1 * P1y;
let A2 = -(P3y - P2y);
let B2 = P3x - P2x;
let C2 = A2 * P2x + B2 * P2y;
let A3 = -(P2y - P1y);
let B3 = P2x - P1x;
let C3 = A3 * P2x + B3 * P2y;
let t1 = (C1 - A1 * pos.x - B1 * pos.y) / (A1 * vel.x + B1 * vel.y);
let t2 = (C2 - A2 * pos.x - B2 * pos.y) / (A2 * vel.x + B2 * vel.y);
let t3 = (C3 - A3 * pos.x - B3 * pos.y) / (A3 * vel.x + B3 * vel.y);
let times = [t1, t2, t3];
let posTimes = [];
for (let i = 0; i < times.length; i++) {
times[i] = round(times[i], 2);
}
// console.log("After rounding:", times);
for (let i = 0; i < times.length; i++) {
if (times[i] > 0) {
posTimes.push(times[i]);
}
}
let hitPoint = createVector(0, 1);
// console.log("posTimes:", posTimes);
trueTime = min(posTimes);
if (trueTime == round(t1, 2)) {
// print("Hit Purple");
return [t1, "t1"];
// hitPoint = createVector(P0.x + V0.x * t1, P0.y + V0.y * t1);
// line(P0.x, P0.y, hitPoint.x, hitPoint.y);
} else if (trueTime == round(t2, 2)) {
// print("Hit Blue");
return [t2, "t2"];
// hitPoint = createVector(P0.x + V0.x * t2, P0.y + V0.y * t2);
// line(P0.x, P0.y, hitPoint.x, hitPoint.y);
} else {
// print("Hit Green");
return [t3, "t3"];
// hitPoint = createVector(P0.x + V0.x * t3, P0.y + V0.y * t3);
// line(P0.x, P0.y, hitPoint.x, hitPoint.y);
}
}
function findNormal(pos, wall) {
let perpVector = createVector(-wall.y, wall.x);
strokeWeight(2);
stroke(0);
line(pos.x, pos.y, perpVector.x, perpVector.y);
// line(P0.x, P0.y, hitPoint.x, hitPoint.y);
}
function getY(x, HP) {
let perpY =
-((vertices[4].a.x - vertices[1].a.x) / (vertices[4].a.y - vertices[1].a.y)) *
x +
(HP.y +
((vertices[4].a.x - vertices[1].a.x) / (vertices[4].a.y - vertices[1].a.y)) *
HP.x);
return perpY;
}
function getPerp(p1, p2, p3) {
x1 = p1.x;
y1 = p1.y;
x2 = p2.x;
y2 = p2.y;
x3 = p3.x;
y3 = p3.y;
stroke(0);
strokeWeight(2);
line1 = line(x1, y1, x2, y2);
m1 = (y2 - y1) / (x2 - x1);
m2 = -1 / m1;
b2 = y3 - x3 * m2;
stroke(255, 0, 0);
line(x3, m2 * x3 + b2, x1, m2 * x1 + b2);
let final = createVector(m2 * x1 + b2 - (m2 * x3 + b2), x1 - x3);
return final;
}
html,
body {
margin: 0;
padding: 0;
overflow: hidden;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.min.js"></script>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您混淆了向量和点。一个点有 2 个从坐标系原点测量的坐标。向量表示方向,可以通过减去 2 个点来给出。因此,入射向量为:
向量 (Vx, Vy) 的法向量(垂直向量)为:
因此,由 2 个点 (Ax, Ay) 和 (Bx, By) 给出的直线的法向量(垂直)为:
reflect()
函数反映了表面上的入射矢量除以表面的给定法线矢量。函数的参数是法向量:line
在两点之间画一条线。refVec
不是一个点而是一个向量。因此,您需要绘制从hitPoint
到hitPoint + refVec
的直线,而不是从hitPoint
到refVec
的形式。全部在一起:
演示
You are confusing vectors and points. A point has 2 coordinates measured from the origin of the coordinate system. A vector represents a direction and can be given by subtracting 2 points. Therefore, the incident vector is:
The normal vector (perpendicular vector) of a vector (Vx, Vy) is:
Hence the normal vector (perpendicular) to a line given by 2 points (Ax, Ay) and (Bx, By) is:
The
reflect()
function reflects an incidence vector on a surface by a given normal vector of the surface. The argument of the function is the normal vector:line
draws a line between 2 points.refVec
is not a point but a vector. Therefore you need to draw the line fromhitPoint
tohitPoint + refVec
instead of formhitPoint
torefVec
.All together:
Demo