Mismatch between BoxGeometry and SphereGeometry alignment issue

I'm having trouble aligning spikes on a globe using sphere geometry. Despite everything else working fine, the spikes don't align properly with the globe as shown in the image below. I've tried using lookAt(new THREE.Vector3(0,0,0)) but it doesn't seem to work. Any help would be appreciated.

I included the necessary code for debugging purposes. Let me know if you need more code to troubleshoot this issue. The desired alignment of the spikes with the sphere is illustrated in the image provided.

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

However, the current alignment looks like this:

https://i.sstatic.net/33wGY.jpg

Here's my main JavaScript initialization file:

$(document).ready(function () {

  // Initializing Camera
  Influx.Camera = new Influx.Camera({
    fov: 60,
    aspectRatio: window.innerWidth / window.innerHeight,
    near: 1,
    far: 1000,
    position: {
      x: 0,
      y: 0,
      z: 750
    }
  });

  //Initializing Scene
  Influx.Scene = new Influx.Scene();

  // Initializing renderer
  Influx.Renderer = new Influx.Renderer({
    clearColor: 0x000000,
    size: {
      width: window.innerWidth,
      height: window.innerHeight
    }
  });

  Influx.Globe  = new Influx.Globe({
    radius: 300,
    width:  50,
    height: 50
  });

  //
  Influx.Stars  = new Influx.Stars({
    particleCount: 15000,
    particle: {
      color: 0xFFFFFF,
      size: 1
    }
  });

  Influx.moveTracker = new Influx.moveTracker();

  Influx.EventListener  = new Influx.EventListener();

  (function animate() {
    requestAnimationFrame( animate );
    render();
    controls.update();
  })();

  function render() {
    camera.lookAt(scene.position);
    group.rotation.y -= 0.001;
    renderer.render( scene, camera );
  };

});

The following code snippet is responsible for creating the spikes on the Globe:

Influx.Spikes = function (lat, long) {

  // convert the positions from a lat, lon to a position on a sphere.
  var latLongToVector3 = function(lat, lon, RADIUS, heigth) {
    var phi   = (lat) * Math.PI/180,
        theta = (lon-180) * Math.PI/180;

    var x = -(RADIUS+heigth) * Math.cos(phi) * Math.cos(theta),
        y =  (RADIUS+heigth) * Math.sin(phi),
        z =  (RADIUS+heigth) * Math.cos(phi) * Math.sin(theta);

    return new THREE.Vector3(x, y, z);
  };

  var geom        = new THREE.Geometry();
  var BoxGeometry = new THREE.BoxGeometry(1, 100, 1);

  //iterates through the data points and makes boxes with the coordinates
  var position = latLongToVector3(lat, long, 300, 2);

  var box = new THREE.Mesh( BoxGeometry );

  //each position axis needs to be set separately, otherwise the box
  //will instantiate at (0,0,0)
  box.position.x = position.x;
  box.position.y = position.y;
  box.position.z = position.z;

  box.lookAt(new THREE.Vector3(0, 0, 0));
  box.updateMatrix();

  //merges the geometry to speed up rendering time, don't use THREE.GeometryUtils.merge because it's deprecated
  geom.merge(box.geometry, box.matrix);

  var total = new THREE.Mesh(geom, new THREE.MeshBasicMaterial({
    color: getRandomColor(),
    morphTargets: true
  }));

  function getRandomColor() {
    var letters = '0123456789ABCDEF';
    var color = '#';
    for (var i = 0; i < 6; i++ ) {
      color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
  };

  //add boxes to the group
  group.add(total);
  scene.add(group);
};

Influx.Camera = function(params = {}) {

  if ( !$.isEmptyObject(params) ) {
    window.camera = new THREE.PerspectiveCamera(params.fov, params.aspectRatio, params.near, params.far);
    camera.position.set(params.position.x, params.position.y, params.position.z);
    camera.lookAt(new THREE.Vector3(0,0,0));
  } else {
    console.log("Trouble with Initializing Camera");
    return;
  }

};

Answer №1

Keep in mind that when using the lookAt method, a direction vector is required. Instead of passing the (0, 0, 0) vector which is not normalized, it's important to calculate the correct direction:

Calculate the normalized direction from the box's position to the center of the sphere.

var dir = box.position.sub(world.position).normalize();
box.lookAt(dir);

Also, consider following these good coding practices for better readability:

var BoxGeometry = new THREE.BoxGeometry(1, 100, 1);

It's recommended to use a different variable name like "boxGeometry" to avoid confusion with classes and maintain naming conventions:

var boxGeometry = new THREE.BoxGeometry(1, 100, 1);

Instead of setting x, y, z positions individually:

box.position.x = position.x;
box.position.y = position.y;
box.position.z = position.z;

You can simplify it by just copying the position:

box.position.copy(position);

Answer №2

Encountering the same issue, I was able to resolve it by ensuring that the line of code box.lookAt(new THREE.Vector3(0, 0, 0)) appears after box.scale.z = xxxx.

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 necessity of utilizing a dummy object for storing events in JavaScript is evident in certain situations

I am confused as to why in some instances a dummy object is needed in JavaScript to store events, like in the following code: Metal.Gold = function() { var temp = $("<div>"); //dummy object this.Submit = function(url1, method, data){ ...

Add a checkbox element to a web API using ReactJS

I'm currently learning react and encountering an issue with checkboxes that I can't seem to resolve. I am working on a modal for updating and inserting data in a .net core web api, which is functioning correctly. However, within the app, I'm ...

Enhance the JQuery dropdown by padding with zeros at the beginning for smooth incrementing

I have been attempting to customize a date dropdown in Sharepoint because the default minutes dropdown only allows selection in 5-minute intervals. Initially, I was able to make it work with the code below: $("select[id$='DateTimeFieldDateMinutes&apo ...

Using web3Provider in a Next.js environment

While attempting to integrate Web3-react v6 into my Next JS project, I encountered an error when trying to wrap my entire app with the provider. In _app.jsx, I included the following code: import React from 'react'; import { Web3ReactProvider } ...

An issue with asynchronous execution in Protractor

I have been using and learning protractor for over a month now. Despite the documentation stating that Protractor waits for Angular calls to complete (http://www.protractortest.org/#/), ensuring all steps are executed synchronously, I have not found it ...

Reveal content as you scroll

I'm having trouble with the code snippet below. My goal is to utilize .cbp-fbscroller in my CSS to show a new side navigation menu on my HTML page only when scrolling down to 900px. However, as someone who is new to JavaScript, I am struggling to make ...

How to retrieve a subobject using AngularJS

From my perspective : <span data-ng-init="fillEditForm['titi']='toto'" ></span> In my Angular controller : console.log($scope.fillEditForm); console.log($scope.fillEditForm['titi']); The outcome : Object { ti ...

Invoking AJAX function post readystatechange

Currently, I am in the process of making an Ajax call to a server and attempting to invoke another function once the response is ready (readystatechanged). As of now, there isn't any serverside code implemented. Surprisingly, Chrome and Firefox encoun ...

Mastering the Art of Scrolling

Can someone please tell me the name of this specific scrolling technique? I am interested in using something similar for my project. Check out this example site ...

Iterating through an array of MongoDB document IDs, querying each ID and then storing the results in a new array results in an empty array

Having trouble with the following code: const users = [] event.registeredUsers.forEach(userId => { User.findOne({ _id: userId }).then(user => { console.log(user) // displays a valid user users.push ...

Automatically submitting the selection when it changes

I am facing an issue with a selection form that is supposed to update the database on change using jQuery, but it seems like nothing is happening. Can anyone provide assistance with this problem? <SELECT name='status' id='status'> ...

Internet Explorer's incompatibility with the window.location.href function

I'm having an issue with navigating to a new page using a callback from an AJAX post request specifically on Internet Explorer. Here is the code snippet causing the problem: $.ajax({ type: "POST", url: phpUrl, data: data, async: ...

Troubleshooting issue with displaying favicons in express.js

Currently, I am working on a simple express.js example and trying to get favicons to display properly. Everything functions correctly when testing locally, but once uploaded to my production server, only the default favicon appears. I have attempted cleari ...

The lack of definition for e.PreventDefault causes an error

In my code, I have a registerAjax(e) function: function registerAjax(e) { e.preventDefault(); let userData = { username: $("#username").val(), password: $("#password").val(), }; $.ajax({ method: "POST", url: kinveyBaseUrl + "user/" + kinve ...

Cannot get Firebase's set() method to work when called within onAuthStateChanged() function

As I embark on developing my first significant web application using ReactJS with Firebase as the backend database, everything was progressing smoothly until a troublesome issue surfaced. The hurdle I encountered involves saving user information upon thei ...

Evaluating text presence with Nightwatch and Selenium by checking for single quotes in an element

I need to verify if an element includes text with an apostrophe. I attempted: 'PROGRAMMA\'S' or "PROGRAMMA'S", such as .assert.containsText('element', 'PROGRAMMA\'S') However, neither method seems t ...

JestJS: Async testing isn't halted

I am facing two issues with my jest test: Is there a way to define the Content collection only once instead of repeating it inside the test? I encountered this error: Jest did not exit one second after the test run has completed. This usually indicates ...

How can you use the :not selector in CSS to target specific elements within a group?

Consider the following set of inputs: <div id="group"> <input id="uno" class="red"></input><br/> <input id="dos" class="red"></input><br/> <input id="tres" class="blue"></input><br/ ...

Submitting POST data to PHP using AJAX

Having always sent AJAX requests with jQuery, I am now faced with the challenge of sending them using 'vanilla' JS. Despite my best efforts, I have managed to get everything working except for passing the data along with the request. The two vari ...

Extracting deleted characters from input in Angular 2

Is there a way to detect a removed character from a text using ngModel in Angular 2? I am looking for something like: Original text: @Hello World ! Modified text: Hello World ! Console.log Removed character: '@' I came across an interesting ...