javascript - 获取矩形的 Angular 点

标签 javascript math trigonometry

我得到了一个矩形的点数组,从左上角位置到每个 Angular 顺时针排序。我需要找到从矩形的 Angular 到每条边的每个特定 Angular 长度的线的起点和终点。我的代码将点旋转一些随机 Angular 只是为了说明问题,但在我的实际场景中,我只有 Angular 点,需要起点和终点来绘制每个 Angular 。我目前正在偏移每个点,就好像使用方向值数组的点在矩形未旋转时与数组中点的顺序匹配,但它不起作用,因为可以在该点旋转点顺序也会改变。我确信我无法掌握正弦和余弦的应用。如何获得每个 Angular 点的值,该值向其每条边偏移给定的长度,以便所有东西都均匀地一起旋转?

function rotate(cx, cy, x, y, angle) {
    var radians = (Math.PI / 180) * angle,
        cos = Math.cos(radians),
        sin = Math.sin(radians),
        nx = (cos * (x - cx)) + (sin * (y - cy)) + cx,
        ny = (cos * (y - cy)) - (sin * (x - cx)) + cy;
    return {x: nx, y: ny};
}

const colors =["red","blue", "green","black"];
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
let centroid = {};
let points = [{x:30,y:30},{x:110, y:30},{x:110,y:110},{x:30, y:110}];

function update() {
  const randAngle = Math.random() * 180 * (Math.random() > 0.5 ? -1:1);
  const length = points.length;
    centroid = points.reduce((last, current)=> {
    last.x += current.x / length;
    last.y += current.y / length;
    return last;
  }, {x: 0, y:0});  
  points = 
    points.map(point=> rotate(centroid.x, 
                              centroid.y, 
                              point.x, 
                              point.y, 
                              randAngle));
}

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);  
  // draw centroid
  ctx.beginPath();
  ctx.arc(centroid.x, centroid.y, 4, 0, Math.PI * 2); 
  ctx.stroke();
  // draw Square
  ctx.beginPath();
  ctx.moveTo(points[0].x, points[0].y);
  for(let i=1;i<points.length;i++) {    
    ctx.lineTo(points[i].x, points[i].y);
  }
  ctx.closePath();
  ctx.stroke();
  // draw corner points
  for(let i=0;i < points.length;i++) {
    ctx.beginPath();
    ctx.fillStyle = colors[i%colors.length];
    ctx.arc(points[i].x, points[i].y, 3, 0, Math.PI * 2);
    ctx.fill();
  }
  
  const cornerLength = 10;
  const startPointDirections = [{ x: 0, y: 1 },
{ x: -1, y: 0 },
{ x: 0, y: -1 },
{ x: 1, y: 0 }];

const endPointDirections = [{ x: 1, y: 0 },
{ x: 0, y: 1 },
{ x: -1, y: 0 },
{ x: 0, y: -1 }];
  // draw corner start points and endpoints
  for(let i=0;i < points.length;i++) {
    ctx.beginPath();
    ctx.fillStyle = colors[i%colors.length];    
    ctx.arc(startPointDirections[i].x * cornerLength + points[i].x, startPointDirections[i].y * cornerLength  + points[i].y, 3, 0, Math.PI * 2);
    ctx.arc(endPointDirections[i].x * cornerLength + points[i].x, endPointDirections[i].y * cornerLength  + points[i].y, 3, 0, Math.PI * 2);
    ctx.fill();
    }        
}

setInterval(()=> {
  update(); 
  draw();
}, 2000);
<canvas></canvas>

最佳答案

似乎您需要将rotate函数应用于相对于旋转 Angular 的偏移点,但此时您没有 Angular 值。所以你可以从旋转的边获得方向向量。

enter image description here

function rotate(cx, cy, x, y, angle) {
    var radians = (Math.PI / 180) * angle,
        cos = Math.cos(radians),
        sin = Math.sin(radians),
        nx = (cos * (x - cx)) + (sin * (y - cy)) + cx,
        ny = (cos * (y - cy)) - (sin * (x - cx)) + cy;
    return {x: nx, y: ny};
}

const colors =["red","blue", "green","black"];
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
let centroid = {};
let points = [{x:30,y:30},{x:110, y:30},{x:110,y:110},{x:30, y:110}];

function update() {
  const randAngle = Math.random() * 180 * (Math.random() > 0.5 ? -1:1);
  const length = points.length;
    centroid = points.reduce((last, current)=> {
    last.x += current.x / length;
    last.y += current.y / length;
    return last;
  }, {x: 0, y:0});  
  points = 
    points.map(point=> rotate(centroid.x, 
                              centroid.y, 
                              point.x, 
                              point.y, 
                              randAngle));
}

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);  
  // draw centroid
  ctx.beginPath();
  ctx.arc(centroid.x, centroid.y, 4, 0, Math.PI * 2); 
  ctx.stroke();
  // draw Square
  ctx.beginPath();
  ctx.moveTo(points[0].x, points[0].y);
  for(let i=1;i<points.length;i++) {    
    ctx.lineTo(points[i].x, points[i].y);
  }
  ctx.closePath();
  ctx.stroke();
  // draw corner points
  for(let i=0;i < points.length;i++) {
    ctx.beginPath();
    ctx.fillStyle = colors[i%colors.length];
    ctx.arc(points[i].x, points[i].y, 3, 0, Math.PI * 2);
    ctx.fill();
  }
  
  const cornerLength = 10;
  
  // draw corner start points and endpoints
  for(let i=0;i < points.length;i++) {
    ctx.beginPath();
    ctx.fillStyle = colors[i%colors.length];    
    let dx = points[i].x - points[(i+3)%4].x     //previous index in cyclic manner
    let dy = points[i].y - points[(i+3)%4].y 
    let len = Math.sqrt(dx*dx+dy*dy)   //really you know side length so use known value
    dx = cornerLength * dx/len      //normalized vector multiplied by magnitude
    dy = cornerLength * dy/len
 
    startx = points[i].x  + dx
    starty = points[i].y  + dy

    endx = points[i].x + dy   //here apply rotated by -Pi/2 offset vector 
    endy = points[i].y - dx   

    ctx.arc(startx, starty, 3, 0, Math.PI * 2);
    ctx.arc(endx, endy, 3, 0, Math.PI * 2);
    ctx.fill();
    }        
}

setInterval(()=> {
  update(); 
  draw();
}, 2000);
<canvas></canvas>

(实际上,dx/lendy/len 等于 cos(angle)sin(angle ) 或反之亦然,使用不同的符号组合)

关于javascript - 获取矩形的 Angular 点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70934872/

相关文章:

javascript - 无法在 OpenLayers3 中获取相对 URL

math - 元组关系演算或关系代数语法验证程序?

arrays - 给定一个数组,我能否在 O(n) 中找到最长的范围,其端点是范围内的最大值?

javascript - 将 0 - 1 中的任何数字归一化的函数

ios - 围绕中心质量创建圆形路径的算法?

c++ - KSP DELTA V 查找器 : Why does C++ assume that log( ) is a function?

javascript - JavaScript 中没有参数绑定(bind)

javascript - 使用 Node.js 将图像上传到 AWS S3 存储桶。 JS

Javascript:类型错误混淆

c++ - Matlab三角函数