Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
svg arc,如何确定给定开始和结束的扫掠和大弧标志&;通过点_Svg_Geometry_Geometric Arc - Fatal编程技术网

svg arc,如何确定给定开始和结束的扫掠和大弧标志&;通过点

svg arc,如何确定给定开始和结束的扫掠和大弧标志&;通过点,svg,geometry,geometric-arc,Svg,Geometry,Geometric Arc,在svg中,我想构建一个函数,返回path-d属性中“arc元素”的所有参数。给定起点、终点和过孔点。(非直线上的3个点符合圆上的定义)。我只对圆弧感兴趣(rx==ry) 我可以很容易地计算出圆心和半径。但是我正在与这两个标志作斗争,是否有一个清晰的定义,如何通过比较这三个点的拓扑来设置这些标志?彼此之间的角度或距离如何?) 我知道标志的含义,最小弧与最大弧,顺时针与逆时针方向的扫掠标志。我最近对svg圆弧做了一些工作,并使用以下内容获得了圆弧扫掠和d值。这可能会有帮助 //---x1,y1 a

在svg中,我想构建一个函数,返回path-d属性中“arc元素”的所有参数。给定起点、终点和过孔点。(非直线上的3个点符合圆上的定义)。我只对圆弧感兴趣(rx==ry)

我可以很容易地计算出圆心和半径。但是我正在与这两个标志作斗争,是否有一个清晰的定义,如何通过比较这三个点的拓扑来设置这些标志?彼此之间的角度或距离如何?)


我知道标志的含义,最小弧与最大弧,顺时针与逆时针方向的扫掠标志。

我最近对svg圆弧做了一些工作,并使用以下内容获得了圆弧扫掠和d值。这可能会有帮助

//---x1,y1 and x2,y2 are the two end points---
    function polarToCartesian(centerX, centerY,radius, angleInDegrees)
    {
        var angleInRadians = (angleInDegrees) * Math.PI / 180.0;

        return {
        x: centerX + (radius * Math.cos(angleInRadians)),
        y: centerY + (radius * Math.sin(angleInRadians))
        };
    }
    var startAngle = 180/Math.PI*Math.atan2(y1-cy, x1-cx);
    var endAngle =  180/Math.PI*Math.atan2(y2-cy, x2-cx);

    StartPnt = polarToCartesian(cx, cy, radius, startAngle);
    EndPnt = polarToCartesian(cx, cy,  radius, endAngle);
    ArcSweep = endAngle - startAngle <= 180 ? "0" : "1";

    var d = [
    "M", StartPnt.x, StartPnt.y,
    "A", radius, radius, 0, ArcSweep, 0, EndPnt.x, EndPnt.y
    ].join(" ");
/--x1、y1和x2、y2是两个端点---
函数极笛卡尔坐标(centerX、centerY、半径、angleInDegrees)
{
var angleInRadians=(angleInDegrees)*Math.PI/180.0;
返回{
x:centerX+(半径*数学坐标(角半径)),
y:中心y+(半径*数学正弦(角度半径))
};
}
var startAngle=180/数学π*数学atan2(y1 cy,x1 cx);
变量端角=180/数学PI*数学atan2(y2 cy,x2 cx);
StartPnt=极笛卡尔坐标(cx,cy,半径,startAngle);
EndPnt=极笛卡尔坐标(cx,cy,半径,端角);

ArcSweep=endAngle-startAngle是的,您可以通过查看由该圆弧的起点(S)、过孔(V)和终点(E)点形成的角度来确定svg路径圆弧段的大圆弧和扫掠标志

对于大圆弧标志:

  • 如果|&角度;SVE |>π/2然后标志=0
  • 如果|&角度;SVE |<π/2然后标志=1
    • 您正在确定以V为中心的角度是锐角还是钝角
    • 如果这个角度是“尖的”(即锐角),那么你将绕着圆走很长一段路
对于扫描标志:

  • If&angle;ESV>0,然后标志=0
  • If&angle;ESV<0然后标志=1
    • 您正在确定V点位于S-to-E线的哪一侧
    • 当你从S向E看的时候,如果V在右边,那么你将逆时针绕着圆圈移动
注意以下几点:

  • 形成角度的点的顺序很重要:对于大弧标志和扫掠标志,分别为S-V-E和E-S-V
  • 所有角度必须介于-π和π之间,即介于-180°和180°之间
  • 绝对值用于确定大圆弧标志,而不是扫描标志
此答案底部的演示代码演示了这些计算。直接回答OP问题的唯一重要代码是前两行:

const lgArcFl = (S,V,E) => Math.abs(angle(S,V,E)) > pi/2 ? 0 : 1;
const sweepFl = (S,V,E) =>          angle(E,S,V)  > 0    ? 0 : 1;
要使用演示,请单击“运行代码片段”按钮,然后单击矩形上的3x,以按该顺序定位起点(S)、通过点(V)和终点(E)。演示将计算半径,然后使用两个标志的各种组合绘制所有4条可能的圆弧,即
0,0
0,1
1,0
1,1
。大弧线和小弧线分别为蓝色和红色,顺时针和逆时针弧线分别为实心和虚线。一个正确的弧将以黄色突出显示。绘制圆弧后,您可以重新单击3次以重复,等等。请注意,在同一位置单击两次或在直线上单击3次不会产生任何圆弧,这在几何上是预期的

请注意,在我第一次发布这个答案(2016年11月5日)时,该演示在Chrome、Opera和Safari中运行,但在Firefox中不起作用。(我没有检查Explorer或Edge,也没有检查任何移动浏览器。)我怀疑这可能是因为我使用了ES6/ES2015代码。但是,在代码编辑器中单击“Use BabelJS/ES2015”按钮会使代码无法使用,原因我不明白。因此,如果您在使演示程序正常工作时遇到问题,可以尝试其他浏览器

constlgarcfl=(S,V,E)=>Math.abs(角度(S,V,E))>pi/2?0 : 1;
常数扫掠FL=(S,V,E)=>角度(E,S,V)=>0?0 : 1;
常数角=([a,b],[c,d],[e,f])=>(数学atan2(f-d,e-c)-数学atan2(b-d,a-c)+3*pi)%(2*pi)-pi;
const qs=sel=>document.querySelector(sel),pi=Math.pi,pts=[];
常数半径=([a,b],[c,d],[e,f])=>{
常数g=c-a,h=2*(c-e)/g,i=d-b,j=c*c+d*d,k=j-a*a-b*b,l=(j-e*e-f*f-h*k/2)/(2*(d-f)-h*i);
返回数学模型(a+(i*l-k/2)/g,b-l);
};
常量mkArc=(arc[sx,sy],[ex,ey],r,lg,sw)=>arc.setAttribute('d',
`M${sx}${sy}A${r}${r}${0${lg}${sw}${ex}${ey}`);
const calcArcs=(S,V,E)=>{
常数args=[S,E,半径(S,V,E)];
[0,0],[0,1],[1,0],[1,1]].forEach([lg,sw])=>mkArc(qs(`arc${lg}${sw}'),…args,lg,sw));
mkArc(qs(`arc'),…args,lgArcFl(S,V,E),sweepFl(S,V,E));
};
设ptNum=0;
qs('svg')。addEventListener('click',evt=>{
常数x=evt.x-10,y=evt.y-10;
pts[ptNum]=[x,y];
setAttribute('transform','translate(${x},${y})`);
如果(ptNum++==2){
钙质(…pts);
ptNum=0;
}
});
文本{
字体系列:信使;
字号:18px;
填充:黑色;
中风:无;
转换:转换(-5px,5px);
}
#arc00,#arc01{
笔画:红色;
}
#弧10,#弧11{
笔画:蓝色;
}
#arc00,#arc10{
笔画宽度:4;
笔划数组:5,5;
}
#arc01,#arc11{
笔画宽度:2;
}
直肠{
填充:无;
笔画:黑色;
高度:200px;
宽度:600px;
}

s
v
E

这是不正确的。SVG弧是“一个radx rady xrot deg largearc扫描端点x endy”。您所称的ArcSweep实际上是largeArc标志,如果角度大于PI,则为“1”。扫描标志确定是顺时针还是逆时针绘制,并具有反射效果