我正在尝试绘制连接两个矩形的(svg)弧。问题是,弧应该从矩形的边界开始,而不是从中心开始。
举例说明:
我有中心点,宽度和宽度矩形C1 w1 h1 C2 w2 h2
的高度以及弧D rx ry
的中心和x和y半径。所以基本上,为了绘制紫色弧线,我缺少P1
和P2
。
所有值都是动态的,可以更改,因此算法需要与rx
和ry
无关,矩形的宽度和高度,矩形相对于彼此的位置等等。 / p>
考虑到圆角将成为顶部的樱桃。但那不是必要的......
答案 0 :(得分:1)
让椭圆的中心为坐标原点(如果不是,只需将矩形坐标移动-D.X和-D.Y)。
在这个系统中,椭圆方程是
X = C1'.X + w1
在此等式中替换矩形边缘坐标,并检查结果是否实际属于矩形。
例如,顶部矩形的右边缘为C1'Y - h1 .. C1'Y + h1
。从椭圆方程中找到Y并检查它是否在P1 = (C1'.X + w1, CalculatedY)
范围内。如果是,{{1}}
答案 1 :(得分:0)
好的,仅适用于将来偶然发现这种情况的人。
这是我在javascript(ES6)中提出的。但将其移植到其他语言应该很容易..
/**
* Calculate the intersection of the border of the given rectangle
* and a circular arc.
* @param {Object} rectangle Rectangle object with dimensions and position properties.
* @param {Object} arc Arc object with center and radius properties.
* @return {Object} Resulting intersection point, with x- and y-coordinates.
*/
calculateBorderPoint(rectangle, arc) {
// Clone the rectangle, because we don't want to mutate the original.
const a = Object.assign({}, rectangle.position);
// Treat center of circle as coordinate origin.
a.x -= arc.center.x;
a.y -= arc.center.y;
let points = [];
// Check east & west with possible x values
const possibleX = [
a.x - rectangle.dimensions.width / 2,
a.x + rectangle.dimensions.width / 2,
];
possibleX.forEach((x) => {
const ySquared = [
Math.sqrt(Math.pow(arc.radius, 2) - Math.pow(x, 2)),
-Math.sqrt(Math.pow(arc.radius, 2) - Math.pow(x, 2)),
];
// Check if the derived y value is in range of rectangle
ySquared.forEach((y) => {
if (y >= a.y - rectangle.dimensions.height / 2 &&
y <= a.y + rectangle.dimensions.height / 2) {
points.push({x, y});
}
});
});
// Check north & south with possible y values
const possibleY = [
a.y - rectangle.dimensions.height / 2,
a.y + rectangle.dimensions.height / 2,
];
possibleY.forEach((y) => {
const xSquared = [
Math.sqrt(Math.pow(arc.radius, 2) - Math.pow(y, 2)),
-Math.sqrt(Math.pow(arc.radius, 2) - Math.pow(y, 2)),
];
// Check if the derived x value is in range of rectangle
xSquared.forEach((x) => {
if (x >= a.x - rectangle.dimensions.width / 2 &&
x <= a.x + rectangle.dimensions.width / 2) {
points.push({x, y});
}
});
});
// At this point you will propably have multiple possible solutions,
// because the circle might intersect the rectangle at multiple points.
// You need to select the point, that makes most sense in your case.
// One solution would be to select the one closest to the other rectangle.
// Translate it back.
points[0].x += arc.center.x;
points[0].y += arc.center.y;
return points[0];
}
它不漂亮,但它有效。我很高兴听到任何建议......