I have a function that moves circles out of the way of an expanding circle. It moves them along a ray from the center of the expanding circle through the center of the circle to move. This allows all surrounding circles to move without overlapping.
Here's a diagram to better explain this:
I expand the size of the red circle from 100px to 200px. I want to move all the blue circles out of the way by half the difference ( (200-100)/2 = 50px, in this example ) along the gray line (with the gray line being different for each blue circle).
$this.siblings( ".circle" ).each( function() {
var $this = $( this ),
circle = $this.data(),
circleX = circle.left + circle.radius,
circleY = circle.top + circle.radius,
a = Math.abs( hoveredY - circleY ),
b = Math.abs( hoveredX - circleX ),
c = Math.sqrt( ( a*a ) + ( b*b ) ),
A = Math.acos( b / c ),
C = 90 * ( Math.PI / 180 ),
B = C - A,
sinA = Math.sin( A ),
sinB = Math.sin( B ),
sinC = Math.sin( C ),
newc = c + ( expand / 2 ),
newa = ( newc * sinA ) / sinC,
newb = ( newc * sinB ) / sinC,
newX = hoveredX + ( hoveredX > circleX ? -newb : newb ),
newY = hoveredY + ( hoveredY > circleY ? -newa : newa ),
left = newX - circle.radius,
top = newY - circle.radius;
$this.animate( {
"left": left,
"top": top
}, 75 );
});
hoveredX
and hoveredY
are the left and top coordinates of the red circle and expand
is how much the red circle is expanding in pixels.
Mathematically, I'm sure there is a better way to do this, but I got this way working, and it's fine (although I'm not opposed hearing better solutions). But the one part I don't like about this function are the two lines:
newX = hoveredX + ( hoveredX > circleX ? -newb : newb ),
newY = hoveredY + ( hoveredY > circleY ? -newa : newa ),
What bugs me is that I'm having to do the check at all. Those two lines are basically saying, "If the circle is on the left/top do it one way, and if it's on the right/bottom do it another way". I feel like I'm missing something earlier in the function that could be solved by switching the sides of operators, adding instead of subtracting, or getting the absolute value.
a = Math.abs(
is why you have to check. Are you sure you need absolute values? \$\endgroup\$