Converting a 3D Position to its Corresponding 2D Screen Position in Three.js

I'm trying to figure out how to calculate the screen position (x,y) of a 3D object with the coordinates (x, y, z). I've researched and found one solution that involves finding the projection matrix and multiplying the 3D position by it to project onto a 2D viewing surface (such as a computer screen). However, I'm unsure of how to locate this matrix in Three.js.

I attempted to use a conversion function like the one below, but it yielded incorrect results:

function Point3DToScreen2D(point3D){
            var screenX = 0;
            var screenY = 0;
            var inputX = point3D.x - camera.position.x;
            var inputY = point3D.y - camera.position.y;
            var inputZ = point3D.z - camera.position.z;
            var aspectRatio = renderer.domElement.width / renderer.domElement.height;
            screenX = inputX / (-inputZ * Math.tan(camera.fov/2));
            screenY = (inputY * aspectRatio) / (-inputZ * Math.tan(camera.fov / 2));
            screenX = screenX * renderer.domElement.width;
            screenY = renderer.domElement.height * (1-screenY);
            return {x: screenX, y: screenY};
        }

Any help would be greatly appreciated!

Answer №1

Here is a successful function I used with Three.js version 69:

function generatePosition(xPos, yPos, zPos, cameraObj, widthVal, heightVal) {
        var point = new THREE.Vector3(xPos, yPos, zPos);
        var calculatedVector = point.project(cameraObj);

        calculatedVector.x = (calculatedVector.x + 1) / 2 * widthVal;
        calculatedVector.y = -(calculatedVector.y - 1) / 2 * heightVal;

        return calculatedVector;
    }

Answer №2

This is the final code snippet I used to accomplish the task:

Note: The 'div' parameter represents a canvas DOM element.

function convertToScreenCoordinates(position, camera, div) {
    var pos = position.clone();
    projScreenMat = new THREE.Matrix4();
    projScreenMat.multiply(camera.projectionMatrix, camera.matrixWorldInverse);
    projScreenMat.multiplyVector3(pos);

    var offset = calculateOffset(div);

    return { 
        x: (pos.x + 1) * div.width / 2 + offset.left,
        y: (-pos.y + 1) * div.height / 2 + offset.top
    };
}

function calculateOffset(element) { 
    var pos = new Object();
    pos.left = pos.top = 0;        
    if (element.offsetParent) { 
        do { 
            pos.left += element.offsetLeft; 
            pos.top += element.offsetTop; 
        } while (element = element.offsetParent); 
    }
    return pos;
} 

Answer №3

To access more information, you can view the original content on the demonstration:

One key element to focus on is the THREE.Projector() object; this tool allows for the automation of calculations that generate rays based on the position of the mouse cursor on the screen and then project it onto the scene.

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

JavaScript is able to retrieve form fields on the frontend and store them as an array

I've created an HTML form with multiple inputs that share the same name. I'm looking to extract all the values from these fields using JavaScript and store them in an array. <form id="myForm"> <table class="table" ...

JavaScript code that is condensed for efficiency without sacrificing readability and maintainability

As a novice in the world of javascript, I find that studying pre-existing code helps me learn a great deal. I've encountered some extensive javascript projects with minified code that becomes almost indecipherable when expanded. Most variables and f ...

Uploading files with jQuery using Rails and CarrierWave with Amazon S3 storage

I'm relatively new to using jquery file uploading plugins and libraries. Currently, I am working on developing an image uploader that can load images via jquery/ajax on the frontend without requiring a site update as the image is uploaded. Then, I ne ...

How can I implement a promise loop in Angular that continues until it encounters a rejection?

My goal is to efficiently load around 10000 resources, but loading them all at once during the resolve phase is taking too long due to some calculations. I then had the idea to load the resources page by page sequentially, however, since all resources need ...

Using React.js to add MongoDB documents into the database

Is there a way to directly insert documents into a MongoDB collection from a React component? I have been working on a personal project, which is a chat web application used for training purposes. For instance, when a user wants to post a new message in a ...

Click outside to toggle dropdown and hide it

My dropdown menu is currently working, but I would like it to close when I click outside of it. I've tried various solutions provided in other posts, but I just can't seem to get it right. Can someone please help me figure out what I am missing? ...

Having Trouble with the Back Button Functionality

Here is the code snippet I am currently using to create a "Back" button: <INPUT type="button" value="Button" onclick="window.history.back(); return true;"> The issue I am facing is that on the previous page, there are two div elements. Initially, d ...

Issue with the transparency of a model in three.js

Exploring my journey with Three.js, I have been actively engaging in online communities like Stack Overflow to enhance my skills. This project serves as my inaugural experiment with loading OBJ and MTL files. However, an issue has surfaced - certain parts ...

Tips for updating a specific section of a Django webpage using AJAX

Currently, I am in the process of launching a website using Django. One crucial application on this site is the 'forum' which facilitates discussions among users. The discussion forum can be accessed through the URL 'XXX.com/forum/roomY&apo ...

AngularJS: Enhancing User Experience by Preserving View State and Setup through Routes

Is it possible in a single page application to switch back and forth between AngularJS routes while maintaining the same state? Traditionally, this would involve binding data in a parent scope. However, for views with extensive graphical elements, this me ...

The lookat() function in three.js isn't functioning according to my requirements

Here is the code snippet I am working with: http://codepen.io/usf/pen/pGscf This is the specific section of interest: function animate() { //sun.rotation.x = t/1000; sun.rotation.y += 0.01; t += 0.1; earth.position.x = Math.sin((2*Ma ...

Ways to extract data from an array nested within a JSON object

I am seeking guidance on how to access the value of "result 2" from my JSON object using jQuery or pure JavaScript. var jsonarray = [{ title: "Category1", items: [{ result: "Item1", //Nested array items2: [{ //How to get the value o ...

Using ng-init to pass a JSON object

I'm attempting to pass a JSON Object to my application using ng-init and the stringify method, but I am encountering an error. Instead of working as expected, I am getting a Lexer error. Lexer Error: Unexpected next character at columns 8-8 [#] in ex ...

Form with several file selection points

I am working on an application that features a dynamic form capable of uploading files to different individuals simultaneously. Each person is assigned a unique input file and has the option to add up to 2 additional dynamic inputs. <div id="InputsWra ...

Having trouble with Isomorphic fetch not functioning properly for external requests?

EDIT: I am trying to determine why the response does not include the requested data and whether it is due to missing libraries or the format of my fetchUrl variable. Hello, I am attempting to utilize the isomorphic fetch method for making AJAX requests bu ...

There seems to be an issue with jQuery DataTables datetime-moment's date parsing functionality, as it is not

Having trouble parsing dates into MMMM YYYY format using the jQuery DataTables plugin. Check out my Plunker. I've tried using the datetime-moment.js plugin with no success. Here's the code snippet I'm working with: $(document).ready(functio ...

Searching for the location of a specific item within an array using

Trying to grasp the fundamental components of Javascript has led me to stumble upon a specific line of code: if (varX.indexOf(String(varY),0) < 0) In this scenario, varX represents an array of Strings and varY is one of the strings contained within th ...

Issue in Wordpress: ReferenceError - '$' is not defined

Currently utilizing WordPress and attempting to access the following code snippet. I am encountering an error on the last line }(jQuery)); (function($) { $(function () { // Slideshow 3 $("#slider3").responsiveSlides({ auto: true, pag ...

Yeoman Error: Issue with 'mkdir' in Javascript Execution

Currently, I am in the process of setting up a Meanjs instance using a Yeoman generator. However, when I execute 'sudo yo meanjs', everything goes smoothly until an issue arises while attempting to create a directory and it fails. Any insights on ...

Is it possible that following or unfollowing a user through Ajax can result in the href attribute of other links changing? Check out the

Attempting to clarify a peculiar situation with as much detail as possible. Attached are images/examples. A specific page is dedicated to displaying all the users a particular user follows. users_controller.rb def following @pals = current_user.followi ...