Discrepancy in results between ThreeJS's ExtrudeGeometry depth and extrudePath

Utilizing THREE.ExtrudedGeometry in two distinct manners led me to anticipate the same outcome.

One method involved using the depth parameter to define the extrusion options, while the other utilized an extrude path, which was a line from Vector3(0, 0, 0) to Vector3(0, 0, depth)

The peculiar observation was that the resulting geometry appeared unexpectedly rotated around the Z-axis. Why is this happening? Is it considered normal behavior or am I making a mistake somewhere?

You can find a demonstration on fiddle by clicking here, along with the following code:


Variables shared across both methods:

// Material for mesh
var material = new THREE.MeshBasicMaterial({color:0xff0000});

// Depth of extrusion
var depth = 10;

// Shape to be extruded
var shape = new THREE.Shape([
    new THREE.Vector2( -20,-60 ),
    new THREE.Vector2( -20, 60 ),
    new THREE.Vector2(  20, 60 ),
    new THREE.Vector2(  20,-60 )
]);

Using depth parameter:

var extrudeSettings1 = {
    bevelEnabled: false,
    steps: 1,
    amount: depth
};

var geometry1 = new THREE.ExtrudeGeometry( shape, extrudeSettings1 );

var mesh1 = new THREE.Mesh( geometry1, material );

mesh1.position.set( -50, 0, 0 );

scene.add( mesh1 );

Now employing an extrude path:

var v1 = new THREE.Vector3( 0, 0, 0 );

var v2 = new THREE.Vector3( 0, 0, depth );

var path = new THREE.LineCurve3( v1, v2 )

var extrudeSettings2 = {
    bevelEnabled: false,
    steps: 1,
    extrudePath: path
};

var geometry2 = new THREE.ExtrudeGeometry( shape, extrudeSettings2 );

var mesh2 = new THREE.Mesh( geometry2, material );

mesh2.position.set( 50, 0, 0 );

scene.add( mesh2 );

EDIT1:

Updated the position.set() as per WestLangley's suggestion.

EDIT2:

After further consideration, although I reviewed WestLangley's response, I am still unable to comprehend it fully. The orientation of the shape should not impact its ability to return to the starting point. In my view, regardless of orientation, the shape should end up in the same position it started from.

To clarify, I have depicted two shapes on the x, y plane and displayed the extrusions to illustrate what I believe should be the correct outcome:

Answer №1

To understand why the behavior occurs, delve into the source code of THREE.ExtrudedGeometry and THREE.TubeGeometry.FrenetFrames.

Here are some insights from the comments found in ExtrudeGeometry:

  • extrudePath: // Represents a 3D spline path for extruding shapes. FrenetFrames are created if .frames aren't defined.
  • frames: // Contains arrays of tangents, normals, binormals

Simply put, as mentioned by WestLangley, when a specific extrudePath is set, the geometry is extruded along a 3D spline path, utilizing FrenetFrames to adjust rotation, unlike a straightforward extrusion method.

In the code section THREE.TubeGeometry.FrenetFrames, you may come across commented code related to initialNormal1. Uncommenting these lines allows you to experiment with different initial positions or input your customized FrenetFrames for desired behavior.

Answer №2

You're not making any mistakes here. What you're witnessing is simply a result of the way the algorithm has been programmed. Think of it as a unique "feature".

When you extend a shape along a path, the shape has the freedom to "rotate", and its initial orientation is arbitrary.

Picture this scenario: if you were extending along a closed 3D loop. As you return to the starting point, the shape must align with the same orientation it began with to ensure the ends of the extension connect seamlessly. The algorithm needs to be adaptable enough to handle this particular situation.

EDIT: While extending along a path, the algorithm calculates a sequence of gradually changing Frenet Frames. (Take a look at the Wikipedia animations.) These Frenet Frames determine how the shape is oriented along the path. The extension algorithm establishes the orientation of the initial Frenet Frame, and that initial orientation can lead to a spinning motion of the shape.

three.js r.68

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's the best way in Angular 6 to set focus on an element that's being made content editable?

I am currently utilizing the contentEditable attribute in Angular 6 to allow for editing the content of elements within an ngFor loop. Is there a way to focus on a tag element when its contentEditable attribute is set to true? <div class="tag" *ngFor= ...

What is the best way to incorporate ngRoute into Jasmine / Karma for testing AngularJS applications?

I am currently working on setting up a basic unit test example. Everything is running smoothly with this app.js: var whapp = angular.module('whapp', []) .filter('reverse', [function(){ return function(string){ return string ...

Combine two or more Firebase Observables

Currently, I am working on creating an Observable using FirebaseObjectObservable. However, before I can accomplish this, I need to query a Firebase list to obtain the key IDs required for the FirebaseObjectObservable. The structure of my data is as follow ...

The problem with utilizing the Node `util.inherits` method

I have encountered an issue with a 'this problem' in a Node server. It seems that replacing worker.stuff with worker.stuff.bind(worker) is necessary for it to function correctly. Is there a way to incorporate the bind method into the Worker Clas ...

Embarking on the GSAP journey

I'm attempting my first animation using GSAP, but no matter what I try, nothing seems to be working. I've even tried using example code without success. Within my PHP file, I have the following code snippet: <head> <script src="https:/ ...

What methods could I use to preserve Material containing an envMap attribute?

After applying an envMap to my Material, I attempted to save it using Material.toJSON() and store it in localStorage. Unfortunately, an error occurred with the message: Texture.js:124 Uncaught TypeError: Failed to execute 'drawImage' on 'C ...

Tips on obtaining checkbox values other than "true"

Having trouble retrieving the values of selected checkboxes instead of displaying "Custom Category"? I've attempted to access the values and attributes with no success. I'm aiming to display the values of the selected checkbox. app.component.ht ...

Issue with running "ng serve" command on command prompt

Upon running the command "ng serve" in cmd for Angular2, I encountered the following errors: "unknown browser query basedir=$(dirname $(echo $0 | sed -e s,\,/,g))" After multiple attempts to resolve the issue, I found the error message: Browsersl ...

Using JQuery to switch classes and activate events

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <body> <span class="fake_h">Too</span> </body> <script> $('.fake_h').click(function() { $(this).addClass( ...

Identify the browser dimensions and implement CSS styling for all screen resolutions

I am currently facing an issue with a function that I have created to apply CSS changes to a menu based on browser resizing and different resolutions. The problem lies in the fact that my function does not seem to be correctly interpreted by the browser. W ...

Is there a versatile spell-checking tool available for HTML text boxes?

When designing a text box in HTML, I want to provide real-time input validation and spell check for the user's text. My goal is to underline any spelling mistakes as they type. This seems like a basic feature, but I've yet to find a plugin or AP ...

Is there a way to ensure that axios.get runs synchronously?

Here is my Node.js code for scraping 1337x.to. Initially, I successfully scraped the search results and then proceeded to extract the URLs of the torrents along with their magnet links. While this process worked fine within different functions, I encounter ...

Can we avoid the addition of a 'children' element by JSX comment, potentially causing issues with types?

Imagine having a third party library structured like this: declare var SomeComponentFromLibrary: React.FC<{ children?: React.ReactElement }>; Within the library's definition, children is set to be a React.ReactElement, and altering this det ...

Importing JavaScript into an Angular component: A beginner's guide

Within my Angular-11 project, I have included the following JavaScript file: "node_modules/admin-lte/plugins/bs-stepper/js/bs-stepper.min.js", I have added it to the angular.json configuration as detailed above. import Stepper from '.. ...

What circumstances allow @Inject to be optional in Angular?

My Angular service is simple yet causing errors. Here's the code snippet: // service.ts export class SimpleService { // ... } // component.ts @Component({ selector: 'my-component', templateUrl: 'components/mycomp/mycomp.ht ...

Troubleshooting sound problems in Angular JS

Can anyone help with pausing an AngularJS audio when the browser window is closed and resuming it when the window is maximized? I'm new to AngularJS and have no idea how to achieve this. var app=angular.module("myApp",['ngAudio']); ...

Transform CSV data into JSON format to generate an empty JSON file

I've been attempting to convert a CSV file to JSON using the convert-csv-to-json package from npm. Although I can successfully retrieve the CSV file from the specified URL and create a 'data.csv' file, the resulting JSON file is only an empt ...

Beware, search for DomNode!

I attempted to create a select menu using material-ui and React const SelectLevelButton = forwardRef((props, ref) => { const [stateLevel, setStateLevel] = useState({ level: "Easy" }); const [stateMenu, setStateMenu] = useState({ isOpen ...

Sending JSON data along with sendFile() in Node.js and Express done right

After setting up a Node.js server with Express and routing, I am faced with the challenge of passing JSON data onto a specific page ("/users/id") while using sendFile(). While I could make an AJAX request on page load to retrieve the data separately, I am ...

What is the best way to incorporate a changing variable within an htmx request?

One of the endpoints in my site requires an ID to be passed as a parameter. For example: mysite.com/product/{id}?limit=5 I'm wondering how to pass the 'id' variable in the hx-get attribute. I can utilize AlpineJS or vanilla JS for this tas ...