计算SVG弧的中心
Calculate center of SVG arc
我有以下信息:
- 半径X(rx)
- 半径Y(ry)
- x1
- y1
- x2
- y2
SVG规范允许您通过指定圆弧的半径以及起点和终点来定义圆弧。还有其他选项,如large-arc-flag
和sweep-flag
,它们有助于定义起点到达终点的方式。更多详细信息请点击此处。
我没有数学倾向,所以理解这一切几乎是不可能的。
我想我正在寻找一个简单的方程,它可以让我知道给定SVG的arc命令所接受的所有参数的centerX
和centerY
值。
感谢您的帮助。
我搜索了stackoverflow,似乎没有一个答案能用通俗的英语解释这个解决方案。
来自W3C SVG 1.1规范:从端点到中心参数化的转换
你可以看一下详细的解释。
这是一个javascript实现。
// svg : [A | a] (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+
function radian( ux, uy, vx, vy ) {
var dot = ux * vx + uy * vy;
var mod = Math.sqrt( ( ux * ux + uy * uy ) * ( vx * vx + vy * vy ) );
var rad = Math.acos( dot / mod );
if( ux * vy - uy * vx < 0.0 ) {
rad = -rad;
}
return rad;
}
//conversion_from_endpoint_to_center_parameterization
//sample : svgArcToCenterParam(200,200,50,50,0,1,1,300,200)
// x1 y1 rx ry φ fA fS x2 y2
// phi, startAngle, deltaAngle, endAngle are radians not degrees.
// SVG use degrees, convert it to radians by:
// phi = degree * Math.PI / 180;
function svgArcToCenterParam(x1, y1, rx, ry, phi, fA, fS, x2, y2) {
var cx, cy, startAngle, deltaAngle, endAngle;
var PIx2 = Math.PI * 2.0;
if (rx < 0) {
rx = -rx;
}
if (ry < 0) {
ry = -ry;
}
if (rx == 0.0 || ry == 0.0) { // invalid arguments
throw Error('rx and ry can not be 0');
}
// SVG use degrees, if your input is degree from svg,
// you should convert degree to radian as following line.
// phi = phi * Math.PI / 180;
var s_phi = Math.sin(phi);
var c_phi = Math.cos(phi);
var hd_x = (x1 - x2) / 2.0; // half diff of x
var hd_y = (y1 - y2) / 2.0; // half diff of y
var hs_x = (x1 + x2) / 2.0; // half sum of x
var hs_y = (y1 + y2) / 2.0; // half sum of y
// F6.5.1
var x1_ = c_phi * hd_x + s_phi * hd_y;
var y1_ = c_phi * hd_y - s_phi * hd_x;
// F.6.6 Correction of out-of-range radii
// Step 3: Ensure radii are large enough
var lambda = (x1_ * x1_) / (rx * rx) + (y1_ * y1_) / (ry * ry);
if (lambda > 1) {
rx = rx * Math.sqrt(lambda);
ry = ry * Math.sqrt(lambda);
}
var rxry = rx * ry;
var rxy1_ = rx * y1_;
var ryx1_ = ry * x1_;
var sum_of_sq = rxy1_ * rxy1_ + ryx1_ * ryx1_; // sum of square
if (!sum_of_sq) {
throw Error('start point can not be same as end point');
}
var coe = Math.sqrt(Math.abs((rxry * rxry - sum_of_sq) / sum_of_sq));
if (fA == fS) { coe = -coe; }
// F6.5.2
var cx_ = coe * rxy1_ / ry;
var cy_ = -coe * ryx1_ / rx;
// F6.5.3
cx = c_phi * cx_ - s_phi * cy_ + hs_x;
cy = s_phi * cx_ + c_phi * cy_ + hs_y;
var xcr1 = (x1_ - cx_) / rx;
var xcr2 = (x1_ + cx_) / rx;
var ycr1 = (y1_ - cy_) / ry;
var ycr2 = (y1_ + cy_) / ry;
// F6.5.5
startAngle = radian(1.0, 0.0, xcr1, ycr1);
// F6.5.6
deltaAngle = radian(xcr1, ycr1, -xcr2, -ycr2);
while (deltaAngle > PIx2) { deltaAngle -= PIx2; }
while (deltaAngle < 0.0) { deltaAngle += PIx2; }
if (fS == false || fS == 0) { deltaAngle -= PIx2; }
endAngle = startAngle + deltaAngle;
while (endAngle > PIx2) { endAngle -= PIx2; }
while (endAngle < 0.0) { endAngle += PIx2; }
var outputObj = { /* cx, cy, startAngle, deltaAngle */
cx: cx,
cy: cy,
startAngle: startAngle,
deltaAngle: deltaAngle,
endAngle: endAngle,
clockwise: (fS == true || fS == 1)
}
return outputObj;
}
用法示例:
svg
<path d="M 0 100 A 60 60 0 0 0 100 0"/>
js
var result = svgArcToCenterParam(0, 100, 60, 60, 0, 0, 0, 100, 0);
console.log(result);
/* will output:
{
cx: 49.99999938964844,
cy: 49.99999938964844,
startAngle: 2.356194477985314,
deltaAngle: -3.141592627780225,
endAngle: 5.497787157384675,
clockwise: false
}
*/
我正在考虑x轴旋转=0的情况。起点和终点方程式:
x1=cx+rx*cos(起始角度)
y1=cy+ry*sin(起始角度)
x2=cx+rx*cos(EndAngle)
y2=cy+ry*sin(EndAngle)
从方程组中排除角度得出:
ry^2*(x1 cx)^2+rx^2*(y1 cy)^2=rx^2*ry^2
ry^2*(x2 cx)^2+rx^2*(y2 cy)^2=rx^2*ry^2
这个方程组可以用手或借助数学包(Maple、Mathematica等)解析求解(cx,cy)。二次方程有两种解(由于大弧标志和扫频标志的组合)。
相关文章:
- D3在一个调用中绘制不同的SVG形状,没有可见性
- 如何使用javascript从主svg对象动态创建svg视图框
- 如何更改<svg>标记为<img>用js标记
- 根据元素和容器大小计算边距
- 从Rally获取一个特定的标记,以便计算另一个字段中的值
- 使用D3.js计算带有字母间距的文本长度
- 如何在 JavaScript 中计算 SVG 路径的椭圆路径坐标
- 使用 snap SVG,如何以像素为单位计算 SVG 文件的整个路径
- 将计算的SVG作为数据URI传递给SRC属性
- 计算safari和chrome中svg路径的getBBox()中包含的控制点
- 计算SVG弧的中心
- 如何计算(SVG) X/Y坐标的平移和旋转(在JS/D3.js)
- HTML5 SVG:计算动态创建的SVG内容的文本大小
- 计算SVG文本的垂直高度
- 尝试旋转和变换SVG路径-我需要三角计算
- 计算SVG元素的尺寸
- 预计算SVG文本坐标和宽度
- 计算SVG/string中的所有十六进制颜色代码
- 在创建节点之前计算绘制的 SVG 路径
- 使用 SVG 规范计算子路径的长度