已知兩點 P1(320, 0), P2(200, 50),畫布大小 640×260。求直線 P1P2 延長後與畫布邊界的交點座標。
k = (50 - 0) / (200 - 320) = 50 / (-120) = -5/12b = y1 - k*x1 = 0 - (-5/12)*320 = 400/3 ≈ 133.33y = -5/12 x + 400/3
x=0 → y = 400/3 ≈ 133.33(在 0~260 內,有效)x=640 → y = -5/12*640 + 400/3 = -800/3 + 400/3 = -400/3 ≈ -133.33(超出下邊界,無效)y=0 → 0 = -5/12 x + 400/3 → x = 320(即 P1,有效)y=260 → 260 = -5/12 x + 400/3 → x = (400/3 - 260) * (-12/5) = (-380/3) * (-12/5) = 304(在 0~640 內,有效)(0, 133.33) 到 (304, 260)(含已知點 (320,0))。public static Point[] getLineClip(double x1, double y1, double x2, double y2,
double w, double h) {
// 1. 直線參數
double k = (y2 - y1) / (x2 - x1);
double b = y1 - k * x1;
// 2. 四邊界交點
List pts = new ArrayList<>();
// 左 x=0
double yLeft = b;
if (yLeft >= 0 && yLeft <= h) pts.add(new Point(0, yLeft));
// 右 x=w
double yRight = k * w + b;
if (yRight >= 0 && yRight <= h) pts.add(new Point(w, yRight));
// 上 y=0
if (k != 0) {
double xTop = -b / k;
if (xTop >= 0 && xTop <= w) pts.add(new Point(xTop, 0));
}
// 下 y=h
if (k != 0) {
double xBottom = (h - b) / k;
if (xBottom >= 0 && xBottom <= w) pts.add(new Point(xBottom, h));
}
// 3. 去重並按參數 t 排序(可選)
return pts.toArray(new Point[0]);
}
若需高性能批量處理(如遊戲渲染),建議使用成熟的線段裁剪算法,避免手動判邊漏況。
掌握「兩點式 → 斜截式 → 邊界求交 → 範圍過濾」通用流程,幾何題迎刃而解。