简体   繁体   English

如何计算视口对齐的多边形边界框?

[英]How to calculate viewport aligned polygon bounding box?

I have a problem with bounding box points calculation.我在计算边界框点时遇到问题。 I'm using three.js to render polygons, it's basically 2D with orthographic camera.我正在使用 three.js 来渲染多边形,它基本上是带有正交相机的 2D。 Unfortunately, simple bounding box calculation - iterate over points and get extreme values doesn't work correctly after camera is rotated.不幸的是,简单的边界框计算 - 迭代点并获取极值在相机旋转后无法正常工作。 It stays aligned to axes.它与轴保持对齐。 I'd like bounding box to be aligned to a viewport (just like in the picture below).我希望边界框与视口对齐(如下图所示)。 It can be rotated by any angle, has to be always aligned to a viewport.它可以旋转任何角度,必须始终与视口对齐。

I added an example below - how to calculate points of the bounding box on the right?我在下面添加了一个示例 - 如何计算右侧边界框的点?

Image description: left - trivial bounding box without rotation, middle - axis aligned bounding box, right - desired result - viewport aligned bounding box图像描述:左 - 无旋转的普通边界框,中 - 轴对齐边界框,右 - 期望结果 - 视口对齐边界框

Fiddle producing middle case: https://jsfiddle.net/tqrc2ue6/5/ Fiddle 生产中间件: https://jsfiddle.net/tqrc2ue6/5/

var camera, scene, renderer, geometry, material, line, axesHelper, boundingBoxGeometry, boundingBoxLine;

const polygonPoints = [{
    x: 10,
    y: 10,
    z: 0
  },
  {
    x: 15,
    y: 15,
    z: 0
  },
  {
    x: 20,
    y: 10,
    z: 0
  },
  {
    x: 25,
    y: 20,
    z: 0
  },
  {
    x: 15,
    y: 20,
    z: 0
  },
  {
    x: 10,
    y: 10,
    z: 0
  },
]


function getBoundingBoxGeometry(geometry) {
  geometry.computeBoundingBox();
  const boundingBox = geometry.boundingBox;
  const boundingBoxPoints = [{
      x: boundingBox.min.x,
      y: boundingBox.min.y,
      z: 0
    },
    {
      x: boundingBox.max.x,
      y: boundingBox.min.y,
      z: 0
    },
    {
      x: boundingBox.max.x,
      y: boundingBox.max.y,
      z: 0
    },
    {
      x: boundingBox.min.x,
      y: boundingBox.max.y,
      z: 0
    },
    {
      x: boundingBox.min.x,
      y: boundingBox.min.y,
      z: 0
    },
  ];
  return new THREE.BufferGeometry().setFromPoints(boundingBoxPoints);
}

init();
animate();


function init() {

  scene = new THREE.Scene();
  axesHelper = new THREE.AxesHelper(10);
  scene.add(axesHelper);
  //camera = new THREE.OrthographicCamera(-25, 25, -25, 25, -1, 1);
  //camera.position.set(15, 15)
  //camera.rotation.z = -Math.PI / 4
  var frustumSize = 50
  var aspect = window.innerWidth / window.innerHeight;

  camera = new THREE.OrthographicCamera(frustumSize * aspect / -2, frustumSize * aspect / 2, frustumSize / 2, frustumSize / -2, -1, 1);
  //camera.rotation.z = 2 * Math.PI /3
  camera.rotation.z = 3 * Math.PI / 4
  camera.position.set(15, 15)
  scene.add(camera);

  geometry = new THREE.BufferGeometry().setFromPoints(polygonPoints);
  boundingBoxGeometry = getBoundingBoxGeometry(geometry);

  material = new THREE.LineBasicMaterial({
    color: 0xffffff
  });

  line = new THREE.Line(geometry, material);
  scene.add(line);

  boundingBoxLine = new THREE.Line(boundingBoxGeometry, material)
  scene.add(boundingBoxLine);


  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);

  document.body.appendChild(renderer.domElement);

}

function animate() {

  requestAnimationFrame(animate);
  render();

}

function render() {

  renderer.render(scene, camera);

}

The left figure is obtained by computing the bounding box of the original coordinates.左图是通过计算原始坐标的边界框得到的。

The right figure is obtained by computing the bounding box of the rotated coordinates.右图是通过计算旋转坐标的边界框得到的。

The central figure is obtained by computing the bounding box in the original coordinates and applying the rotation to the corners.中心图形是通过计算原始坐标中的边界框并将旋转应用于角点而获得的。 It is no more axis aligned wrt the original coordinates.它不再与原始坐标轴对齐。

Yves explained the concept. Yves 解释了这个概念。 You need to convert points from one coordinate system to another to solve this.您需要将点从一个坐标系转换到另一个坐标系才能解决这个问题。 But since it's an orthographic view, you can also use camera projection for conversions.但由于它是正交视图,您还可以使用相机投影进行转换。

In this way, we project all the points to the screen coordinate system, we calculate the position of the box in this coordinate, and then we unproject the points of the box to the world coordinate system.这样我们把所有的点project到屏幕坐标系,我们计算出盒子在这个坐标下的unproject ,然后我们把盒子的点反投影到世界坐标系。

I updated your sample to demonstrate this.更新了您的样本以证明这一点。 Just keep in mind that width and height of this rectangle are valid only if view direction be parallel to one of the X, Y or Z axes.请记住,仅当视图方向平行于 X、Y 或 Z 轴之一时,此矩形的宽度和高度才有效。

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM