fix perfectly straight line bugs

This commit is contained in:
Baipyrus 2022-06-17 16:23:33 +02:00
parent bdb4bff01a
commit 33a9f46bb9
2 changed files with 52 additions and 73 deletions

View File

@ -1,79 +1,41 @@
PVector intersect(PVector A, PVector B, PVector C, PVector D) {
// This returns the Intersection Point between lines AB and CD
// ONLY IF said point lies within the two segmented lines.
final float dx1 = B.x - A.x;
final float dx2 = D.x - C.x;
if ((dx1 == 0) || (dx2 == 0)) {
return null;
}
final float M1 = (B.y-A.y)/dx1;
final float M2 = (D.y-C.y)/dx2;
final float dm = M1 - M2;
if (dm == 0) {
return null;
}
final float B1 = A.y - M1 * A.x;
final float B2 = C.y - M2 * C.x;
if (M1 == M2 && B1 == B2) {
return null;
}
final float tx = (B2-B1)/dm;
final PVector common = new PVector(tx, M2 * tx + B2);
final PVector midpointA = B.copy();
midpointA.sub(A).div(2).add(A);
if (PVector.dist(midpointA, common) > PVector.dist(A, B) / 2) {
return null;
}
PVector midpointB = D.copy();
midpointB.sub(C).div(2).add(C);
if (PVector.dist(midpointB, common) > PVector.dist(C, D) / 2) {
return null;
}
return common;
final float d = ((A.x-B.x)*(C.y-D.y)-(A.y-B.y)*(C.x-D.x));
final float t = ((A.x-C.x)*(C.y-D.y)-(A.y-C.y)*(C.x-D.x))/d;
final float u = ((A.x-C.x)*(A.y-B.y)-(A.y-C.y)*(A.x-B.x))/d;
PVector output = null;
if (0 <= t && t <= 1 && 0 <= u && u <= 1)
output = new PVector(A.x+t*(B.x-A.x), A.y+t*(B.y-A.y));
return output;
}
boolean reflect(Projectile p, Wall w) {
// Position -> Next : A -> B
// Wall.start -> Wall.end : C -> D
PVector A = p.position.copy();
PVector B = p.next.copy();
final PVector A = p.position.copy();
final PVector B = p.next.copy();
final PVector C = w.start.copy();
final PVector D = w.end.copy();
final PVector I = intersect(A, B, C, D);
if (I != null && C.y - D.y != 0) {
// Calculating the Mathematical Function for the line CD
final double m_2 = (C.y - D.y) / (C.x - D.x); // -0???
final double b_2 = C.y - m_2 * C.x; // 100???
if (I != null) {
// Calculating E, which is reflecting Point B across line CD
final float dx = D.x - C.x;
final float dy = D.y - C.y;
final float at = (dx * dx - dy * dy) / (dx * dx + dy*dy);
final float bt = 2 * dx * dy / (dx*dx + dy*dy);
PVector E = new PVector(
at * (B.x - C.x) + bt*(B.y - C.y) + C.x,
bt * (B.x - C.x) - at*(B.y - C.y) + C.y
);
// Calculating the Mathematical Function for the line BE
final double m_0 = (-1) / m_2; // INFINITY???
final double b_0 = B.y - m_0 * B.x; // -INFINITY???
if (m_0 - m_2 != 0) {
// Calculating the Midpoint between B and soon-to-be E
// This would also work using scalar projection:
// https://www.youtube.com/watch?v=DHPfoqiE4yQ
final double mx = (b_2 - b_0) / (m_0 - m_2);
final PVector M = new PVector((float)mx, (float)(m_0 * mx + b_0));
// Calculating E, which is reflecting Point B across line CD
PVector E = PVector.sub(PVector.mult(M, 2), B);
// Calculate E, such that Lines AI and IE are of the same length
E.sub(I).setMag(PVector.dist(I, A)).add(I);
p.next = E.copy();
PVector newVelocity = PVector.sub(E, I);
newVelocity.setMag(p.velocity.mag());
p.velocity = newVelocity.copy();
return true;
}
// Calculate E, such that Lines AI and IE are of the same length
E.sub(I).setMag(PVector.dist(I, A)).add(I);
p.next = E.copy();
PVector newVelocity = PVector.sub(E, I);
newVelocity.setMag(p.velocity.mag());
p.velocity = newVelocity.copy();
return true;
}
return false;

View File

@ -23,21 +23,38 @@ void setup() {
userPosition = new PVector(width/2, height/2);
userVelocity = new PVector(0, 0);
// walls.add(new Wall(
// new PVector(width/2, 0),
// new PVector(width, height/2)
// ));
// walls.add(new Wall(
// new PVector(width, height/2),
// new PVector(width/2, height)
// ));
// walls.add(new Wall(
// new PVector(width/2, height),
// new PVector(0, height/2)
// ));
// walls.add(new Wall(
// new PVector(0, height/2),
// new PVector(width/2, 0)
// ));
walls.add(new Wall(
new PVector(width/2, 0),
new PVector(width, height/2)
new PVector(100, 100),
new PVector(width-100, 100)
));
walls.add(new Wall(
new PVector(width, height/2),
new PVector(width/2, height)
new PVector(width-100, 100),
new PVector(width-100, height-100)
));
walls.add(new Wall(
new PVector(width/2, height),
new PVector(0, height/2)
new PVector(width-100, height-100),
new PVector(100, height-100)
));
walls.add(new Wall(
new PVector(0, height/2),
new PVector(width/2, 0)
new PVector(100, height-100),
new PVector(100, 100)
));
}