Я пытаюсь программно нарисовать стрелку из одного эллипса в другой, как показано ниже. Как рассчитать, куда на краю эллипса B должна указывать стрелка? Или есть более простой способ сделать это в SVG? Мне даны координаты x
и y
каждого эллипса, а также их горизонтальный и вертикальный радиусы. По этим координатам и радиусам мне нужно нарисовать стрелку.
В SVG вы можете нарисовать стрелку в конце строки с помощью маркера.
Чтобы узнать начальную и конечную точки линии, вам нужно вычислить их как точки на эллипсе под заданным углом.
Пожалуйста, прочитайте комментарии в коде.
//object with the first ellipse's attributes
let e1 = { cx: 20, cy: 50, rx: 10, ry: 5 };
//object with the second ellipse's attributes
let e2 = { cx: 120, cy: 20, rx: 10, ry: 5 };
//the distance in x between ellipses
let dx = e2.cx - e1.cx;
//the distance in y between ellipses
let dy = e2.cy - e1.cy;
//the angle
let angle = Math.atan2(dy, dx);
//the starting point of the line as a point on the first ellipse
let p1 = {
x: e1.cx + e1.rx * Math.cos(angle),
y: e1.cy + e1.ry * Math.sin(angle)
};
//the ending point of the line as a point on the second ellipse
let p2 = {
x: e2.cx + e2.rx * Math.cos(angle + Math.PI),
y: e2.cy + e2.ry * Math.sin(angle + Math.PI)
};
//setting the attributes of the line
l1.setAttribute("x1", p1.x);
l1.setAttribute("x2", p2.x);
l1.setAttribute("y1", p1.y);
l1.setAttribute("y2", p2.y);
<svg viewBox = "0 0 200 100" xmlns = "http://www.w3.org/2000/svg">
<marker id = "mk" viewBox = "0 0 4 4" markerWidth = "4" markerHeight = "4" refX = "4" refY = "2" orient = "auto">
<polygon points = "0,0 4,2 0,4" />
</marker>
<ellipse cx = "20" cy = "50" rx = "10" ry = "5" />
<ellipse cx = "120" cy = "20" rx = "10" ry = "5" />
<line id = "l1" stroke = "black" marker-end = "url(#mk)" />
</svg>
Это здорово, именно то, что я искал! Я удивлен, что математика настолько проста. Кажется, что стрелка не исходит из центра исходного эллипса и не указывает на центр целевого эллипса. Вместо этого кажется, что стрелка соединяет один из фокусов каждого эллипса. Это на самом деле лучше для моей цели. Спасибо!