<script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.min.js"></script>
<style>
html,
body {
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
<script>
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");
iterations = createSlider(0, 20, 1);
iterations.position(10, 70);
iterations.style("width", "80px");
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();
let numIter = iterations.value();
fill(0);
strokeWeight(0);
textSize(15);
text(angOne, 100, 25);
text(angTwo, 100, 45);
text(rotVel, 100, 65);
text(numIter, 100, 85);
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);
const b2 = (vertices[1].a.x - vertices[0].a.x) * -m2;
const xInt = b2 / (m1 - m2);
const yInt = xInt * m1;
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(255, 195, 0);
strokeWeight(5);
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);
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
);
stroke(0);
let IOne = createVector(0, 0);
let ITwo = createVector(0, 0);
let IThree = createVector(0, 0);
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
);
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
);
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
);
let inVec = createVector(hitPoint.x - P0.x, hitPoint.y - P0.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);
if (hit[1] == "t3") {
perp = getPerp(AOne, ATwo, hitPoint);
let n = createVector(AOne.y - ATwo.y, ATwo.x - AOne.x);
refVec = inVec.reflect(n);
} else if (hit[1] == "t1") {
perp = getPerp(BOne, BTwo, hitPoint);
let n = createVector(BOne.y - BTwo.y, BTwo.x - BOne.x);
refVec = inVec.reflect(n);
} else {
perp = getPerp(COne, CTwo, hitPoint);
let n = createVector(COne.y - CTwo.y, CTwo.x - COne.x);
refVec = inVec.reflect(n);
}
stroke("black");
line(hitPoint.x, hitPoint.y, hitPoint.x + refVec.x, hitPoint.y + refVec.y);
line(P0.x, P0.y, hitPoint.x, hitPoint.y);
let P0s = [];
let V0s = [];
let hits = [];
let hitPoints = [hitPoint];
let refs = [refVec];
let inVecs = [];
for (let i = 0; i < numIter; i++) {
P0s.push(createVector(hitPoints[i].x, hitPoints[i].y));
V0s.push(createVector(refs[i].x, refs[i].y));
hits.push(wallHit(P0s[i], V0s[i]));
hitPoints.push(createVector(P0s[i].x + V0s[i].x * hits[i][0], P0s[i].y + V0s[i].y * hits[i][0]));
inVecs.push(createVector(hitPoints[i + 1].x - P0s[i].x, hitPoints[i + 1].y - P0s[i].y));
// print(hits[0][1]);
if (hits[i][1] == "t3") {
perp2 = getPerp(AOne, ATwo, hitPoints[i + 1]);
let n2 = createVector(AOne.y - ATwo.y, ATwo.x - AOne.x);
refs.push(inVecs[i].reflect(n2));
} else if (hits[i][1] == "t1") {
perp2 = getPerp(BOne, BTwo, hitPoints[i + 1]);
let n2 = createVector(BOne.y - BTwo.y, BTwo.x - BOne.x);
refs.push(inVecs[i].reflect(n2));
} else {
perp2 = getPerp(COne, CTwo, hitPoints[i + 1]);
let n2 = createVector(COne.y - CTwo.y, CTwo.x - COne.x);
refs.push(inVecs[i].reflect(n2));
}
stroke("black");
// line(hitPoint2.x, hitPoint2.y, hitPoint2.x + refVec2.x, hitPoint2.y + refVec2.y);
// line(hitPoints[i+1].x, hitPoints[i+1].y, hitPoints[i+1].x + refs[i+1].x, hitPoints[i+1].y + refs[i+1].y);
line(P0s[i].x, P0s[i].y, hitPoints[i + 1].x, hitPoints[i + 1].y);
}
//
// let P02 = createVector(hitPoint.x, hitPoint.y);
// let V02 = createVector(refVec.x, refVec.y);
// let hit2 = wallHit(P02, V02);
// hitPoint2 = createVector(P02.x + V02.x * hit2[0], P02.y + V02.y * hit2[0]);
//
// let inVec2 = createVector(hitPoint2.x - P02.x, hitPoint2.y - P02.y);
// print("inVecs[0]:", inVecs[0], "inVec2:", inVec2);
// // print(hitPoints[0].x)
//
// if (hit2[1] == "t3") {
// perp2 = getPerp(AOne, ATwo, hitPoint2);
// let n2 = createVector(AOne.y - ATwo.y, ATwo.x - AOne.x);
// refVec2 = inVec2.reflect(n2);
// } else if (hit2[1] == "t1") {
// perp2 = getPerp(BOne, BTwo, hitPoint2);
// let n2 = createVector(BOne.y - BTwo.y, BTwo.x - BOne.x);
// refVec2 = inVec2.reflect(n2);
// } else {
// perp2 = getPerp(COne, CTwo, hitPoint2);
// let n2 = createVector(COne.y - CTwo.y, CTwo.x - COne.x);
// refVec2 = inVec2.reflect(n2);
// }
//
// stroke("black");
// line(hitPoint2.x, hitPoint2.y, hitPoint2.x + refVec2.x, hitPoint2.y + refVec2.y);
// line(P02.x, P02.y, hitPoint2.x, hitPoint2.y);
}
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;
}
</script>
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.