Canvas绘制嵌套多边形:如何保持内部多边形比例不拉伸
解决Canvas同时绘制多个多边形时比例失真的问题
问题根源
当前的drawParcel函数每次调用都会基于单个多边形的边界独立计算缩放比例和中心点,导致第二个较小的多边形被单独拉伸至画布尺寸,破坏了相对比例。要保持所有多边形的比例一致,必须基于所有待绘制多边形的整体边界来计算统一的缩放和偏移参数。
解决方案
步骤1:计算所有多边形的整体边界
编写辅助函数遍历所有多边形的顶点,找出全局的最小/最大X、Y坐标,确定所有图形的整体覆盖范围。
步骤2:使用统一参数绘制所有多边形
基于整体边界计算统一的缩放比例和中心点偏移量,所有多边形都使用这套参数进行坐标转换,确保相对大小和位置不变。
修改后的代码实现
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 getCombinedBounds(polygons) { let minX = Infinity, minY = Infinity; let maxX = -Infinity, maxY = -Infinity; polygons.forEach(points => { points.forEach(([x, y]) => { minX = Math.min(minX, x); minY = Math.min(minY, y); maxX = Math.max(maxX, x); maxY = Math.max(maxY, y); }); }); return { minX, minY, maxX, maxY }; } // 统一绘制所有多边形 function drawAllParcels(polygons, canvasId) { const canvas = document.getElementById(canvasId); const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); // 清空画布 const { minX, minY, maxX, maxY } = getCombinedBounds(polygons); const mapWidth = maxX - minX; const mapHeight = maxY - minY; const mapCenterX = (maxX + minX) / 2; const mapCenterY = (maxY + minY) / 2; // 基于整体边界计算统一缩放比例 const scale = Math.min(canvas.width / mapWidth, canvas.height / mapHeight); // 绘制每个多边形 polygons.forEach(points => { ctx.beginPath(); points.forEach(([x, y]) => { ctx.lineTo( (x - mapCenterX) * scale + canvas.width / 2, (y - mapCenterY) * scale + canvas.height / 2 ); }); ctx.stroke(); }); } // 使用示例:传入所有多边形数组和画布ID drawAllParcels([myPoints, mypointsmall], 'yourCanvasId');
关键说明
getCombinedBounds函数遍历所有多边形的顶点,获取覆盖所有图形的最小矩形边界。drawAllParcels基于整体边界计算缩放比例,确保所有图形都能适配画布且保持相对大小。- 所有多边形使用相同的坐标转换公式,保证它们在画布上的相对位置和比例与原始数据一致。
内容的提问来源于stack exchange,提问作者zizu 112233
相关产品推荐
相关产品推荐

