椭圆弧的边界
Bounds of ellipse arc
我需要找到二维变换椭圆弧的精确边界。
参赛数据为:
- a - 椭圆半径 x
- b - 椭圆半径 y
- transform - 具有 0 个平移的 2D 变换 (a, b, c, d, tx, ty)
- startAngle - 圆弧起始角度
- endAngle - 圆弧结束角度
我已使用此主题答案找到变换椭圆的边界
https://math.stackexchange.com/questions/91132/how-to-get-the-limits-of-rotated-ellipse
它工作正常。
我现在有什么
const rx2 = radiusX * radiusX;
const ry2 = radiusY * radiusY;
let maxX = Math.sqrt(rx2 * transform.a * transform.a + ry2 * transform.c * transform.c);
let maxY = Math.sqrt(rx2 * transform.b * transform.b + ry2 * transform.d * transform.d);
let minX = -maxX;
let minY = -maxY;
下一步是找到点p1、p2、p3、p4(见图)
这样我就可以检查哪些点在 startAngle 和 endAngle 内。
required points
椭圆的方程为:
simple equation
变换后的椭圆方程应为:
transformed equation
为了找到所需的点,最后一个方程必须求解 x 和 y
我知道了。
所以我只需要对点 (minX, minY) 应用逆变换; (最大X,最小Y); (maxX, maxY); (最大X,最小Y);
然后用简单的椭圆(上面提到的)和直线方程求出四个交点,然后将其转化为全局坐标乘以变换。
这里是一分代码
arcLineIntersection(lineStart, lineEnd, rx2, ry2, out) {
const lineK = (lineEnd.y - lineStart.y) / (lineEnd.x - lineStart.x);
if (Number.isFinite(lineK)) {
const lineB = lineStart.y - lineK * lineStart.x;
const a = lineK * lineK + ry2 / rx2;
const b = 2 * lineK * lineB;
const x = -b / (2 * a);
const y = lineK * x + lineB;
out.set(x, y);
} else {
const x = lineStart.x;
const y = Math.sqrt(ry2 * (1 - x * x / rx2));
out.set(x, y);
}
}
Result
我需要找到二维变换椭圆弧的精确边界。
参赛数据为:
- a - 椭圆半径 x
- b - 椭圆半径 y
- transform - 具有 0 个平移的 2D 变换 (a, b, c, d, tx, ty)
- startAngle - 圆弧起始角度
- endAngle - 圆弧结束角度
我已使用此主题答案找到变换椭圆的边界 https://math.stackexchange.com/questions/91132/how-to-get-the-limits-of-rotated-ellipse
它工作正常。
我现在有什么
const rx2 = radiusX * radiusX;
const ry2 = radiusY * radiusY;
let maxX = Math.sqrt(rx2 * transform.a * transform.a + ry2 * transform.c * transform.c);
let maxY = Math.sqrt(rx2 * transform.b * transform.b + ry2 * transform.d * transform.d);
let minX = -maxX;
let minY = -maxY;
下一步是找到点p1、p2、p3、p4(见图) 这样我就可以检查哪些点在 startAngle 和 endAngle 内。
required points
椭圆的方程为: simple equation
变换后的椭圆方程应为: transformed equation
为了找到所需的点,最后一个方程必须求解 x 和 y
我知道了。
所以我只需要对点 (minX, minY) 应用逆变换; (最大X,最小Y); (maxX, maxY); (最大X,最小Y); 然后用简单的椭圆(上面提到的)和直线方程求出四个交点,然后将其转化为全局坐标乘以变换。
这里是一分代码
arcLineIntersection(lineStart, lineEnd, rx2, ry2, out) {
const lineK = (lineEnd.y - lineStart.y) / (lineEnd.x - lineStart.x);
if (Number.isFinite(lineK)) {
const lineB = lineStart.y - lineK * lineStart.x;
const a = lineK * lineK + ry2 / rx2;
const b = 2 * lineK * lineB;
const x = -b / (2 * a);
const y = lineK * x + lineB;
out.set(x, y);
} else {
const x = lineStart.x;
const y = Math.sqrt(ry2 * (1 - x * x / rx2));
out.set(x, y);
}
}
Result