简体   繁体   中英

Intersection of line from the center of a rectangle

I'm trying to find the co-ordinates of where a line originating from the center a box cuts the box

x1,y1 is the center of the box. x2,y2 is the destination of the line minX is the left edge of the box minY is the bottom of the box maxX is the right side of the box maxY is the top of the box

I'm trying to use the standard y=mx+b equation to see where it cuts

function intersect (x1, y1, x2, y2, minX, minY, maxX, maxY) {
   // Completely outside.   Should not be possible 
   if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY))        return false;    
   var x,y,_x,_y;

var m = (y2 - y1) / (x2 - x1);
var b=y1-m*x1;
if (y2 > y1 && x2 > minX) {
    _x = (maxY-b) / m;
    }   
if (y1 > minY)  {
    _x = (maxY-b) / m;
    }   
if (x1 > minX)  {
    _y = m * (maxX) + b;
    }   

if (x1 > minX)  {
    _y = m * (minX) + b;
    }   
return{_x:_x,_y:_y}

}

I'm doing something wrong as the returned values are way off, but I can't see my mistake.

Try understanding how this works:

function intersect(x1, y1, x2, y2, mixX, minY, maxX, maxY) {
    var point = rectangleIntersect(maxX - x1, maxY - y1, x2 - x1, y2 - y1);
    return point && { x: point.x + x1, y: point.y + y1 };
}

function rectangleIntersect(w, h, x, y) {
    var sx = x > 0 ? 1 : -1;
    var sy = y > 0 ? 1 : -1;

    x *= sx;
    y *= sy;

    if (x < w && y < h) return null;

    var m = x * h;
    var n = y * w;

    if (m < n) w = m / y;
    if (m > n) h = n / x;

    return { x: sx * w, y: sy * h };
}

Notice that I didn't use (minX, minY) at all because it can be derived from (maxX, maxY) and (x1, y1) as follows:

minX = x1 + (x1 - maxX)
minY = y1 + (y1 - maxY)

Hope this helped.


See the demo for yourself:

 var $ = document.getElementById.bind(document); var inputs = ["minX", "minY", "maxX", "maxY", "x2", "y2"].reduce(init, {}); var canvas = document.querySelector("canvas"); var context = canvas.getContext("2d"); var height = canvas.height; var width = canvas.width; var h = height / 2 + 0.5; var w = width / 2 + 0.5; draw(); function init(inputs, name) { var input = inputs[name] = $(name); input.addEventListener("input", handler(input, $(name + "Value"))); return inputs; } function handler(input, output) { output.innerHTML = input.value; return function () { output.innerHTML = input.value; draw(); }; } function draw() { context.clearRect(0, 0, width, height); context.strokeStyle = "#808080"; line(w, 0, w, height); line(0, h, width, h); var ax =+ inputs.minX.value; var ay =+ inputs.minY.value; var bx =+ inputs.maxX.value; var by =+ inputs.maxY.value; var x2 =+ inputs.x2.value; var y2 =+ inputs.y2.value; var minX = Math.min(ax, bx); var minY = Math.min(ay, by); var maxX = Math.max(ax, bx); var maxY = Math.max(ay, by); context.strokeStyle = "#000080"; rect(cx(minX), cy(minY), cx(maxX), cy(maxY)); context.strokeStyle = "#800000"; var x1 = (minX + maxX) / 2; var y1 = (minY + maxY) / 2; line(cx(x1), cy(y1), cx(x2), cy(y2)); var point = intersect(x1, y1, x2, y2, minX, minY, maxX, maxY); if (point) { context.fillStyle = "#008000"; context.strokeStyle = "#008000"; context.beginPath(); context.arc(cx(point.x), cy(point.y), 2, 0, Math.PI * 2); context.stroke(); context.fill(); } } function rect(x1, y1, x2, y2) { line(x1, y1, x1, y2); line(x1, y2, x2, y2); line(x2, y2, x2, y1); line(x2, y1, x1, y1); } function cx(x) { return w + 20 * x; } function cy(y) { return h - 20 * y; } function line(x1, y1, x2, y2) { context.beginPath(); context.moveTo(x1, y1); context.lineTo(x2, y2); context.stroke(); } function intersect(x1, y1, x2, y2, mixX, minY, maxX, maxY) { var point = rectangleIntersect(maxX - x1, maxY - y1, x2 - x1, y2 - y1); return point && { x: point.x + x1, y: point.y + y1 }; } function rectangleIntersect(w, h, x, y) { var sx = x > 0 ? 1 : -1; var sy = y > 0 ? 1 : -1; x *= sx; y *= sy; if (x < w && y < h) return null; var m = x * h; var n = y * w; if (m < n) w = m / y; if (m > n) h = n / x; return { x: sx * w, y: sy * h }; } 
 html { font-family: monospace; } canvas { border: 1px solid #000000; } table { display: inline-block; vertical-align: top; } 
 <canvas width="400" height="400"></canvas> <table> <tr> <td>min x:</td> <td><input type="range" min="-10" max="10" value="1" id="minX"/></td> <td id="minXValue"></td> </tr> <tr> <td>min y:</td> <td><input type="range" min="-10" max="10" value="1" id="minY"/></td> <td id="minYValue"></td> </tr> <tr> <td>max x:</td> <td><input type="range" min="-10" max="10" value="7" id="maxX"/></td> <td id="maxXValue"></td> </tr> <tr> <td>max y:</td> <td><input type="range" min="-10" max="10" value="5" id="maxY"/></td> <td id="maxYValue"></td> </tr> <tr> <td>x2:</td> <td><input type="range" min="-10" max="10" value="0" id="x2"/></td> <td id="x2Value"></td> </tr> <tr> <td>y2:</td> <td><input type="range" min="-10" max="10" value="0" id="y2"/></td> <td id="y2Value"></td> </tr> </table> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM