What is the method for determining the bounding box of a polygon aligned to the viewport

I am facing difficulties in calculating bounding box points accurately when using three.js for rendering polygons in a 2D orthographic camera setup. The simple method of iterating over points to find extreme values does not function correctly after the camera has been rotated. It remains aligned with the axes, whereas I require the bounding box to be aligned with a viewport (similar to the illustration below). It should be rotatable at any angle while always staying aligned with the viewport.

I have provided an example below - how can I determine the bounding box points on the right side?

Image description: left - basic bounding box without rotation, middle - axis-aligned bounding box, right - desired output - viewport-aligned bounding box https://i.sstatic.net/xEzEA.png

Fiddle producing the middle case: 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);
  
  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 = 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);

}

Answer №1

The figure on the left is generated by calculating the bounding box of the initial coordinates.

The figure on the right is created by determining the bounding box of the rotated coordinates.

The figure in the center is formed by computing the bounding box using the original coordinates and then rotating the corners accordingly. This results in a figure that is no longer aligned with the axes of the original coordinates.

Answer №2

Yves provided a clear explanation of the concept. To solve this problem, you must convert points from one coordinate system to another. In addition to using orthographic view, you can utilize camera projection for conversions.

By projecting all points onto the screen coordinate system, determining the box's position in this coordinate system, and then unprojecting the box's points back to the world coordinate system, we can effectively solve the task at hand.

I have updated your sample to showcase this process. It is important to note that the width and height of the rectangle are accurate only when the viewing direction is parallel to one of the X, Y, or Z axes.

https://i.sstatic.net/xu1XU.png

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The map markers are nowhere to be found on the map when using Internet Explorer

Take a look at this code I wrote... var styles = [ { "featureType": "landscape", "stylers": [ {"weight": 0.1}, {"color": "#E7EDEF"} ] }, ... { "featureType": "poi.park", "elementType": "labels", "stylers": [ ...

Strategies for improving the efficiency of this loop function?

var tickers = []; for (var i=0; i<reportsArray.length; i++) { tickers.push(reportsArray[i].ticker); } Is there a more efficient way to achieve the same result using lodash library? You can find more information about lodash here. Here is an examp ...

Include an additional image with a JavaScript function

I recently started using a WordPress plugin known as User Submitted Posts. This plugin has the functionality to allow users to upload multiple images. I have configured it so that users can upload anywhere from 0 to a maximum of 3 images. However, when att ...

In the v-bind:Style statement, check the condition

<div> <figure :style="{ 'background': 'url(' + item.main_featured + ') center no-repeat' }"> </div> I need the background style attribute to display a color if the URL fetched from the API is und ...

Tips for ensuring the HTML checkbox element is fully loaded before programmatically selecting it

When a user accesses the page, I want certain checkboxes to be automatically checked. To achieve this, I am storing the IDs of the HTML checkbox elements in a service. Upon entering the page, the service is utilized to retrieve an array containing these ID ...

Utilizing LINQ with a list of AJAX elements for seamless integration with DataTable

Trying to execute a LINQ query to populate an AJAX list, which will then be used in a DataTable within my View. This was previously working without any issues when I wasn't using AJAX. The data was directly placed in the model and each row was render ...

Enable Sound when Hovering over Video in React Next.js

I am currently facing an issue while trying to incorporate a short video within my nextjs page using the HTML tag. The video starts off muted and I want it to play sound when hovered over. Despite my best efforts, I can't seem to get it working prope ...

Encountering issues with pipes and ngModel functionality in Angular causing errors

I have a unique custom dropdown feature that binds the selected dropdown value to an input field in my reactive form using ngModel. I have also implemented a mask on the input fields using a pipe. Here is all the relevant code for this functionality: HTML ...

What's preventing me from tapping on hyperlinks on my mobile device?

I'm currently working on a website (saulesinterjerai.lt) and everything seems to be functioning properly, except for the fact that on mobile devices, the links aren't clickable and instead navigates to other layers. How can I disable this behavio ...

Eliminate the legend color border

I have successfully implemented the following code and it is functioning properly. However, I am trying to remove the black boundary color legend but am struggling to figure out how to do so. var marker = new kendo.drawing.Path({ fill: { co ...

When attempting to perform a second addition operation on the Angular calculator, it fails to work. However, each addition works perfectly when done individually

I have encountered a curious issue with my Angular calculators. Individually, they both function perfectly as intended. However, when I attempt to combine them, one always malfunctions. Is there something crucial that I am overlooking in this scenario? (D ...

Querying MongoDB using JavaScript function

Currently, I am utilizing a MongoDB query within a JavaScript function. The script is structured as follows: var continous = ['b', 'e', 'LBE']; continous.forEach(e => izracun(e)); function izracun(atr) { var query1 = ...

Create an Android application using Node.js

While developing my mobile application, I am utilizing html5 with node.js to create a chat box for users connected on the same wireless network. However, I encounter an issue when coding on my desktop using node.js software. How can I overcome this challen ...

Generate a new TreeView using the checked checkboxes from a current TreeView

I am currently working on implementing a dynamic user access feature for specific nodes within an existing treeview that is also dynamic. The primary TreeView that I am using contains checkboxes and gets populated from a database. Additionally, there is a ...

Guide to making axios/api calls in a Nativescript mobile application

In my development process, I am working on creating a small application using Nativescript-vue. This application requires backend functionality that is built on the laravel framework for making API calls to retrieve relevant data. For example, when a user ...

Ways to rouse a dormant AudioTracks feature

When I click a button, I am able to get the correct value of AudioTracks.length. However, without clicking the button, I am unable to retrieve this value. Take a look at my code below. It works at line (B) but not at (A). Can you help me understand why and ...

Node.js - Error: Undefined:0 SyntaxEncountered an unexpected end of input syntax error

Exploring Node.js and Backbone.js for the first time. Using the book "Backbone Blueprints" but encountering issues with the provided code to set up the webserver. Node.js is installed and running fine. Here's the package.json code: { "name": "simp ...

Updating textbox values with ajax results in the page refreshing and the newly assigned values being lost

I'm currently working on updating a section of my webpage using AJAX instead of C#, as I don't want the page to refresh. All I need to do is execute a SELECT query to retrieve the current client from the SQL database and populate the correspondin ...

Combine various choices into a select dropdown

I am facing an issue with an ajax call in codeigniter where the response always consists of two values: team_id1 and team_id2. Instead of displaying them as separate values like value="1" and value="2", I want to join them together as value="1:2". I have ...

React form input not reflecting changes in API request

I have encountered an issue with using the searchInput state as a variable for the api request in my React application. The button in the return statement is not functioning as expected, as it causes the page to refresh without loading anything. However, ...