Using Three.js to construct a tangent plane at a specific point on a sphere

I am currently working on constructing a tangent plane on the surface of a sphere at a specific point using Three.js (v0.129). The algorithm I have been following is outlined as follows:

  1. Locate the center of the sphere;
  2. Determine the radius vector that intersects the given point;
  3. Calculate the normal vector to the radius vector;
  4. Multiply the radius vector by the normal vector, as their product should yield a vector perpendicular to both;
  5. Identify the endpoints of the product vector and the normal vector to create a plane through those points - this will be the tangent plane.

However, I have encountered an issue where the product vector is not always perpendicular to the radius and the normal vectors. I have attempted to visualize this by drawing lines for each vector, leading to the diagram shown below:

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

My question is: what mistake am I making in my approach? Is there a more effective method for constructing a tangent plane to a sphere at a specified point?

The code snippet I am using is as follows:


const createTangentPlane = (point: THREE.Vector3, sphere: Entity) => {
sphere.object3D.updateMatrixWorld();

sphere.object3D.updateMatrix();

const center = sphere.object3D.position;
const radiusVector = new THREE.Vector3().subVectors(point, center).normalize();
const radiusNormal = radiusVector
    .clone()
    .applyAxisAngle(new THREE.Vector3(0, 0, 1), Math.PI * 0.5)
    .normalize();
const a = radiusNormal.clone().normalize().setLength(10).add(point);
const b = radiusNormal.clone().normalize().negate().setLength(10).add(point);
const orthogonalVector = radiusVector.clone().cross(radiusNormal);
const a1 = orthogonalVector.clone().setLength(10).add(point);
const b1 = orthogonalVector.clone().negate().setLength(10).add(point);

createLine(([a1, b1]);
createLine([a, b]);
createLine([center, point]);

//createPlaneFrom4Points([a, a1, b1, b]);

}

Answer №1

Provided:

  • three.js r130 (however, r129 should work as well)
  • The specific location of the sphere
  • The "contact point" on the surface of the sphere (assuming it is a Vector3)

Assumption:

  • The sphere's position is given in global coordinates
  • The contact point is also specified in global coordinates
let normal = new THREE.Vector3().copy( tangentPoint )
normal.sub( sphere.position ) // eliminate sphere translation

let plane = new THREE.Mesh(
  new THREE.PlaneGeometry( sphere.radius, sphere.radius ),
  new THREE.MeshBasicMaterial( { color: 'red' } )
)
plane.lookAt( normal )
plane.position.copy( tangentPoint )

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

Scanning barcode and Qrcode with Angular js HTML5 for seamless integration

Looking to scan Barcode and Qrcode on Android, iPhone, and iPad devices for a project that is built on AngularJS and HTML5 as a mobile website. The requirement is not to download any third-party native application on the device, ruling out the use of nati ...

Sharing AngularJs controllers between different modules can help streamline your

I'm facing an issue with trying to access an array from one controller in another controller. Despite simplifying the code for clarity, I still can't seem to make it work. Here is my first controller: app.controller('mycont1', [' ...

Creating an HTML5 video tag with bearer authentication using a WebAPI: The ultimate guide

My ASP.NET WebAPI requires bearer authentication, and most of my requests towards the API follow this format: GET http://localhost:29080/api/v1/users/me HTTP/1.1 Host: localhost:29080 Connection: keep-alive Accept: application/json, text/plain, */* Origin ...

setTimeout is only effective for durations less than 1000 milliseconds

I am trying to implement a timeout function that displays an alert two seconds after a form is submitted. The code I have tried using does not seem to be working as expected: $(document).ready(function() { $("#newsletter").submit(function() { setTi ...

What makes the creation of Javascript objects so flexible and dynamic?

Recently, I've been exploring the concept of creating new objects in JavaScript. It's interesting to note that in JS, every object creation is dynamic. This allows you to create an object and then add properties later on. Even fields created in t ...

Implementing a line break within a JavaScript function specifically designed for formatting images

As I am not a javascript developer, the code I have been given for debugging is somewhat challenging. The issue at hand involves an iOS module where a .js CSS file has been set up and images are loading improperly, resulting in the need for horizontal scro ...

Replace the current picture with a newly uploaded one and keep it consistent

On my webpage, there is an image that I want to be able to replace by clicking on it and selecting a new image from the file uploader without showing the upload button. Once the new image is uploaded, I'd like it to replace the current image, and for ...

Encountering a "Window is undefined" error while trying to load a node_module package within a

I am attempting to incorporate the pickr package (a color picker library) into my nuxt.js application. However, I am encountering an error during import, specifically "window is undefined". Below is the code snippet: <script> import Pickr from &apo ...

Tips for creating a fixed footer that adjusts with a flexible wrapper

Feeling incredibly stressed, I embarked on a quest to find the perfect sticky footer. After searching Google for what seemed like an eternity, I came across multiple tutorials recommending the use of min-height:100%. However, this approach caused the wrap ...

What is the best way to save my photo on the server?

Currently, I am developing an application using Phonegap that is specific for Android, iOS, and Windows phone platforms. As part of the app functionality, I am utilizing the Camera API to capture images on the user's device. However, at the moment, th ...

Is there a way to modify the background color of ::before when hovering over it?

I have a ul-li list and when i hover last li ::before element looks white and not so good. I want to change it when i hover the last li element. How can I achieve this? Here are my codes: <div className="dropup-content"> <ul> & ...

Is there a way to find out the ultimate destination of a shortened URL without actually opening the webpage?

I am trying to implement a feature where I can click on links within email messages and have the full link displayed in a separate pane using jQuery. However, I am facing some challenges with this implementation. My plan is to use AJAX to call a PHP scrip ...

Struggling to override a css element in a responsive design

Here is a Link that I am having trouble with. Within my CSS, I have an element named tbox. It functions as an inline box with a width set at 100%. On the homepage, it adjusts its width perfectly based on its parent and is fully responsive. However, when na ...

Clicking on the prop in a React class component

This is the situation I am facing <List> {mainTags.map((mainTagItem) => { return ( <ListItem onClick={() => { setMainTag(mainTagItem.tag.tagId) }} button className={classes.mainTagItem}> <div className={classes. ...

Refreshing a page will disable dark mode

I'm in the process of implementing a dark mode for my website using the code below. However, I've encountered an issue where the dark mode resets when refreshing the page or navigating to a new page. I've heard about a feature called localst ...

Tips for resizing an image to perfectly fit on a compact HTML5 canvas without sacrificing its quality

I need assistance with my code. I'm trying to draw an image on the canvas while maintaining its quality. const canvas = document.getElementById("canvas"); const context = canvas.getContext("2d"); canvas.width = 360px; canvas.height = 360px; const img ...

Ways to retrieve nested data from an object

I have added an object with categories in a database. It displays the price and date of addition. How can I output the date to the console? Currently, in the console, it shows: [ [ { cost: '50$', date: [Object] } ] ]. I need to extract the inform ...

Monitoring alterations in dynamically produced input fields using jQuery

My code currently generates multiple input fields dynamically, each related to a specific database record. I utilize PHP's dynamic array notation ('[]') to store the input values. Everything is working smoothly up to this point... Now, I am ...

What is the best way to incorporate hyperlinks or text color modifications to a variable string in JavaScript?

I have a website that features a random on-load slideshow with text displayed in div containers for each slide. I am looking to enhance the functionality by adding links or changing the color of specific words within the text. You can view my current progr ...

There is a problem with my module where multiple files that require it are overriding its variables

Currently, I am working on developing a mongo connection pool factory that is capable of checking if a connection to mongo already exists. If a connection exists, it will return that connection. However, if there is no existing connection, it will create a ...