Если у вас есть бесконечная линия, которая определяется точкой P
и нормализованным направлением R
, и вторая бесконечная линия, которая определяется точкой Q
и направлением S
, тоТочка пересечения бесконечных линий X
составляет:
alpha ... angle between Q-P and R
beta ... angle between R and S
gamma = 180° - alpha - beta
h = | Q - P | * sin(alpha)
u = h / sin(beta)
t = | Q - P | * sin(gamma) / sin(beta)
t = dot(Q-P, (S.y, -S.x)) / dot(R, (S.y, -S.x)) = determinant(mat2(Q-P, S)) / determinant(mat2(R, S))
u = dot(Q-P, (R.y, -R.x)) / dot(R, (S.y, -S.x)) = determinant(mat2(Q-P, R)) / determinant(mat2(R, S))
X = P + R * t = Q + S * u
Это можно рассчитать с помощью PVector
, следующим образом:
// Intersect 2 endless lines
// line 1: "P" is on endless line, the direction is "dir1" ("R")
// line 2: "Q" is on endless line, the direction is "dir2" ("S")
PVector Intersect( PVector P, PVector dir1, PVector Q, PVector dir2) {
PVector R = dir1.copy();
PVector S = dir2.copy();
R.normalize();
S.normalize();
PVector QP = PVector.sub(Q, P);
PVector SNV = new PVector(S.y, -S.x);
float t = QP.dot(SNV) / R.dot(SNV);
PVector X = PVector.add(P, PVector.mult(R, t));
return X;
}
См. Пример:
void setup() {
size(500,500);
}
void draw() {
background(0, 0, 0);
stroke(255);
fill(255, 0, 0);
PVector l1p1 = new PVector(250, 150);
PVector l1p2 = new PVector(300, 300);
PVector l2p1 = new PVector(200, 180);
PVector l2p2 = new PVector(300, 220);
PVector l3p1 = new PVector(200, 300);
PVector l3p2 = new PVector(250, 280);
line(l1p1.x, l1p1.y, l1p2.x, l1p2.y);
line(l2p1.x, l2p1.y, l2p2.x, l2p2.y);
line(l3p1.x, l3p1.y, l3p2.x, l3p2.y);
PVector dir1 = PVector.sub(l1p2, l1p1);
PVector dir2 = PVector.sub(l2p2, l2p1);
PVector dir3 = PVector.sub(l3p2, l3p1);
PVector x1 = Intersect(l1p1, dir1, l2p1, dir2);
circle(x1.x, x1.y, 10);
PVector x2 = Intersect(l1p1, dir1, l3p1, dir3);
circle(x2.x, x2.y, 10);
PVector x3 = Intersect(l2p1, dir2, l3p1, dir3);
circle(x3.x, x3.y, 10);
}
Обратите внимание, если линии параллельнытогда скаляры возвращаемой точки (PVector
объекта) бесконечны. Это можно оценить по Float.isInfinite
. например:
if (!Float.isInfinite(x1.x) || !Float.isInfinite(x1.y))
circle(x1.x, x1.y, 10);