简体   繁体   English

找到最接近矩形点的边缘

[英]Find closest edge to a point of a rectangle

I'm trying to achieve something on JS which probably is not that hard, but not for my brain, unfortunately.不幸的是,我正在尝试在 JS 上实现一些可能并不难的东西,但对我的大脑来说却不是。

I have 4 arrays which are corners forming a rectangle in two-dimensional space.我有 4 个数组,它们是在二维空间中形成矩形的角。

var corner1 = [x, y];
var corner2 = [x, y];
var corner3 = [x, y];
var corner4 = [x, y];

I have a point which is inside that rectangle (I don't have to check that).我在那个矩形内有一个点(我不必检查它)。

var point = [x, y]

I need to find the closest location to that point which is just next to the closest edge.我需要找到离最近边缘最近的那个点的最近位置。

Here is a picture which describes better what I want to achieve.这是一张更好地描述了我想要实现的目标的图片。

在此处输入图像描述

You can use a formula to get the closest point on a line, and repeat it for the four sides of the rectangle.您可以使用公式来获取一条直线上的最近点,然后对矩形的四个边重复该公式。 Then pick the one that is closest.然后选择最接近的那个。

Here is a snippet that defines a rectangle (hard-coded), draws it, and then captures the mouse position as the "my point" in your question.这是一个片段,它定义了一个矩形(硬编码),绘制它,然后将鼠标位置捕获为您问题中的“我的观点”。 The formula is used to calculate the closest position on the rectangle and draws it as a red point:该公式用于计算矩形上最近的位置并将其绘制为红色点:

 // Utility functions for vectors const squaredSize = v => v[0]**2 + v[1]**2; const sub = (v, w) => [v[0] - w[0], v[1] - w[1]]; const add = (v, w) => [v[0] + w[0], v[1] + w[1]]; const mul = (v, k) => [v[0]*k, v[1]*k]; const squaredDistance = (a, b) => squaredSize(sub(a, b)); const dot = (v, w) => v[0]*w[0] + v[1]*w[1]; function closestPointOnLine(a, b, p) { const ap = sub(p, a); const ab = sub(b, a); return add(a, mul(ab, dot(ap, ab) / squaredSize(ab))); } function closestPointOnPoly(poly, p) { const points = poly.map((a, i) => closestPointOnLine(a, rect[(i + 1)%4], p)); const dists = points.map(q => squaredDistance(p, q)); return points[dists.indexOf(Math.min(...dists))]; } // I/O management const canvas = document.querySelector("canvas"); const ctx = canvas.getContext("2d"); const rect = [[30, 10], [130, 30], [121, 60], [21, 40]]; drawPoly(rect); document.addEventListener("mousemove", function (e) { const p = [e.clientX, e.clientY]; const closest = closestPointOnPoly(rect, p); render(rect, closest); }); function render(poly, point) { ctx.clearRect(0, 0, canvas.width, canvas.height); drawPoly(poly); drawPoint(point); } function drawPoly(points) { ctx.moveTo(...points.at(-1)); for (let p of points) ctx.lineTo(...p); ctx.stroke(); } function drawPoint(point) { ctx.beginPath(); ctx.arc(...point, 2, 0, 2 * Math.PI, true); ctx.fillStyle = "red"; ctx.fill(); }
 html, body { margin: 0 }
 <canvas></canvas>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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