Construction of rectangle using length and width parameter



I am new to three js. I am trying to create rectangular frame by extruding the profile along rectangular path and for rectangular path i am passing input as length and height of desired rectangular frame.
Now the problem is when i give/pass value of length & height(i.e. 100 X 100 or 100 X 200) the output is not showing expected/correct result.
The corner points get stretched when as the values get changed.
Can anybody suggest any other way to extrude profile along path without the rectangular frame get stretched along corner points?or is there any other function than spline curve because i have tried this already?

Below is the image of rectangular frame(which is not expected)
this the image of expected result

Below is the code i used:

                                    var shape;
				var length=document.getElementById("lenght").value;
				var height=document.getElementById("height").value;
				num = parseInt(length);
				num1 = parseInt(height);
				var closedSpline = new THREE.CatmullRomCurve3( [ new THREE.Vector3(0,0,0), 
									new THREE.Vector3(num,0,0), 
									new THREE.Vector3(num, num1,0), 
									new THREE.Vector3(0, num1,0)] );
					closedSpline.curveType = 'centripetal';
					closedSpline.closed = true;
					closedSpline.tension =0.05;
				var extrudeSettings = {
						steps: 4,
						bevelEnabled: false,
						extrudePath: closedSpline
				var spts = [];
					spts.push(new THREE.Vector2(0, 0));
					spts.push(new THREE.Vector2(10, 10));
					spts.push(new THREE.Vector2(20, 20));
					spts.push(new THREE.Vector2(0,10));
					var shape = new THREE.Shape( spts );
					var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
					mesh1 = new THREE.Mesh( geometry);'frame_sample_1';


This is an interesting approach to create a rectangular frame, using extrusion.

I’d use THREE.Shape() with a hole:

function createFrame(sizeX, sizeY, width){

  let shape = new THREE.Shape([
    new THREE.Vector2(0, 0),
    new THREE.Vector2(sizeX, 0),
    new THREE.Vector2(sizeX, sizeY),
    new THREE.Vector2(0, sizeY)
  let hole = new THREE.Path([
    new THREE.Vector2(width, width),
    new THREE.Vector2(width, sizeY - width),
    new THREE.Vector2(sizeX - width, sizeY - width),
    new THREE.Vector2(sizeX - width, width)
  let shapeGeom = new THREE.ShapeGeometry(shape);
  return shapeGeom


i used your approach ,it help us to control length and height of rectangular geometry.
But still i am facing issue of extrude profiles along a rectangular path. I also modify your code to extrude/sweep my profile along rectangular path but it didn’t work out.

I also check the link you provided, I also have closely related issue as your’s

I need to extrude different profile (refer below image) along path to construct my final photo frame

Below is the image of photo frame with the profile i need

And i need to modify the length and height of same frame with same profile.I tried out scaling but it not useful in my case because i need to maintain the inside boundary of photo frame


Have a look at this thread then:


I have used the code of thread you suggested but still it is not giving expected output photo frame profile. I have used my profile shape in that code but it giving below output

Expected output

I have used below code to extrude frame

var profileShape1 = new THREE.Shape();
profileShape1.moveTo(0, 0);
profileShape1.lineTo(10, 0);
profileShape1.lineTo(5, 10);
profileShape1.moveTo(0, 5);

var contour1 = [
  new THREE.Vector2(0, 0),
  new THREE.Vector2(num, 0),
  new THREE.Vector2(num,num1),
  new THREE.Vector2(0,num1)
  //new THREE.Vector2(1, -1)

var geometry = ProfiledContourGeometry(profileShape1, contour1, true, true);
mesh1= new THREE.Mesh(geometry);


I’ve corrected your code:

var profileShape1 = new THREE.Shape();
profileShape1.moveTo(0, 0);
profileShape1.lineTo(10, 0);
profileShape1.lineTo(5, 10);
profileShape1.lineTo(5, 5);
profileShape1.lineTo(0, 5);


Your code helped me a lot
now i am getting correct results as expected.:blush:


You’re welcome :slight_smile:
Just don’t think about it as of the ultimate solution. It’s just a start point, that needs some modifications and improvements :slight_smile:


i am facing issue while calculating volume of rectangular photo frame(previously discussed geometry).I can find volume of STL file correctly however it is not giving volume of extrude photo frame.
Can you please suggest any logic for volume calculation for extrude geometry.


Maybe, it’s because STL has a non-indexed geometry, and a frame has an indexed one?

What logics did you use for volume calculation for STL?


First i calculated vertices and faces of the given mesh and its count.
Below is the code i used:
function volumeOfT(p1, p2, p3) {
var v321 = p3.x * p2.y * p1.z;
var v231 = p2.x * p3.y * p1.z;
var v312 = p3.x * p1.y * p2.z;
var v132 = p1.x * p3.y * p2.z;
var v213 = p2.x * p1.y * p3.z;
var v123 = p1.x * p2.y * p3.z;
return (-v321 + v231 + v312 - v132 - v213 + v123) / 6.0;
function calculateVolume(mesh){
var volumes = 0.0;
var len = mesh.faces.length;

            for (var i = 0; i < len; i++){
                var Pi = mesh.faces[i].a;
                var Qi = mesh.faces[i].b;
                var Ri = mesh.faces[i].c;
                var P = new THREE.Vector3(mesh.vertices[Pi].x, mesh.vertices[Pi].y, mesh.vertices[Pi].z);
                var Q = new THREE.Vector3(mesh.vertices[Qi].x, mesh.vertices[Qi].y, mesh.vertices[Qi].z);
                var R = new THREE.Vector3(mesh.vertices[Ri].x, mesh.vertices[Ri].y, mesh.vertices[Ri].z);
                volumes += volumeOfT(P, Q, R);
            loadedmeshVolume = Math.abs(volumes);


If I got you correctly, you apply a method that is intended for THREE.Geometry(), whereas the result of profiledContourGeometry() is an indexed THREE.BufferGeometry().


I got your point, to get volume i need to convert THREE.BufferGeometry() to THREE.Geometry()
I have tried to convert using
geometry = new THREE.Geometry().fromBufferGeometry( geometry );

However this approach is not giving me correct value of volume.To figure what is the problem i compare two volumes,
one volume which i get from above geometry and second volume which i get after exporting(to STL fromat) same geometry.
Both volumes are not same which is expected to be same.

Can you suggest where i am going wrong?
According to me there is some geometric parameter missing at the time of converting buffergeometry to geometry.


My point is to use .index property of a buffered geometry and get vertices by indices. There’s no need for conversion from THREE.BufferGeometry() to THREE.Geometry().
Could you provide a live code example?

Here is an example with the simplest profiled contour:
The result is 8 cubic units, as expected.

function calculateVolume(mesh) {

  var volumes = 0.0;
  var len = mesh.geometry.index.count / 3;
  var idx = mesh.geometry.index.array;
  var pos = mesh.geometry.attributes.position.array;
  var P = new THREE.Vector3();
  var Q = new THREE.Vector3();
  var R = new THREE.Vector3();

  for (var i = 0; i < len; i++) {
    let face = i * 3; 
    let Pi = idx[face + 0];
    let Qi = idx[face + 1];
    let Ri = idx[face + 2];
    P.fromArray(pos, Pi * 3);
    Q.fromArray(pos, Qi * 3);
    R.fromArray(pos, Ri * 3);
    volumes += volumeOfT(P, Q, R);
  return Math.abs(volumes);


Your code helped to get exact volume.:slightly_smiling_face:


@sonali_funde You’re welcome :slight_smile: :beers: