Updating line connections between objects in Three.js while rendering

I am working with a three.js canvas that contains circles moving independently. Initially, these circles are connected by a single line that follows the same geometry as their positions.

However, I am facing difficulty updating the line's geometry when these circles move.

I have tried searching through all the scene's children to find any child named 'item' and updating their x & y positions. Yet, when attempting to update the line's geometry, it either disappears or remains static (as seen in the code below).

How can I effectively update the line's geometry on each frame to match the movements of the circles?

var container;
var camera, scene, renderer;

var numItems = 40;
var xspeed; // Speed of the shape
var yspeed; // Speed of the shape
var lineGeometry;

init();
animate();

function init() {
  container = document.createElement('div');
  document.body.appendChild(container);
  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000);
  scene = new THREE.Scene();
  scene.background = new THREE.Color(0xff3000);
  var geometry = new THREE.CircleBufferGeometry(15, 20);
  lineGeometry = new THREE.Geometry();

  for (var i = 0; i < numItems; i++) {
    var item = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: Math.random() * 0x000000 }));
    item.position.x = (-180) + (i * Math.random() * (80 - 1) + 1);
    item.position.y = (-50) + (i * Math.random() * (80 - 1) + 1);
    item.xspeed = Math.random() * (2 - 1);
    item.yspeed = Math.random() * (1 - 0.5);
    item.name = "item";
    scene.add(item);
    lineGeometry.vertices.push(item.position);
  }

  var line = new THREE.Line(lineGeometry, new THREE.LineBasicMaterial({ color: 0x000000 }));
  line.name = "line";
  scene.add(line);

  function animate() {
    requestAnimationFrame(animate);
    render();
  }
  
  function render() {
    for (var i = 0; i < scene.children.length; i++) {
      var newPosition;
      if (scene.children[i].name === 'item') {
        scene.children[i].position.x = scene.children[i].position.x + scene.children[i].xspeed;
        scene.children[i].position.y = scene.children[i].position.y + scene.children[i].yspeed;

        newPosition = scene.children[i].position;

        if (scene.children[i].position.x > window.innerWidth/2 || scene.children[i].position.x < -window.innerWidth/2) {
          scene.children[i].xspeed = scene.children[i].xspeed * (-1);
        }
        if (scene.children[i].position.y > window.innerWidth/2 || scene.children[i].position.y < -window.innerWidth/2) {
          scene.children[i].yspeed = scene.children[i].yspeed * (-1);
        }
      }

      if (scene.children[i].name === 'line') {
        scene.children[i].vertices = newPosition;
      }
    }

    camera.position.x = 0;
    camera.position.z = 1000;
    renderer.render(scene, camera);
  }

Answer №1

Your line geometry points are already aligned with circle positions, eliminating the need for constant reassignment during scene rendering.

If you make the line a global variable and create another global array to store circles, you can simplify the process.

var camera, scene, renderer, line, circles = [];

You can then easily add your item to the array:

circles.push(item);
scene.add(item); 

This will streamline your render function as follows:

function render() {
  circles.forEach(circle => {
    circle.position.x += circle.xspeed;
    circle.position.y += circle.yspeed;

    if (circle.position.x > window.innerWidth / 2 || circle.position.x < -window.innerWidth / 2) {
      circle.xspeed *= -1;
    }
    if (circle.position.y > window.innerWidth / 2 || circle.position.y < -window.innerWidth / 2) {
      circle.yspeed *= -1;
    }
  });
  line.geometry.verticesNeedUpdate = true;

  renderer.render(scene, camera);
}

var container;
var camera, scene, renderer, line, circles = [];

var numItems = 40;
var xspeed // Speed of the shape
var yspeed // Speed of the shape
var lineGeometry;

init();
animate();

function init() {
  scene = new THREE.Scene();
  scene.background = new THREE.Color(0xff3000);
  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000);
  camera.position.set(0, 0, 1000);
  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  var geometry = new THREE.CircleBufferGeometry(15, 20);
  lineGeometry = new THREE.Geometry();

  for (var i = 0; i < numItems; i++) {
    var item = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({
      color: Math.random() * 0x000000
    }));
    item.position.x = (-180) + (i * Math.random() * (80 - 1) + 1);
    item.position.y = (-50) + (i * Math.random() * (80 - 1) + 1);
    item.xspeed = Math.random() * (2 - 1);
    item.yspeed = Math.random() * (1 - 0.5);
    circles.push(item);
    scene.add(item);
    lineGeometry.vertices.push(item.position);
  }

  line = new THREE.Line(lineGeometry, new THREE.LineBasicMaterial({
    color: 0x000000
  }));
  line.name = "line";
  scene.add(line);
}

function animate() {
  requestAnimationFrame(animate);
  render();
}

function render() {
  circles.forEach(circle => {
    circle.position.x += circle.xspeed;
    circle.position.y += circle.yspeed;

    if (circle.position.x > window.innerWidth / 2 || circle.position.x < -window.innerWidth / 2) {
      circle.xspeed *= -1;
    }
    if (circle.position.y > window.innerWidth / 2 || circle.position.y < -window.innerWidth / 2) {
      circle.yspeed *= -1;
    }
  });
  line.geometry.verticesNeedUpdate = true;
  // this flag is crucial for updating vertex coordinates in a geometry

  renderer.render(scene, camera);
}
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>

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

Having trouble getting the jQuery/JS redirect button to function properly

I'm fairly new to working with jQuery. My current challenge involves unsetting a cookie and then navigating to the next page. There are numerous resources discussing this topic online, but what seemed like a simple task has turned into a two-hour hea ...

transfer jquery element using jquery ajax

How can I send a jQuery object to a PHP function using POST? When I stringify the object, I get the following output: [ { "id": "701", "user_id": "2", "playlist": "ukg%20garage", "tracks": "5", "thumbnail": "Coldplay.jpeg", "crea ...

What is the significance of providing a sole argument to the Object () function?

Answering a related question about object constructors, what is the intention behind passing an argument to the constructor of objects and using it in this specific manner? function makeFoo(a, b) { var foo = Object.create(Foo.prototype); var res ...

Once an item is added, the table vanishes into thin air

I have a DataTables setup to show a list of project names, and I have a button that should add an item to the displayed array. However, when I click the button, the table disappears. Below is the code snippet: view.html <button ng-click="vm.add()"> ...

Next.js - NextAuth consistently delivers a successful status code every time

In my Next.js project, I am utilizing NextAuth. The issue I'm encountering is that NextAuth consistently returns a 200 status code and updates the session to authenticated, even when the username or password doesn't match. I've attempted thr ...

Refreshing a single HTML element in ASP.NET MVC - the simple way!

Recently, I put together an image gallery using the unite gallery jquery plugin and now I want to change up the images it displays. My plan is to have a button labeled "art" that, when clicked, triggers a function to update the directory path and load ne ...

The request to http://localhost:5000/error resulted in a 404 (Not Found) error message. I encountered difficulties connecting

When attempting to retrieve information about a product from Amazon using their productId with Express.js and ScraperAPI, an error is encountered: Error message: "{name: "RequestError", message: "Error: Invalid URI "${baseUrl}&url=https://www.amazon.com/d ...

Client-side rendering for NextJS server components is also supported

I am currently working with Material UI v5.11.16 in a nextjs environment using v13.3.0. I followed the official documentation setup for my nextjs project which can be found here. So far, I have successfully integrated Material UI components without having ...

Select the first item that is visible and chosen

Currently, I am working with a select list: <option ng-repeat="hour in Hours" value="{{hour.Value}}" ng-show="filterEvent($index)" ng-selected="hour.Value == EventDate || $first"> {{hour.Text}} </opti ...

When using NodeJS, having multiple 'if' statements may result in conflicting headers being returned,

Introduction to Promises. Encountering challenges in NodeJS due to the utilization of multiple if-statements and return-statements. Considering leveraging Promise as a potential solution. This snippet showcases an example: const express = require(' ...

NextJS - Accessing local files with readdir and readFile functions leads to error: Module not found when trying to resolve 'fs' module

I have been working with NextJS and have successfully used the getStaticProps functionality in previous projects to populate data. However, I recently set up a new NextJS project and it seems that this functionality is no longer working. When starting th ...

Implementing MUI createTheme within Next.js

After switching from material-UI version 4 to version 5.5.0 in my project, I encountered issues with createTheme. The colors and settings from the palette are not being applied as expected. Current versions: next: 11.0.0 react: 17.0.2 mui : 5.5.0 theme. ...

Dealing with Ajax errors in Django reponses

My code includes an ajax call to a Django view method: $("#formi").submit(function(event){ event.preventDefault(); var data = new FormData($('form').get(0)); $.ajax({ type:"POST", url ...

Is it possible to utilize the same Context in multiple forms within React?

Is it possible to utilize React Context to store the state of multiple forms, or should each form have its own unique Context? Below is a snippet of code that showcases the use of React Hooks API: In FormContext.js ... import {FormReducer} from './ ...

Running the test suite in another tab is causing it to fail

I am experiencing an unusual issue in my protractor UI test. During one of the tests, I need to click on a link that opens in a new tab. The test passes when run individually, but fails when run as part of the test suite. I would appreciate it if you coul ...

When attempting to use JQuery autocomplete, the loading process continues indefinitely without successfully triggering the intended function

Currently, I am utilizing JQuery autocomplete to invoke a PHP function via AJAX. Below is the code snippet I am working with: $("#client").autocomplete("get_course_list.php", { width: 260, matchContains: true, selectFirst: false }); Upon execution, ...

Guidelines for combining inner objects with their parent in Javascript

I need assistance with using the filter function in Angular.js because it's not working on objects. Is there a way to merge a nested object into its parent using Javascript? For example, I have the following data structure: { "data" : [ { "ch ...

Pass user input values to PHP via AJAX and display the outcome on a designated div

I am currently working on a project where I need to send an input value to a PHP script and display the returned value in a div using AJAX. However, I seem to be struggling with getting it to work properly. Any assistance or suggestions would be greatly ap ...

Discovering the data-id value in an HTML element by clicking it with JavaScript and returning that value through a for loop

this is my unique html content <ul class="dialogs"> {% if t_dialogs %} <li class="grouping">Today</li> {% for item in t_dialogs %} <li class=&qu ...

Is it possible to preserve the <canvas> elements to use for future animation frames?

Currently, I am working on a graph visualization project that involves complex calculations being done on an HTML5 canvas. My goal is to create an interactive animation where the graph remains fixed, but additional elements are overlaid as the mouse moves ...