【问题标题】:Intersection of line from the center of a rectangle直线与矩形中心的交点
【发布时间】:2014-12-06 22:00:37
【问题描述】:

我正在尝试找到一条从盒子中心开始的线切割盒子的坐标

x1,y1 是框的中心。 x2,y2 是行的目的地 minX 是框的左边缘 minY 是盒子的底部 maxX 是框的右侧 maxY 是框的顶部

我正在尝试使用标准的 y=mx+b 方程来查看它在哪里切割

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}

}

我做错了,因为返回的值很远,但我看不到我的错误。

【问题讨论】:

  • 您检查条件x1 &gt; minX 两次,如果为真,两个条件块将不同 值分配给_y(因此第二个块将覆盖第一个块的分配)。我想这不是故意的?
  • 是的,那是错误的,但即使将其更改为 (x1

标签: javascript math graphics graph raphael


【解决方案1】:

尝试了解其工作原理:

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 };
}

请注意,我根本没有使用(minX, minY),因为它可以从(maxX, maxY)(x1, y1) 派生如下:

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

希望这会有所帮助。


亲自观看演示:

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>

【讨论】:

  • 谢谢!你不知道我已经尝试了多少天来让它发挥作用!
  • 我加了一个demo给你看看。
猜你喜欢
  • 2014-06-09
  • 1970-01-01
  • 2012-07-23
  • 2012-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多