Having difficulty drawing an arrow connecting one mesh object to the surface of another mesh object

When attempting to draw an arrow from one mesh object to another, I encountered some issues. Directly using the positions of the objects as arguments in the Arrow Helper resulted in the arrow going inside the object due to the position representing the center of the object.

To resolve this, I decided to create objects and utilize raycasting.

var ray = new THREE.Raycaster(sourcePos, direction.clone().normalize());

In this setup, the origin is set as the source object's position and the direction is determined from the source to the target. By intersecting with the target, I obtain collision results:

var collisionResults = ray.intersectObject(target);

The next step involves calculating the distance at which the ray first intersects the target:

var length = collisionResults[0].distance;

Finally, an arrow is created using the calculated values:

var arrow = new THREE.ArrowHelper(direction.clone().normalize(), sourcePos, length, 0xaa0000);
scene.add(arrow);

The arrow creation process works well for certain cases like:

helper_methods.draw_arrow(mesh1, mesh2);
helper_methods.draw_arrow(mesh1, mesh2);

However, when trying to draw an arrow between mesh2 and mesh3:

helper_methods.draw_arrow(mesh2, mesh3);

An error message stating "collisionResults[0] is null" is displayed. I am currently unable to identify the root cause of this issue and would appreciate any assistance. Below is a snippet of the code being used along with the helper methods:


var mesh1 = helper_methods.create_mesh();
mesh1.position.set(100, 0, 0);
scene.add(mesh1);

var mesh2 = helper_methods.create_mesh();
mesh2.position.set(300, 0, 0);
scene.add(mesh2);

var mesh3 = helper_methods.create_mesh();
mesh3.position.set(100, 200, 0);
scene.add(mesh3);

helper_methods.draw_arrow(mesh1, mesh2);
helper_methods.draw_arrow(mesh1, mesh2);
helper_methods.draw_arrow(mesh2, mesh3);

Below are the helper methods used in the code:


create_mesh: function(){
    var darkMaterial = new THREE.MeshBasicMaterial({color: 0xffffcc});
    var geometry = new THREE.CylinderGeometry(30, 30, 50, 100, 1);
    var mesh = new THREE.Mesh(geometry, darkMaterial);
    return mesh;
},

draw_arrow: function(source, target){
    var sourcePos = new THREE.Vector3(source.position.x, source.position.y, source.position.z);
    var targetPos = new THREE.Vector3(target.position.x, target.position.y, target.position.z);
    var direction = new THREE.Vector3().subVectors(targetPos, sourcePos);

    var ray = new THREE.Raycaster(sourcePos, direction.clone().normalize());
    var collisionResults = ray.intersectObject(target);
    var length = collisionResults[0].distance;
    var arrow = new THREE.ArrowHelper(direction.clone().normalize(), sourcePos, length, 0xaa0000);

    scene.add(arrow);
    return arrow;
}

Answer №1

There's a more straightforward approach to accomplishing this.

Technique 1

  1. Your task involves drawing from one specific point on the surface of one mesh to another specific point on the surface of another mesh.
  2. You already possess the position of the object's center, which implies you also have the position of its surface.
    • The vertices of your object are all centered around the origin (local center)
    • The object's center is transformed by the given transformation matrix.
    • This action essentially transforms all vertex positions accordingly.
    • Each of those vertex positions remains on the surface, only requiring transformation.

This technique works well if you know which vertex you intend to use, as suggested by the manner in which you framed your question. However, if you simply aim to direct an arrow from one mesh to another without penetration, a different method might be advisable.

Technique 2

If your objective is merely to indicate the direction from one mesh to another, with pinpoint accuracy not being a priority, this alternative approach is preferable. The strategy involves determining the bounding box or bounding sphere of your mesh and leveraging that information for efficient arrow placement.

  1. Establish a bounding volume

    a. As you collect all the mesh vertices, identify the farthest one from the center. This data will provide the radius of the encompassing sphere upon completion.

    b. Alternatively, note the greatest distances along each of the 6 axes (+-x,y,z) to construct a bounding box.

  2. Determine a line extending from the bounding volume's surface to that of another surface. With either a box or a sphere, this step should prove relatively simple (particularly for a sphere).

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 search for Javascript is futile when utilizing .Net RijndaelManaged

I have implemented an encryption/decryption process in my C# WCF using the following code: public static string EncryptString(string InputText, string Password) { RijndaelManaged RijndaelCipher = new RijndaelManaged(); RijndaelCiph ...

Performing function in Vue.js when a change occurs

I recently started developing a Vue.js component that includes an input field for users to request a specific credit amount. My current goal is to create a function that will log the input amount to the console in real-time as it's being typed. Ultima ...

Error encountered while running script across PHP pages

I have encountered an issue with the following code snippet. It runs perfectly fine in my initial PHP file, but when I attempt to use it in another file, the script does not seem to work as expected. Specifically, I do not receive any alert message from ...

Is it possible to hide a div using Media Queries until the screen size becomes small enough?

Whenever the screen size shrinks, my navbar sections start getting closer together until they eventually disappear. I've implemented a button for a dropdown menu to replace the navbar links, but I can't seem to make it visible only on screens wit ...

How to retrieve an element in jQuery without using the onclick event listener

I'm looking to extract the element id or data attribute of an HTML input element without using the onclick event handler. Here is the code I currently have: <button class="button primary" type="button" onclick="add_poll_answers(30)">Submit</ ...

Expiration Date of Third-Party Cookies

I need help retrieving the expiration date of a third-party cookie programmatically using JavaScript. Even though I can see the expiry time in the browser's DevTools (refer to the screenshot at https://i.sstatic.net/BW072.png), I am struggling to figu ...

Display a specific division depending on the outcome of an Ajax request within a PHP form

My PHP form has a layout similar to this: <form> <div id="inid"> National ID: <input type="text" id="individual_nid" oninput="getIndividualName(this.value)" /> </div> <hr /> name: <div id="individua ...

Modify the placeholder color for a disabled Input element to match the overall Mui theme design

I am struggling to change the color of the placeholder text in a disabled input field within my app's theme. Despite attempting to target the MuiFormControl, MuiInputBase, and MuiInput components in my theme.tsx file on CodeSandbox, I have not been su ...

What is the best way to control the iteration of a JavaScript 'for' loop based on specific conditions?

I need help with controlling the iteration of a 'for' loop in Javascript. Here is the code snippet: for (var j=0; j < number; j++){ $('#question').empty; $('#question').append('' + operand1[j], operator[j ...

What is the best way to incorporate both images and text in PHP code?

I'm currently working on creating a large image call-to-action (CTA) for my new WordPress website. I've set up a new field group with the type "group" in ACF, and added some functions in PHPStorm. However, none of my images, text, or links are ap ...

Using Next.js Link prefetch feature can lead to unexpected 404 errors on a production website

I'm currently working on a Next.JS blog project where I have created a page to showcase all of my articles. When I render the component, it appears like this: <div> {articles.map((article, index) => { const path = `/magazine/${ar ...

Having difficulty automatically populating a textarea with the chosen option from a datalist

Is there a way to automatically populate the Address field of a client in a textarea based on the input of the client's name in an input field? I have created a 'for loop' to retrieve a datalist of client names. For the address, I retrieved ...

Is it possible to modify the text alignment of a div based on the dropdown selection

I'm having trouble getting the alignment to work with my dropdown list that styles the font of a div. It's frustrating because I usually find solutions easily on Google, but this time the align feature is really bugging me. <SCRIPT LANGUAGE=" ...

Obtain the computed style by utilizing setTimeout for effective functionality

I want to retrieve the calculated style (background-color) of a span element. Here's my HTML code, consisting of two label elements, each containing an input and a span: <label> <input type="radio" name="numbers" value="01" checked/> ...

Exploring the world of Node.js callback parameter passing

Currently, I am diving into the world of Node callbacks and JavaScript in general. As I delve deeper, I find myself puzzled by the following snippet: var request = require('request'); request('http://www.google.com', function (error, ...

Switch between toggling tasks in Vue does not seem to be functioning as

I'm reaching out again because I'm struggling to figure out what I'm doing wrong. I followed a tutorial step by step but the code isn't working as expected. My goal is to toggle between marking tasks as done and not done. When I test th ...

Step-by-step guide on how to effectively send a NodeJS request and stream it into a separate response

Currently, I am in the process of developing an API to interact with a specific map service that requires the use of an API key. It is crucial for me to keep this API key private. To achieve this, I plan to make internal calls within my server's own A ...

What is the process for including headers while establishing a connection to a websocket?

After configuring a websocket topic using Spring websocket on the server side, we implemented the client side with Stomp.js to subscribe to it. Everything was functioning correctly when connecting directly to the websocket service. However, we decided to i ...

My backend axios post request is not returning any data to my external API. What could be the issue?

I've encountered an issue where I'm attempting to transmit data from my client-side using an ajax call to my backend axios post request, which is responsible for posting data to an external API URL. Despite receiving a 200 status code, none of th ...

The error message in threejs is "GL_INVALID_OPERATION: Attempting to perform an invalid operation on

I'm having an issue when trying to combine post-processing with the "THREE.WebGLMultisampleRenderTarget." The console shows the error message: [WebGL-000052BE06CD9380] GL_INVALID_OPERATION: Invalid operation on multisampled framebuffer When using th ...