I'm trying to programmatically draw an arrow from one ellipse to another, like below. How do I calculate where on ellipse B's edge the arrow needs to point? Or is there an easier way to do this in SVG? I am given the x
and y
coordinates of each ellipse along with their horizontal and vertical radiuses. From those coordinates and radiuses, I need to draw an arrow.
CodePudding user response:
In SVG you can draw an arrow at the end of a line by using a marker.
In order to know the starting and ending points of the line you need to calculate them as points on the ellipse at a given angle.
Please read the comments in the code.
//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>