问题描述
const coords = [{x:10,y:20},{x:5,y:6},{x:1,y:25},{x:11,y:2}];
我想知道是否有一种方法可以仅计算这些坐标来计算边框的宽度和高度?
解决方法
使用map()
函数将输入数组转换为x
或y
值的数组。然后,您可以将这些转换后的数组馈送到Math.min()
和Math.max()
以获得left
,right
,bottom
和top
来计算{{1 }}。当您使用bounding box
时,宽度和高度的计算就很简单(将最大值减去最小值)。请参见下面的代码段。
bounding box
,
我想这就是x
(宽度)和y
(高度)的最小值和最大值之间的差。
虽然obvious way似乎在提取的坐标数组上使用Math.max()
/ Math.min()
来计算那些值,但是它需要不必要地循环源数组几次,而单遍处理(例如Array.prototype.reduce()
)足够了,并且在输入数组相对较大时可以执行noticeably faster:
const points = [{x:10,y:20},{x:5,y:6},{x:1,y:25},{x:11,y:2}],{width,height} = points.reduce((acc,{x,y}) => {
const {min,max} = Math
if(!acc.mX || x < acc.mX){
acc.mX = x
} else if (!acc.MX || x > acc.MX){
acc.MX = x
}
if(!acc.mY || y < acc.mY){
acc.mY = y
} else if (!acc.MY || y > acc.MY){
acc.MY = y
}
acc.width = acc.MX - acc.mX
acc.height = acc.MY - acc.mY
return acc
},{width: 0,height: 0})
console.log(`width: ${width}; height: ${height}`)
,
看看这个片段。猜猜这是一个开始的方法。
一些解释:
我们正在根据使用Math.operationMinOrMax(...coords.map(c => c.propertyXorY))
的坐标集计算minX,maxX,minY和maxY值。
- 边界框( =>左角)的min-x坐标是minX值。
- 边界框( => top )的min-y坐标是minY值。
- 边界框( =>右角)的max-x坐标是maxX值。
- 边界框( => bottom )的max-y坐标是maxY值。
大小(属性 w 和 h )可以通过减去maxX - minX
和maxY - minY
来计算。
const boundingBox = (coords) => {
const minX = Math.min(...coords.map(c => c.x)),maxX = Math.max(...coords.map(c => c.x));
const minY = Math.min(...coords.map(c => c.y)),maxY = Math.max(...coords.map(c => c.y));
return {
x: minX,y: minY,w: maxX - minX,h: maxY - minY
}
}
console.log(
boundingBox( [ {x:10,y:5},{x:100,y:0},y:100},{x:12,y:50},{x:0,{x:27,y:22} ])
);