【发布时间】:2018-09-06 09:17:00
【问题描述】:
对于我正在构建的游戏,我需要在由两个坐标组成的线的两侧绘制一个矩形。
我有一张图片说明了这个“很难问”的问题。
给定坐标 (-4,3) 和 (3, -4) 假设矩形的宽度为 4(例如) 我需要找到所有 (x1, y1), (x2, y2), (x3, y3), (x4, y4)
** 我最终需要用 Javascript 编写这个。
【问题讨论】:
标签: javascript math geometry
对于我正在构建的游戏,我需要在由两个坐标组成的线的两侧绘制一个矩形。
我有一张图片说明了这个“很难问”的问题。
给定坐标 (-4,3) 和 (3, -4) 假设矩形的宽度为 4(例如) 我需要找到所有 (x1, y1), (x2, y2), (x3, y3), (x4, y4)
** 我最终需要用 Javascript 编写这个。
【问题讨论】:
标签: javascript math geometry
我尝试使用 javascript 和 canvas 来解决这个问题。问题是画布中的坐标是颠倒的,我想你已经知道了。此外,由于您的矩形非常小,我将您的数字乘以 10。
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
let cw = canvas.width = 300,
cx = cw / 2;
let ch = canvas.height = 300,
cy = ch / 2;
const rad = Math.PI / 180;
ctx.translate(cx,cy)
//axis
ctx.strokeStyle = "#d9d9d9";
ctx.beginPath();
ctx.moveTo(-cx,0);
ctx.lineTo(cx,0);
ctx.moveTo(0,-cy);
ctx.lineTo(0,cy);
ctx.stroke();
// your data
let p1={x:-40,y:30};
let p2={x:30,y:-40};
// the angle of the initial line
let angle = Math.atan2(p2.y-p1.y, p2.x-p1.x);
// the center of the line
let c =
{ x: p1.x + (p2.x - p1.x)/2,
y: p1.y + (p2.y - p1.y)/2
}
let w = dist(p1, p2);//the width of the rect
let h = 60;//the height of the rect
// draw the initial line
line(p1,p2);
// draw the center as a red point
marker(c);
// calculate the opoints of the rect
function rectPoints(w,h){
let p1 = {
x : c.x -w/2,
y : c.y -h/2
}
let p2 = {
x : c.x + w/2,
y : c.y -h/2
}
let p3 = {
x : c.x + w/2,
y : c.y +h/2
}
let p4 = {
x : c.x -w/2,
y : c.y +h/2
}
// this rotate all the points relative to the center c
return [
rotate(p1,c, angle),
rotate(p2,c, angle),
rotate(p3,c, angle),
rotate(p4,c, angle)
]
}
// draw the rect
ctx.strokeStyle = "blue";
drawRect(rectPoints(w,h));
// some helpful functions
function line(p1,p2){
ctx.beginPath();
ctx.moveTo(p1.x,p1.y);
ctx.lineTo(p2.x,p2.y);
ctx.stroke();
}
function dist(p1, p2) {
let dx = p2.x - p1.x;
let dy = p2.y - p1.y;
return Math.sqrt(dx * dx + dy * dy);
}
function marker(p,color){
ctx.beginPath();
ctx.fillStyle = color || "red";
ctx.arc(p.x,p.y,4,0,2*Math.PI);
ctx.fill();
}
function rotate(p,c, angle){
let cos = Math.cos(angle);
let sin = Math.sin(angle);
return {
x: c.x + (p.x - c.x) * cos - (p.y - c.y) * sin,
y: c.y + (p.x - c.x) * sin + (p.y - c.y) * cos
}
}
function drawRect(points){
ctx.beginPath();
ctx.moveTo(points[0].x,points[0].y);
ctx.lineTo(points[1].x,points[1].y);
ctx.lineTo(points[2].x,points[2].y);
ctx.lineTo(points[3].x,points[3].y);
ctx.lineTo(points[0].x,points[0].y);
ctx.closePath();
ctx.stroke();
}
canvas{border:1px solid #d9d9d9}
<canvas></canvas>
【讨论】:
点A、B构成向量
M.X = B.X - A.X
M.Y = B.Y - A.Y
垂直向量
P.X = -M.Y
P.Y = M.X
P的长度:
Len = Math.sqrt(P.X*P.X + P.Y*P.Y)
归一化(单位)垂直:
uP.X = P.X / Len
uP.Y = P.Y / Len
积分
X1 = A.X + uP.X * HalfWidth
Y1 = A.Y + uP.Y * HalfWidth
(X4, Y4) = (A.X - uP.X * HalfWidth, A.Y - uP.Y * HalfWidth)
and similar for points 2 and 3 around B
【讨论】: