Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draw an arrow between two circles?

Tags:

svg

d3.js

How can I draw an arrowed line between two circles, given:

  1. Location of the centers of the cirlces
  2. Radius of the circles

I am using line and marker svg objects.

If I draw the arrows to the "center" of the circle - then the arrow is invisible. If I move the arrow too far back - then the line shows through and hides the pointy end of the arrow (here exaggerated for better visibility): Arrows moved waaaay back

As per request, here is the relevant bits of my code (in livescript):

# Draw an arrow to use for lines
svg.append("svg:defs")
 .append("svg:marker")
  .attr("id", "arrow")
  .attr("viewBox", "0 0 10 10")
  .attr("refX", 27)
  .attr("refY", 5)
  .attr("markerUnits", "strokeWidth")
  .attr("markerWidth", 8)
  .attr("markerHeight", 6)
  .attr("orient", "auto")
  .append("svg:path")
  .attr("d", "M 0 0 L 10 5 L 0 10 z")

svg.append("line")
 .attr "x1" 5 
 .attr "x2" 50 
 .attr "y1" 5 
 .attr "y2" 50
 .style "stroke" "black"
 .attr "stroke-width" 2
 .attr "marker-end" "url(\#arrow)"

Alternatively, here is JSFiddle of the working example (note that the arrows are "fidgeted" to look just right): http://jsfiddle.net/yeQS2/

like image 374
Andriy Drozdyuk Avatar asked Oct 31 '12 19:10

Andriy Drozdyuk


1 Answers

If I understood correctly, you need to find the 2D vector that you need to add to the source to get to the border of the target circle.

Pseudo code:

d = distance between A and B; // (sqrt((xB-xA)² + (yB-yA)²)).
d2 = d - radius;

ratio = d2 / d;

dx = (xB - xA) * ratio;
dy = (yB - yA) * ratio;

x = xA + dx;
y = yA + dy;
like image 131
Joan Charmant Avatar answered Oct 03 '22 00:10

Joan Charmant