Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><a href="http://jsbin.com/ipifat/7/edit#javascript,live" rel="nofollow noreferrer">tl;dr -> Look at the jsbin code-example</a></p> <p>It is our goal to draw a line from the edges of two Rectangles A &amp; B that would be drawn through their centers. Therefore we'll have to determine where the line <em>pierces</em> through the edge of a Rect. We can assume that our <code>Rect</code> is an object containing <code>x</code> and <code>y</code> as offset from the upper left edge and <code>width</code> and <code>height</code> as dimension offset.</p> <p><img src="https://i.stack.imgur.com/sWGb1.png" alt="different rectangles"></p> <p>This can be done by the following code. The Method you should look at closely is <code>pointOnEdge</code>.</p> <pre><code>// starting with Point and Rectangle Types, as they ease calculation var Point = function(x, y) { return { x: x, y: y }; }; var Rect = function(x, y, w, h) { return { x: x, y: y, width: w, height: h }; }; var isLeftOf = function(pt1, pt2) { return pt1.x &lt; pt2.x; }; var isAbove = function(pt1, pt2) { return pt1.y &lt; pt2.y; }; var centerOf = function(rect) { return Point( rect.x + rect.width / 2, rect.y + rect.height / 2 ); }; var gradient = function(pt1, pt2) { return (pt2.y - pt1.y) / (pt2.x - pt1.x); }; var aspectRatio = function(rect) { return rect.height / rect.width; }; // now, this is where the fun takes place var pointOnEdge = function(fromRect, toRect) { var centerA = centerOf(fromRect), centerB = centerOf(toRect), // calculate the gradient from rectA to rectB gradA2B = gradient(centerA, centerB), // grab the aspectRatio of rectA // as we want any dimensions to work with the script aspectA = aspectRatio(fromRect), // grab the half values, as they are used for the additional point h05 = fromRect.width / 2, w05 = fromRect.height / 2, // the norm is the normalized gradient honoring the aspect Ratio of rectA normA2B = Math.abs(gradA2B / aspectA), // the additional point add = Point( // when the rectA is left of rectB we move right, else left (isLeftOf(centerA, centerB) ? 1 : -1) * h05, // when the rectA is below (isAbove(centerA, centerB) ? 1 : -1) * w05 ); // norm values are absolute, thus we can compare whether they are // greater or less than 1 if (normA2B &lt; 1) { // when they are less then 1 multiply the y component with the norm add.y *= normA2B; } else { // otherwise divide the x component by the norm add.x /= normA2B; } // this way we will stay on the edge with at least one component of the result // while the other component is shifted towards the center return Point(centerA.x + add.x, centerA.y + add.y); }; </code></pre> <p>I wrote a <a href="http://jsbin.com/ipifat/7/edit#javascript,live" rel="nofollow noreferrer">jsbin</a>, you can use to test with some boxes (lower part, in the ready method):</p> <p>You might want to take a look at <a href="https://github.com/Tharabas/NativeJS/blob/master/src/Geometry.js" rel="nofollow noreferrer">a little Geometry helper</a> I wrote some time ago on top of <a href="http://www.prototypejs.org/" rel="nofollow noreferrer">prototype.js</a></p> <p>I really hope, that this helps you with your problem ;)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload