У меня есть два вектора, выравнивание по оси Y фиксируется, благодаря чему выравнивание по оси X может вращаться.Эти векторы соединены вместе двумя отрезками фиксированной длины.Учитывая угол между двумя векторами (82,74) и длину всех сегментов, как я могу получить угол двух соединенных сегментов (24,62 и 22,61)?
Что дано: величина векторов и угол между осью X и OG:
var magOG = 3,
magOE = 4,
magGH = 3,
magEH = 2,
angleGamma = 90;
Это моя отправная точка: angleGamma = 90
- тогда я буду иметьследующие векторы:
var vOG = new vec2(-3,0),
vOE = new vec2(0,-4);
С этого момента я пытаюсь получить angleAlpha
и angleBeta
для значений angleGamma
меньше 90 градусов.
Величина ограниченных сегментов:
Сегменты HG и HE должны соответствовать следующим условиям:
/
| OG*OG+ OE*OE = (HG + HE)*(HG + HE)
>
| OG - HG = OE - HE
\
, что приведет к следующим двум решениям (как указано в принятом ответе - билатерация):
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:
Вот игровая площадка с полным решением.Здесь используется библиотека визуализации - JSXGraph .Благодаря Центру мобильного обучения с использованием цифровых технологий Университета Байройта.
Кредиты для функции пересечения окружностей: 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 X-Y 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>