简体   繁体   English

如何计算两个约束段的旋转角度?

[英]How to calculate the rotation angle of two constrained segments?

I have two vectors, the Y-aligned is fixed whereby the X-aligned is allowed to rotate. 我有两个向量,Y轴是固定的,X轴可以旋转。 These vectors are connected together through two fixed-length segments. 这些向量通过两个固定长度的段连接在一起。 Given the angle between the two vectors (82.74) and the length of all segments, how can I get the angle of the two jointed segments (24.62 and 22.61)? 给定两个向量之间的角度(82.74)和所有线段的长度,如何获得两个关节线段的角度(24.62和22.61)?

在此处输入图片说明

What is given: the magnitude of the vectors, and the angle between the X-axis and OG: 给出的是:向量的大小,以及X轴和OG之间的角度:

var magOG = 3,
    magOE = 4,
    magGH = 3,
    magEH = 2,
    angleGamma = 90;

This is my starting point: angleGamma = 90 - then, I will have following vectors: 这是我的起点: angleGamma = 90然后,我将得到以下向量:

var vOG = new vec2(-3,0),
    vOE = new vec2(0,-4);

From here on, I am trying to get angleAlpha and angleBeta for values of angleGamma less than 90 degrees. 从这里开始,我试图让angleAlphaangleBeta的值angleGamma小于90度。

MAGNITUDE OF THE CONSTRAINED SEGMENTS: 约束分部的大小:

Segments HG and HE must meet following conditions: 细分HG和HE必须满足以下条件:

/
|  OG*OG+ OE*OE = (HG + HE)*(HG + HE)
>
|  OG - HG = OE - HE
\

which will lead to following two solutions (as pointed out in the accepted answer - bilateration): 这将导致以下两种解决方案(如公认的答案中所指出的那样-双边):

Solution 1:
========================================================
HG = 0.5*(-Math.sqrt(OG*OG + OE*OE) + OG - OE)
HE = 0.5*(-Math.sqrt(OG*OG + OE*OE) - OG + OE)

Solution 2:
========================================================
HG = 0.5*(Math.sqrt(OG*OG + OE*OE) + OG - OE)
HE = 0.5*(Math.sqrt(OG*OG + OE*OE) - OG + OE)

SCRATCHPAD: 便笺:

Here is a playground with the complete solution. 这是一个提供完整解决方案的游乐场。 The visualization library used here is the great JSXGraph . 这里使用的可视化库是很棒的JSXGraph Thanks to the Center for Mobile Learning with Digital Technology of the Bayreuth University. 感谢拜罗伊特大学的数字技术移动学习中心。

Credits for the circle intersection function: 01AutoMonkey in the accepted answer to this question: A JavaScript function that returns the x,y points of intersection between two circles? 圆交函数的功劳 :该问题的公认答案为01AutoMonkey一个JavaScript函数,返回两个圆之间的交点x,y?

 function deg2rad(deg) { return deg * Math.PI / 180; } function rad2deg(rad) { return rad * 180 / Math.PI; } function lessThanEpsilon(x) { return (Math.abs(x) < 0.00000000001); } function angleBetween(point1, point2) { var x1 = point1.X(), y1 = point1.Y(), x2 = point2.X(), y2 = point2.Y(); var dy = y2 - y1, dx = x2 - x1; var t = -Math.atan2(dx, dy); /* range (PI, -PI] */ return rad2deg(t); /* range (180, -180] */ } function circleIntersection(circle1, circle2) { var r1 = circle1.radius, cx1 = circle1.center.X(), cy1 = circle1.center.Y(); var r2 = circle2.radius, cx2 = circle2.center.X(), cy2 = circle2.center.Y(); var a, dx, dy, d, h, h2, rx, ry, x2, y2; /* dx and dy are the vertical and horizontal distances between the circle centers. */ dx = cx2 - cx1; dy = cy2 - cy1; /* angle between circle centers */ var theta = Math.atan2(dy,dx); /* vertical and horizontal components of the line connecting the circle centers */ var xs1 = r1*Math.cos(theta), ys1 = r1*Math.sin(theta), xs2 = r2*Math.cos(theta), ys2 = r2*Math.sin(theta); /* intersection points of the line connecting the circle centers */ var sxA = cx1 + xs1, syA = cy1 + ys1, sxL = cx2 - xs2, syL = cy2 - ys2; /* Determine the straight-line distance between the centers. */ d = Math.sqrt((dy*dy) + (dx*dx)); /* Check for solvability. */ if (d > (r1 + r2)) { /* no solution. circles do not intersect. */ return [[sxA,syA], [sxL,syL]]; } thetaA = -Math.PI - Math.atan2(cx1,cy1); /* Swap XY and re-orient to -Y */ xA = +r1*Math.sin(thetaA); yA = -r1*Math.cos(thetaA); ixA = cx1 - xA; iyA = cy1 - yA; thetaL = Math.atan(cx2/cy2); xL = -r2*Math.sin(thetaL); yL = -r2*Math.cos(thetaL); ixL = cx2 - xL; iyL = cy2 - yL; if(d === 0 && r1 === r2) { /* infinite solutions. circles are overlapping */ return [[ixA,iyA], [ixL,iyL]]; } if (d < Math.abs(r1 - r2)) { /* no solution. one circle is contained in the other */ return [[ixA,iyA], [ixL,iyL]]; } /* 'point 2' is the point where the line through the circle intersection points crosses the line between the circle centers. */ /* Determine the distance from point 0 to point 2. */ a = ((r1*r1) - (r2*r2) + (d*d)) / (2.0 * d); /* Determine the coordinates of point 2. */ x2 = cx1 + (dx * a/d); y2 = cy1 + (dy * a/d); /* Determine the distance from point 2 to either of the intersection points. */ h2 = r1*r1 - a*a; h = lessThanEpsilon(h2) ? 0 : Math.sqrt(h2); /* Now determine the offsets of the intersection points from point 2. */ rx = -dy * (h/d); ry = +dx * (h/d); /* Determine the absolute intersection points. */ var xi = x2 + rx, yi = y2 + ry; var xi_prime = x2 - rx, yi_prime = y2 - ry; return [[xi, yi], [xi_prime, yi_prime]]; } function plot() { var cases = [ {a: 1.1, l: 1.9, f: 0.3073}, {a: 1.0, l: 1.7, f: 0.3229} ]; var testCase = 1; var magA = cases[testCase].a, magL = cases[testCase].l; var maxS = Math.sqrt(magA*magA+magL*magL), magS1 = maxS * cases[testCase].f, magS2 = maxS - magS1; var origin = [0,0], board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-5.0, 5.0, 5.0, -5.0], axis: true}); var drawAs = {dashed: {dash: 3, strokeWidth: 0.5, strokeColor: '#888888'} }; board.suspendUpdate(); var leftArm = board.create('slider', [[-4.5, 3], [-1.5, 3], [0, -64, -180]]); var leftLeg = board.create('slider', [[-4.5, 2], [-1.5, 2], [0, -12, -30]]); var rightArm = board.create('slider', [[0.5, 3], [3.5, 3], [0, 64, 180]]); var rightLeg = board.create('slider', [[0.5, 2], [3.5, 2], [0, 12, 30]]); var lh = board.create('point', [ function() { return +magA * Math.sin(deg2rad(leftArm.Value())); }, function() { return -magA * Math.cos(deg2rad(leftArm.Value())); } ], {size: 3, name: 'lh'}); var LA = board.create('line', [origin, lh], {straightFirst: false, straightLast: false, lastArrow: true}); var cLS1 = board.create('circle', [function() { return [lh.X(), lh.Y()]; }, function() { return magS1; }], drawAs.dashed); var lf = board.create('point', [ function() { return +magL * Math.sin(deg2rad(leftLeg.Value())); }, function() { return -magL * Math.cos(deg2rad(leftLeg.Value())); } ], {size: 3, name: 'lf'}); var LL = board.create('line', [origin, lf], {straightFirst: false, straightLast: false, lastArrow: true}); var cLS2 = board.create('circle', [function() { return [lf.X(), lf.Y()]; }, function() { return magS2; }], drawAs.dashed); var lx1 = board.create('point', [ function() { return circleIntersection(cLS1, cLS2)[0][0]; }, function() { return circleIntersection(cLS1, cLS2)[0][1]; } ], {size: 3, face:'x', name: 'lx1'}); var lx2 = board.create('point', [ function() { return circleIntersection(cLS1, cLS2)[1][0]; }, function() { return circleIntersection(cLS1, cLS2)[1][1]; } ], {size: 3, face:'x', name: 'lx2'}); /* Angle between lh, lx1 shall be between 0 and -180 */ var angleLAJ = board.create('text', [-3.7, 0.5, function(){ return angleBetween(lh, lx1).toFixed(2); }]); /* Angle between lf, lx1 shall be between 0 and 180 */ var angleLLJ = board.create('text', [-2.7, 0.5, function(){ return angleBetween(lf, lx1).toFixed(2); }]); var rh = board.create('point', [ function() { return +magA * Math.sin(deg2rad(rightArm.Value())); }, function() { return -magA * Math.cos(deg2rad(rightArm.Value())); } ], {size: 3, name: 'rh'}); var RA = board.create('line', [origin, rh], {straightFirst: false, straightLast: false, lastArrow: true}); var cRS1 = board.create('circle', [function() { return [rh.X(), rh.Y()]; }, function() { return magS1; }], drawAs.dashed); var rf = board.create('point', [ function() { return +magL * Math.sin(deg2rad(rightLeg.Value())); }, function() { return -magL * Math.cos(deg2rad(rightLeg.Value())); } ], {size: 3, name: 'rf'}); var RL = board.create('line', [origin, rf], {straightFirst: false, straightLast: false, lastArrow: true}); var cRS2 = board.create('circle', [function() { return [rf.X(), rf.Y()]; }, function() { return magS2; }], drawAs.dashed); var rx1 = board.create('point', [ function() { return circleIntersection(cRS1, cRS2)[1][0]; }, function() { return circleIntersection(cRS1, cRS2)[1][1]; } ], {size: 3, face:'x', name: 'rx1'}); var rx2 = board.create('point', [ function() { return circleIntersection(cRS1, cRS2)[0][0]; }, function() { return circleIntersection(cRS1, cRS2)[0][1]; } ], {size: 3, face:'x', name: 'rx2'}); var angleRAJ = board.create('text', [+1.3, 0.5, function(){ return angleBetween(rh, rx1).toFixed(2); }]); var angleRLJ = board.create('text', [+2.3, 0.5, function(){ return angleBetween(rf, rx1).toFixed(2); }]); board.unsuspendUpdate(); } plot(); 
 <!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/jsxgraph/0.99.7/jsxgraph.css" /> <link rel="stylesheet" href="style.css"> <script type="text/javascript" charset="UTF-8" src="//cdnjs.cloudflare.com/ajax/libs/jsxgraph/0.99.7/jsxgraphcore.js"></script> </head> <body> <div id="jxgbox" class="jxgbox" style="width:580px; height:580px;"></div> </body> </html> 

According to your sketch, the coordinates of E and G are: 根据您的草图,E和G的坐标为:

E = (0, -magOE)
G = magOG * ( -sin(gamma), -cos(gamma) )

Then, calculating the position of H is a trilateration problem. 那么,计算H的位置是一个三边测量问题。 Actually, it is just bilateration because you are missing a third distance. 实际上,这只是双向关系,因为您缺少第三条距离。 Hence, you will get two possible positions for H. 因此,您将获得H的两个可能职位。

First, let us define a new coordinate system, where E lies at the origin and G lies on the x-axis. 首先,让我们定义一个新的坐标系,其中E位于原点,G位于x轴上。 The x-axis direction in our original coordinate system is then: 那么,我们原始坐标系中的x轴方向为:

x = (G - E) / ||G - E||

The y-axis is: y轴为:

y = ( x.y, -x.x )

The coordinates of E and G in this new coordinate system are: 在此新坐标系中,E和G的坐标为:

E* = (0, 0)
G* = (0, ||G - E||)

Now, we can easily find the coordinates of H in this coordinate system, up to the ambiguity mentioned earlier. 现在,我们可以很容易地找到此坐标系中H的坐标,直到前面提到的模棱两可为止。 I will abbreviate ||G - E|| = d 我将缩写||G - E|| = d ||G - E|| = d like in the notation used in the Wikipedia article: ||G - E|| = d就像Wikipedia文章中使用的表示法一样:

H.x* = (magGH * magGH - magEH * magEH + d * d) / (2 * d)
H.y* = +- sqrt(magGH * magGH - H.x* * H.x*)

Hence, we have two solutions for Hy , one positive and one negative. 因此,对于Hy ,我们有两种解决方案,一种为正,一种为负。

Finally, we just need to transform H back into our original coordinate system: 最后,我们只需要将H转换回原始坐标系即可:

H = x * H.x* + y * H.y* - (0, magOE)

Given the coordinates of H, calculating the angles is pretty straightforward: 给定H的坐标,计算角度非常简单:

alpha = arccos((H.x - G.x) / ||H - G||)
beta  = arccos((H.y - E.y) / ||H - E||)

Example

Taking the values from your example 从您的示例中获取价值

magOG = 3
magOE = 4
magGH = 3
magEH = 2
angleGamma = 82.74°

we first get: 我们首先得到:

E = (0, -4)
G = 3 * ( -sin(82.74°), -cos(82.74°) )
  = (-2.976, -0.379)

Our coordinate system: 我们的坐标系:

x = (-0.635, 0.773) y = ( 0.773, 0.635) x =(-0.635,0.773)y =(0.773,0.635)

In this coordinate system: 在此坐标系中:

E* = (0, 0)
G* = (0, 4.687)

Then, the coordinates of H in our auxiliary coordinate system are: 然后,我们辅助坐标系中H的坐标为:

H* = (2.877, +- 0.851)

I will only focus on the positive value for H*.y because this is the point that you marked in your sketch. 我将仅关注H * .y的正值,因为这是您在草图中标记的点。

Transform back to original coordinate system: 转换回原始坐标系:

H = (-1.169, -1.237)

And finally calculate the angles: 最后计算角度:

alpha = 25.41°
beta  = 22.94°

The slight differences to your values are probably caused by rounding errors (either in my calculations or in yours). 您的值略有差异可能是由于舍入误差(无论是在我的计算中还是在您的计算中)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM