Javascript 给定固定角度、宽度和;我们如何计算椭圆的水平和垂直半径?
给定一个固定的角度、宽度和矢状,我们如何计算椭圆的水平和垂直半径 我想画一条椭圆弧,它具有给定的弧宽、弧高(矢状)和椭圆的给定角度。Javascript 给定固定角度、宽度和;我们如何计算椭圆的水平和垂直半径?,javascript,math,geometry,ellipse,Javascript,Math,Geometry,Ellipse,给定一个固定的角度、宽度和矢状,我们如何计算椭圆的水平和垂直半径 我想画一条椭圆弧,它具有给定的弧宽、弧高(矢状)和椭圆的给定角度。 下图中为黑色和黄色虚线弧。要做到这一点,我需要知道椭圆的两个半径 对于一个圆,可以很容易地计算出它的1个半径,给出任意2个角度、矢状或宽度值。 请参阅下面的代码片段。 如何调整函数以适用于椭圆? 图中的角度可以说是对称的,从-60到60,角度为120。这是我真正需要的情况,即弧在垂直轴或水平轴的两侧反射自身。 如果角度是120,从80开始,到200结束,没有真正的
下图中为黑色和黄色虚线弧。要做到这一点,我需要知道椭圆的两个半径 对于一个圆,可以很容易地计算出它的1个半径,给出任意2个角度、矢状或宽度值。
请参阅下面的代码片段。
如何调整函数以适用于椭圆? 图中的角度可以说是对称的,从-60到60,角度为120。这是我真正需要的情况,即弧在垂直轴或水平轴的两侧反射自身。
如果角度是120,从80开始,到200结束,没有真正的矢状图,只有弧的最高点和一个紧密的边界框,如果有人也有解决方案,这将是一种奢侈
var arcCalc=函数(r、w、a、s){
//允许对象使用
if(对象的r实例){
w=r.w | | r.宽度;
a=r.a | | r.角;
s=r.s | | r.sagitta;
r=r.r | | r.半径;
}
w=这个。toPts(w);
s=此。toPts(s);
r=这个。toPts(r);
var sin,cos,twoKnown;
sin=Math.sin;
cos=Math.cos;
//如果我们知道任何两个论点,那么我们就可以找出其他论点
//如果不是,我们不能
twoKnown=+!r++!w++!a++!s<3;
//此时,我们正试图避免抛出错误
//所以现在就把我们收到的垃圾扔回去吧
如果(!twoKnown)
返回{
半径:r,
宽度:w,
角度:a,,
萨吉塔:是的,
r:r,
w:w,
a:a,
s:s
};
如果(a){
a*=数学PI/180;
}
if(!r){
如果(!s){
r=w/(2*sin(a/2));
}否则如果(!a){
r=(s*s+0.5*w*(0.5*w))/(2*s);
}否则{
r=s/(1-cos(a/2));
}
}
//在这一点上,我们知道我们有r
如果(!w){
如果(!s){
w=2*r*sin(a/2);
}否则{
w=2*Math.sqrt(s*(2*r-s));
}
}
//在这一点上,我们知道我们有r和w
如果(!a){
如果(!s){
//我们加了一轮是因为
//w/(2*r)可能达到1.000000000001
//然后就产生了NaN
a=2*Math.asin(本轮(w/(2*r));
}否则{
a=2*Math.acos(本轮(1-s/r));
}
}
如果(!s){
s=r-r*cos(a/2);
}
a*=180/Math.PI;
返回{
半径:r,
宽度:w,
角度:a,,
萨吉塔:是的,
r:r,
w:w,
a:a,
s:s
};
};
给出的是角度α、宽度和矢状。圆的半径r
可根据α和正弦公式计算。类似地,x-sagitta
遵循余弦公式
为了找到y
,我们使用y/x
的因子将图形缩放到x方向。这会将椭圆转换为半径为y的圆。它将[x-sagitta,width/2]
处的点转换为[(x-sagitta)*y/x,width/2]
。该转换点必须位于半径为y
的圆上。我们在y
中得到一个二次方程:
((x-sagitta)*y/x)^2+(宽度/2)^2=y^2
其积极的解决办法是
y=width*x*sqrt(1/(矢状图*(2*x-sagitta))/2
前提是2*x>sagitta
。它减少到cos(alpha/2)>0
或alpha<180°
。当然,矢状、宽度和阿尔法的极端组合会导致椭圆极度拉伸
继续,这将给出(r是圆的半径,x和y是椭圆的轴):
使用Python和matplotlib绘制所有内容可确保方程式有意义:
从matplotlib导入pyplot作为plt
从matplotlib.patches导入椭圆
从数学输入sqrt、sin、cos、atan、pi
矢状位=15
α=120*pi/180
宽度=100
r=宽度/2/sin(α/2)
x=r*cos(α/2)+sagitta
y=宽度*x/sqrt(矢状图*(2*x-矢状图))/2
ax=plt.gca()
ax.图([r*cos(alpha/2),0,r*cos(alpha/2)],[r*sin(alpha/2),0,r*sin(alpha/2)],ls='-',
颜色(深红色)
椭圆=椭圆((0,0),2*x,2*y,颜色=紫色,线宽=1,填充=假,ls='-'))
圆=椭圆((0,0),2*r,2*r,color='番茄',线宽=1,fill=False,ls='-'
lim=最大值(x,y)*1.05
最大设定值\u xlim(-lim,lim)
最大设定值_ylim(-lim,lim)
ax.axhline(0,color='silver')
ax.axvline(0,颜色='silver')
ax.plot([x-sagitta,x-sagitta],[width/2,-width/2],color='limegreen',ls='--'))
ax.plot([x-sagitta,x],[0,0],color='brown',ls=''-')
ax.添加补片(椭圆)
ax.添加补片(圆形)
ax.文本(x-sagitta,宽/2'[x-s,宽/2]')
ax.set_方面(1)
plt.show()
给定的是角度α、宽度和矢状。圆的半径
r
可根据α和正弦公式计算。类似地,x-sagitta
遵循余弦公式
为了找到y
,我们使用y/x
的因子将图形缩放到x方向。这会将椭圆转换为半径为y的圆。它将[x-sagitta,width/2]
处的点转换为[(x-sagitta)*y/x,width/2]
。该转换点必须位于半径为y
的圆上。我们在y
中得到一个二次方程:
((x-sagitta)*y/x)^2+(宽度/2)^2=y^2
其积极的解决办法是
y=width*x*sqrt(1/(矢状图*(2*x-sagitta))/2
前提是2*x>sagitta
。它减少到cos(alpha/2)>0
或alpha<180°
。当然是矢状、宽度和宽度的极端组合
var arcCalc = function(r, w, a, s) {
// to allow for object usage
if (r instanceof Object) {
w = r.w || r.width;
a = r.a || r.angle;
s = r.s || r.sagitta;
r = r.r || r.radius;
}
w = this.toPts(w);
s = this.toPts(s);
r = this.toPts(r);
var sin, cos, twoKnown;
sin = Math.sin;
cos = Math.cos;
// if we know any two arguments then we can work out the other ones
// if not we can't
twoKnown = +!r + +!w + +!a + +!s < 3;
// At this point of time we are trying to avoid throwing errors
// so for now just throw back the garbage we received
if (!twoKnown)
return {
radius: r,
width: w,
angle: a,
sagitta: s,
r: r,
w: w,
a: a,
s: s
};
if (a) {
a *= Math.PI / 180;
}
if (!r) {
if (!s) {
r = w / (2 * sin(a / 2));
} else if (!a) {
r = (s * s + 0.5 * w * (0.5 * w)) / (2 * s);
} else {
r = s / (1 - cos(a / 2));
}
}
// at this point we know we have r
if (!w) {
if (!s) {
w = 2 * r * sin(a / 2);
} else {
w = 2 * Math.sqrt(s * (2 * r - s));
}
}
// at this point we know we have r and w
if (!a) {
if (!s) {
// We added the round because
// w / (2*r) could come to 1.00000000001
// and then NaN would be produced
a = 2 * Math.asin(this.round(w / (2 * r)));
} else {
a = 2 * Math.acos(this.round(1 - s / r));
}
}
if (!s) {
s = r - r * cos(a / 2);
}
a *= 180 / Math.PI;
return {
radius: r,
width: w,
angle: a,
sagitta: s,
r: r,
w: w,
a: a,
s: s
};
};
r = width / 2 / sin(alpha / 2)
x = r * cos(alpha / 2) + sagitta
y = width * x / sqrt(sagitta * (2 * x - sagitta)) / 2