|
|
@ -57,14 +57,17 @@ export class BoxCheckIntersect
|
|
|
|
this.box = box;
|
|
|
|
this.box = box;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//直线与盒子相交,或者被盒子包含.
|
|
|
|
//直线与盒子相交,或者被盒子包含. Cohen–Sutherland裁剪算法
|
|
|
|
IsIntersectLine(p1: Vec2, p2: Vec2): boolean
|
|
|
|
IsIntersectLine(p1: Vec2, p2: Vec2): boolean
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let code1 = ComputeOutCode(p1.x, p1.y, this.box);
|
|
|
|
let code1 = ComputeOutCode(p1.x, p1.y, this.box);
|
|
|
|
let code2 = ComputeOutCode(p2.x, p2.y, this.box);
|
|
|
|
let code2 = ComputeOutCode(p2.x, p2.y, this.box);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//按位AND不为0:两个点共享一个外部区域(LEFT,RIGHT,TOP或BOTTOM),因此两个点都必须在窗口外部
|
|
|
|
|
|
|
|
if (code1 & code2) return false;
|
|
|
|
|
|
|
|
|
|
|
|
let code = code1 | code2;
|
|
|
|
let code = code1 | code2;
|
|
|
|
if (code1 === 0 || code2 === 0 || code === 3 || code === 12)
|
|
|
|
if (code1 === 0 || code2 === 0 || code === 3 || code === 12)//点1点2在矩形内,或者竖直贯穿,水平贯穿
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
if ((code & TOP) && doIntersect(p1, p2, this.p3, this.p4))
|
|
|
|
if ((code & TOP) && doIntersect(p1, p2, this.p3, this.p4))
|
|
|
@ -87,3 +90,89 @@ export class BoxCheckIntersect
|
|
|
|
return ((nearestX - cen.x) ** 2 + (nearestY - cen.y) ** 2) <= radius ** 2;
|
|
|
|
return ((nearestX - cen.x) ** 2 + (nearestY - cen.y) ** 2) <= radius ** 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm
|
|
|
|
|
|
|
|
function CohenSutherlandLineClip(box: Box2, p1: Vec2, p2: Vec2)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let [x0, y0] = [p1.x, p1.y];
|
|
|
|
|
|
|
|
let [x1, y1] = [p2.x, p2.y];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let xmin = box.min.x;
|
|
|
|
|
|
|
|
let ymin = box.min.y;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let xmax = box.max.x;
|
|
|
|
|
|
|
|
let ymax = box.max.y;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// compute outcodes for P0, P1, and whatever point lies outside the clip rectangle
|
|
|
|
|
|
|
|
let outcode0 = ComputeOutCode(x0, y0, box);
|
|
|
|
|
|
|
|
let outcode1 = ComputeOutCode(x1, y1, box);
|
|
|
|
|
|
|
|
let accept = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (true)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!(outcode0 | outcode1))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// bitwise OR is 0: both points inside window; trivially accept and exit loop
|
|
|
|
|
|
|
|
accept = true;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (outcode0 & outcode1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// bitwise AND is not 0: both points share an outside zone (LEFT, RIGHT, TOP,
|
|
|
|
|
|
|
|
// or BOTTOM), so both must be outside window; exit loop (accept is false)
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// failed both tests, so calculate the line segment to clip
|
|
|
|
|
|
|
|
// from an outside point to an intersection with clip edge
|
|
|
|
|
|
|
|
let x: number, y: number;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// At least one endpoint is outside the clip rectangle; pick it.
|
|
|
|
|
|
|
|
let outcodeOut = outcode1 > outcode0 ? outcode1 : outcode0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Now find the intersection point;
|
|
|
|
|
|
|
|
// use formulas:
|
|
|
|
|
|
|
|
// slope = (y1 - y0) / (x1 - x0)
|
|
|
|
|
|
|
|
// x = x0 + (1 / slope) * (ym - y0), where ym is ymin or ymax
|
|
|
|
|
|
|
|
// y = y0 + slope * (xm - x0), where xm is xmin or xmax
|
|
|
|
|
|
|
|
// No need to worry about divide-by-zero because, in each case, the
|
|
|
|
|
|
|
|
// outcode bit being tested guarantees the denominator is non-zero
|
|
|
|
|
|
|
|
if (outcodeOut & TOP)
|
|
|
|
|
|
|
|
{ // point is above the clip window
|
|
|
|
|
|
|
|
x = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0);
|
|
|
|
|
|
|
|
y = ymax;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (outcodeOut & DOWN)
|
|
|
|
|
|
|
|
{ // point is below the clip window
|
|
|
|
|
|
|
|
x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0);
|
|
|
|
|
|
|
|
y = ymin;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (outcodeOut & RIGHT)
|
|
|
|
|
|
|
|
{ // point is to the right of clip window
|
|
|
|
|
|
|
|
y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0);
|
|
|
|
|
|
|
|
x = xmax;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (outcodeOut & LEFT)
|
|
|
|
|
|
|
|
{ // point is to the left of clip window
|
|
|
|
|
|
|
|
y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0);
|
|
|
|
|
|
|
|
x = xmin;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Now we move outside point to intersection point to clip
|
|
|
|
|
|
|
|
// and get ready for next pass.
|
|
|
|
|
|
|
|
if (outcodeOut === outcode0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
x0 = x;
|
|
|
|
|
|
|
|
y0 = y;
|
|
|
|
|
|
|
|
outcode0 = ComputeOutCode(x0, y0, box);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
x1 = x;
|
|
|
|
|
|
|
|
y1 = y;
|
|
|
|
|
|
|
|
outcode1 = ComputeOutCode(x1, y1, box);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|