What are the steps for creating a unique plane geometry using three.js?

I am hoping to develop a three.js plane with a higher number of points than the default setup. This means I won't be using PlaneGeometry since it doesn't allow me to define custom points. My goal is to have the flexibility to animate or move any point at any given time.

Here is my initial progress:

var camera;
var scene;
var renderer;
var mesh;

init();
animate();

function init() {

    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000);

    var light = new THREE.DirectionalLight( 0xffffff );
    light.position.set( 0, 1, 1 ).normalize();
    scene.add(light);


    var geometry = new THREE.PlaneGeometry( 50, 50);  

    var texture = THREE.ImageUtils.loadTexture('images/03032122.png', {}, function() {
    renderer.render(scene, camera);
    })
    var material = new THREE.MeshBasicMaterial({map: texture, transparent: true })


    mesh = new THREE.Mesh(geometry, material );
    mesh.position.z = -50;
    scene.add( mesh );

    renderer = new THREE.WebGLRenderer({ alpha: true });
    renderer.setSize( window.innerWidth, window.innerHeight );

    renderer.setClearColor( 0xffffff, 1);
    document.body.appendChild( renderer.domElement );

    window.addEventListener( 'resize', onWindowResize, false );

    render();
}

function animate() {
    //mesh.scale.x+= 0.0003;


    render();
    requestAnimationFrame( animate );

}

function render() {
    renderer.render( scene, camera );
}


function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize( window.innerWidth, window.innerHeight );
    render();
}

My objective is to create something akin to this visual:

Answer №1

Make sure to pay attention to PlaneGeometry, as it is now deprecated (meaning it will be removed in a future update). Instead, use PlaneBufferGeometry.

@pailhead's response is accurate if you are looking for the standard plane division.

If you want the vertices to have different positions, you will need to construct the geometry vertex by vertex, which is a different approach.

Additionally, if you need to move/animate the vertices later on, you can adjust each vertex's position after creating the geometry with this code:

planeMesh.geometry.vertices[i].set(x, y, z); // This allows you to change the coordinates of each vertex
planeMesh.geometry.verticesNeedUpdate = true;

*: For example, creating a plane with 4 vertices (2 triangles):

var geo = new THREE.Geometry();
geometry.vertices.push(
    new THREE.Vector3(x1, y1, z1), // vertex0
    new THREE.Vector3(x2, y2, z2), // 1
    new THREE.Vector3(x3, y3, z3), // 2
    new THREE.Vector3(x4, y4, z4) // 3
    );
geometry.faces.push(
    new THREE.Face3(2, 1, 0), // using vertices with rank 2, 1, 0
    new THREE.Face3(3, 1, 2) // vertices[3], 1, 2...
    );

It is important to note that what defines this geometry as a plane is that the 4 vertices are coplanar.

When dealing with geometries with numerous faces, you may find it helpful to draw them out on paper. Depending on the complexity of your geometry, you may also need to utilize an algorithm.

Answer №2

I designed my own unique aircraft using the following code:

        // Custom Aircraft
            var size = 600, step = 150;
            var geometry = new THREE.Geometry();
            for ( var i = - size; i <= size; i += step ) {

                geometry.vertices.push( new THREE.Vector3( - size, 0, i ) );
                geometry.vertices.push( new THREE.Vector3(   size, 0, i ) );

                geometry.vertices.push( new THREE.Vector3( i, 0, - size ) );
                geometry.vertices.push( new THREE.Vector3( i, 0,   size ) );

            }

            var material = new THREE.LineBasicMaterial( { color: 0xFF0000, opacity: 0.7 } );

            var line = new THREE.Line( geometry, material, THREE.LinePieces );
            scene.add( line );

Answer №3

Consider expanding the arguments of THREE.PlaneGeometry by adding two more parameters.

THREE.PlaneGeometry( width, height, widthSegments, heightSegments )

Refer to the library (observe a function call) and check the documentation for guidance.

Alternatively, you may explore the following resource:

Answer №4

If you're interested in creating a customized plane with unique borders, I suggest directly modifying the position attribute array and updating the geometry points position:

// Define the length of x and the number of divisions
    const x_length = 1 
    const divisions = 10
    
    let geometry = new THREE.PlaneBufferGeometry( x_length, 1, divisions, 1 )
    let material = new THREE.MeshPhongMaterial( { color: 0xecf0f1, wireframe: true } )
    
    let pointPos = geometry.getAttribute("position").array
        
    for (let i = 0; i < divisions + 1; i++) {
      let x = pointPos[3 * i] + x_length/2

      // Assigning y as a function of x^2
      pointPos[3 * i + 1] = Math.pow(x, 2) 
      pointPos[3 * ( divisions + 1 ) + 3 * i + 1] = - pointPos[3 * i  + 1]
      
      console.log(`x = ${pointPos[3 * i]}; y = ${pointPos[3 * ( divisions + 1 ) + 3 * i + 1]}`)

        }
    
    pointPos.needsUpdate = true;
    
    mesh = new THREE.Mesh(geometry, material )

    scene.add(mesh)

For a visual demonstration, check out my example https://codepen.io/ferrari212/pen/bGpgLBd?editors=0010

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

What is the term used for the objects that res.render passes?

I constantly find myself struggling with defining objects inside res.render. Is there a way to define them globally or outside of res.render? I hope someone can offer some guidance.. here is a sample code snippet: router.get("/home/blog", function(req,r ...

Exploring the Benefits of Using a Try-Catch Block for Creating an Audio Element

While reviewing the Jbox plugin code, specifically focusing on the audio addition part, I encountered the following snippet of code: jBox.prototype.audio = function(options) { options || (options = {}); jBox._audio || (jBox._audio = {}); // ...

Invoke a PHP function located in a separate file using a JavaScript function to fetch data from a database

How can I properly call a PHP function from a JavaScript function located in a different file? I am trying to pass a variable from an onClick function in JavaScript to a PHP function, which will then access a MySQL database to retrieve data. However, my c ...

Is it possible to use AngularJS to show additional information between rows when a table row is clicked in HTML

I'm currently working on an html table where the <tbody> is generated using angular's ng-repeat. Take a look at my html: <tbody ng-repeat="car in carList | filter:tableFilter"> <tr> <td><a target="_blank" h ...

Massive HTML Table Containing Rows upon Rows

Currently, I have a server that can provide me with a list of objects in json format, and my goal is to showcase them in a table on the client side. Initially, I thought about dynamically modifying the DOM after receiving data from the server. Building th ...

JavaScript - unable to view updated information without refreshing page

I am currently developing a Single Page Application (SPA) using Rails for the backend and JavaScript for the frontend. When I submit the initial form to create a Resource, it shows up on the page immediately upon pressing the submit button. However, when I ...

AngularJS version is a software update for the Angular

I recently started learning AngularJs and have been following the Oreilly AngularJS book. I was able to successfully run this code with Angular version 1.0.8, but it doesn't work with newer versions of Angular. Can someone tell me why? <!DOCTYPE h ...

The condition is not being recognized after clicking the third button

When the button is clicked for the first time in the code snippet below, all divs except for the red one should fade out. With each subsequent click, the opacity of the next div with a higher stack order should be set to 1. Everything works fine until the ...

Strategies for effectively managing and eliminating spam messages in ReactJs

When displaying a list of items with a delete button next to each one, I show 25 results and then page the rest to retrieve the next set of results when the user clicks the next page button. One issue I am encountering is that after a user deletes an item ...

The mysterious case of the missing currentUserObj in Angular with rxjs Subject

I've encountered an issue while trying to pass data from my login component to the user-profile component using an rxjs subject. Despite calling the sendUser method in the login component and subscribing to the observable in the user-profile component ...

Can Selenium in JavaScript be used to retrieve child elements from a webpage?

I've been struggling to adapt my JavaScript script for use with Selenium (also in JavaScript). Despite numerous attempts, I haven't been able to find a solution. I've attached an image to better explain my question await chromeDriver.findEle ...

Determining the positioning of a tablet with a JavaScript algorithm

We are currently working on developing an HTML5/JavaScript application specifically designed for tablet devices. Our main goal is to create different screen layouts for landscape and portrait orientations. Initially, we attempted to detect orientation cha ...

Can you show me the steps for linking the next method of an EventEmitter?

After emitting an event, I am looking to run some additional code. Is there a method to chain the .next() function in this way? @Output() myEvent = new EventEmitter<string>(); this.myEvent.next({‘test string’}).onComplete(console.log('done& ...

Verifying the username's availability through AJAX requests

My registration form utilizing AJAX isn't connecting to the database. It seems like I'm missing something important. Let's focus on validating this particular field: Username:<input type="text" name="user" id="user" maxlength="30"> & ...

Can grapesjs be integrated into AngularJS using a controller?

JavaScript Question var app = angular.module('CompanyProfile', []); app.controller('CompanyProfileCtrl', function() { function initializeEditor() { var editor = grapesjs.init({ allowScripts: 1, ...

Error message: Invalid input for directive, only numeric values are accepted

I need help with a directive that restricts non-numeric symbols in an input field. Below is the code for the directive: import { NgControl } from "@angular/forms"; import { HostListener, Directive } from "@angular/core"; @Direct ...

What is the best way to ensure that a Mantine burger closes once a link is clicked?

Is there a way to automatically close the Mantine burger after selecting a navigation choice in the modal? It appears that the burger does not close automatically (due to the x icon remaining visible). My setup includes NextJS with Mantine & react-icon ...

execute a jQuery function within a data list component

Looking to slide down a div and then slide it back up when a button is clicked. After searching on Google, I found a solution but unfortunately, the slide up function is not working as expected. When the button is clicked, the div slides down correctly but ...

Function utilizing variables parsed by Angular directive

I am currently working on a directive that I have created: feedBackModule.directive("responseCollection", ['deviceDetector', function (deviceDetector) { return { restrict: "E", templateUrl: 'js/modules/Feedback/direc ...

Relocating to reveal or conceal item

I am currently working with jQuery and trying to achieve a specific functionality. My goal is to hide and unhide an element, while also focusing on the exposed area once it becomes visible. I have a link #welcomeselect that, when clicked, should reveal t ...