从坐标数组中绘制多边形内的多边形

问题描述 投票:0回答:1

我有一个 JavaScript 函数,可以在画布上绘制多边形并将其显示在画布上。当我只绘制一个多边形时,我得到预期的结果,它将多边形拉伸到画布的高度和宽度。问题是,如果我在一个画布上绘制两个多边形,第二个变量中包含的较小的多边形将拉伸到最大画布高度和宽度。我如何绘制第一个并保留第二个的比率。





var myPoints = [ [ 9.409270240851829, 47.330314065858211 ], [ 9.409285680358719, 47.330421732544742 ], [ 9.409388568077148, 47.330416591964713 ], [ 9.409454076275221, 47.330412683706811 ], [ 9.409599179371462, 47.330416844605445 ], [ 9.409516164722477, 47.330356713043116 ], [ 9.409412455482686, 47.330279111507451 ], [ 9.409265655950009, 47.330289194938722 ], [ 9.409270240851829, 47.330314065858211 ] ];

var mypointsmall = [ [ 9.409277330768161, 47.330294996637527 ], [ 9.40929555711242, 47.330394995087424 ], [ 9.409449188016863, 47.330385694636568 ], [ 9.409441872135783, 47.330340644668418 ], [ 9.409432145964761, 47.330341377653177 ], [ 9.409430621953572, 47.330332010609965 ], [ 9.409383287787568, 47.330335311475089 ], [ 9.409376169945089, 47.330288098791449 ], [ 9.409349057871147, 47.330289992509627 ], [ 9.409347814140572, 47.330283553765319 ], [ 9.409279252163072, 47.330288260899749 ], [ 9.409281541354549, 47.330294699779891 ], [ 9.409277330768161, 47.330294996637527 ] ] ;

function drawParcel(point,id)
{
var canvas = document.getElementById(id);
var ctx = document.getElementById(id).getContext('2d');
    //ctx = canvas1.getContext("2d");
 
 
var minX,minY,maxX,maxY; 
point.forEach((p,i) => {
   if(i === 0){ // if first point 
      minX = maxX = p[0];
      minY = maxY = p[1]; 
   }else{   
      minX = Math.min(p[0],minX);
      minY = Math.min(p[1],minY);
      maxX = Math.max(p[0],maxX);
      maxY = Math.max(p[1],maxY);
   }
 });
 // now get the map width and heigth in its local coords
 const mapWidth = maxX-minX;
 const mapHeight = maxY-minY;
 const mapCenterX = (maxX + minX) /2;
 const mapCenterY = (maxY + minY) /2;
 
 // to find the scale that will fit the canvas get the min scale to fit height or width
 const scale = Math.min(canvas.width / mapWidth,canvas.height / mapHeight);
 
 // Now you can draw the map centered on the cavas
 ctx.beginPath();
 point.forEach(p => { 
      ctx.lineTo(
          (p[0] - mapCenterX) * scale + canvas.width /2 ,
          (p[1] - mapCenterY) * scale + canvas.height / 2 
      );
 });
 ctx.stroke();
}
javascript canvas
1个回答
0
投票

您当前的函数通过查看您提供的形状中的最小和最大 x 和 y 坐标来计算边界。

如果您已经知道两者中最大的形状是什么,您可以:

  • 使绘制函数仅在未通过参数传递的情况下计算边界
  • 使绘制函数返回它使用的边界
  • 不要将边界传递给第一次调用,存储使用的计算边界
  • 将这些边界传递给第二个调用

运行示例:

var myPoints = [
  [9.409270240851829, 47.330314065858211],
  [9.409285680358719, 47.330421732544742],
  [9.409388568077148, 47.330416591964713],
  [9.409454076275221, 47.330412683706811],
  [9.409599179371462, 47.330416844605445],
  [9.409516164722477, 47.330356713043116],
  [9.409412455482686, 47.330279111507451],
  [9.409265655950009, 47.330289194938722],
  [9.409270240851829, 47.330314065858211]
];

var mypointsmall = [
  [9.409277330768161, 47.330294996637527],
  [9.40929555711242, 47.330394995087424],
  [9.409449188016863, 47.330385694636568],
  [9.409441872135783, 47.330340644668418],
  [9.409432145964761, 47.330341377653177],
  [9.409430621953572, 47.330332010609965],
  [9.409383287787568, 47.330335311475089],
  [9.409376169945089, 47.330288098791449],
  [9.409349057871147, 47.330289992509627],
  [9.409347814140572, 47.330283553765319],
  [9.409279252163072, 47.330288260899749],
  [9.409281541354549, 47.330294699779891],
  [9.409277330768161, 47.330294996637527]
];

const bounds = drawParcel(myPoints, "cvs");
drawParcel(mypointsmall, "cvs", bounds);

function drawParcel(point, id, bounds) {
  var canvas = document.getElementById(id);
  var ctx = canvas.getContext('2d');

  var minX, minY, maxX, maxY;
  
  if (!bounds) {
    point.forEach((p, i) => {
      if (i === 0) { // if first point 
        minX = maxX = p[0];
        minY = maxY = p[1];
      } else {
        minX = Math.min(p[0], minX);
        minY = Math.min(p[1], minY);
        maxX = Math.max(p[0], maxX);
        maxY = Math.max(p[1], maxY);
      }
    });
  } else {
    minX = bounds.minX;
    maxX = bounds.maxX;
    minY = bounds.minY;
    maxY = bounds.maxY;
  }
  
  // now get the map width and heigth in its local coords
  const mapWidth = maxX - minX;
  const mapHeight = maxY - minY;
  const mapCenterX = (maxX + minX) / 2;
  const mapCenterY = (maxY + minY) / 2;

  // to find the scale that will fit the canvas get the min scale to fit height or width
  const scale = Math.min(canvas.width / mapWidth, canvas.height / mapHeight);

  // Now you can draw the map centered on the cavas
  ctx.beginPath();
  point.forEach(p => {
    ctx.lineTo(
      (p[0] - mapCenterX) * scale + canvas.width / 2,
      (p[1] - mapCenterY) * scale + canvas.height / 2
    );
  });
  ctx.stroke();
  
  return { minX, maxX, minY, maxY };
}
<canvas id="cvs" width="480" height="320"></canvas>

© www.soinside.com 2019 - 2024. All rights reserved.