Align plane and ring geometries together

Hi, I´m new in the threejs world.
I’ve been looking for a solution since 3 days and
I can´t find any help on Google or in this forum :frowning:

I try to create an interactive part designer.
For this, I want to generate plane and ring geometries, but how can I connect them easy as possible together.
In my example, I translate the geometries by hand manually… And that is the problem.

The my “part-parameters” are changing constantly.


function main() {

  // Hilfs-Koordinatensystem
  let scene = new THREE.Scene();
  scene.add(new THREE.AxesHelper(10)); //X=red, Y=green, Z=blue

  // Part Parameters
  const biegelaenge = 500; // for extrude, later
  const dicke = 2; // Thickness from my part
  const radius = 2; // radius inside
  const B0_schenkel = 10;
  const B0_winkel = 90; // B = Bug
  const B1_schenkel = 5;
  const B1_winkel = 45;
  const B2_schenkel = 6;
  const B2_winkel = 0; // do not exist!
  //const B3_schenkel = 0;
  //const B3_winkel = 0;
  //const B4_....

  // Length Bug0
  B0 = schenkel(B0_schenkel, dicke);

  // Radius Bug0, must write a function, but later
  const geometry = new THREE.RingGeometry(
    radius + dicke,
  const material = new THREE.MeshPhongMaterial({
    color: "rgb(80,80,20)",
    side: THREE.DoubleSide,
  const mesh = new THREE.Mesh(geometry, material);

  // Length Bug1
  B1 = schenkel(B1_schenkel, dicke);

  // Radius Bug1
  const geometry2 = new THREE.RingGeometry(
    radius + dicke,
  const material2 = new THREE.MeshPhongMaterial({
    color: "rgb(80,80,20)",
    side: THREE.DoubleSide,
  const mesh2 = new THREE.Mesh(geometry2, material2);

  // Length Bug2
  B2 = schenkel(B2_schenkel, dicke);

  // Radius Bug2
  // do not exist!

  // Extrude geometry here, later

  //Grid XZ
  let grid = new THREE.GridHelper(100, 100, 0xffffff, 0x333333);

  // Random light sources
  let pL0 = generatePointLight(0xffffff, 1, false, 5, 5, 5);
  let pL1 = generatePointLight(0xffffff, 1, false, -5, 5, 5);
  let pL2 = generatePointLight(0xffffff, 1, false, 5, 5, -5);
  let pL3 = generatePointLight(0xffffff, 1, false, -5, 5, -5);

  let PersCam = new THREE.PerspectiveCamera(
    window.innerWidth / window.innerHeight,
  console.log(window.innerWidth / window.innerHeight);

  // Cameraposition
  PersCam.position.x = 0; // red
  PersCam.position.y = 0; // green
  PersCam.position.z = 50; // blue
  // Blickrichtung von Kamera, irgendwie keine funktion
  PersCam.lookAt(new THREE.Vector3(0, 0, 0));

  // Camerahelper, for orthogonal camera, later
  // let  camhelper = new THREE.CameraHelper( PersCam );
  // scene.add( camhelper );

  // Renderer
  let renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.shadowMap.enabled = false; // Schatten an/aus
  renderer.setSize(window.innerWidth, window.innerHeight); // Fenstergröße
  renderer.setClearColor("rgb(80,80,80)"); // Background olor
  document.getElementById("webgl").appendChild(renderer.domElement); // Wo im HTML Code
  let controls = new THREE.OrbitControls(PersCam, renderer.domElement); // Orbit controls

  // Update animation
  update(renderer, scene, PersCam, controls);

////////////// FUNKTIONEN ////////////////////////////////
function schenkel(l, b) {
  let geo = new THREE.PlaneGeometry(l, b);
  let mat = new THREE.MeshPhongMaterial({
    color: "rgb(80,60,60)",
    side: THREE.DoubleSide,
  let mesh = new THREE.Mesh(geo, mat);
  //mesh.receiveShadow = true;
  return mesh;
/*function generateBox(w, h, d) {
  let geo = new THREE.BoxGeometry(w, h, d);
  let mat = new THREE.MeshPhongMaterial({
    color: "rgb(100,10,10)",
  let mesh = new THREE.Mesh(geo, mat);
  mesh.castShadow = true;
  return mesh;
function generatePointLight(color, intensity, shadowTgl, x, y, z) {
  let light = new THREE.PointLight(color, intensity);
  light.castShadow = shadowTgl; // Schatten an/aus
  light.position.x = x;
  light.position.y = y;
  light.position.z = z;
  light.shadow.mapSize.width = 2048;
  light.shadow.mapSize.height = 2048;
  return light;
function deg2rad(deg) {
  rad = deg * (Math.PI / 180.00);
  return rad;
function update(renderer, scene, camera, controls) {
  renderer.render(scene, camera);
  requestAnimationFrame(function () {
    update(renderer, scene, camera, controls);
  }); // funktion vom Browser!

/// Backyard //
//setInterval, use later // ist für Updates von Werten gut, z.B. bei der Tabelle

obviously you will need to invoke the magic power of geometry. first, you will need to intersect two lines perpendicular to the brown segments to find the ring center. and then you have to calculate angles from that point to brown segments ends.

This should work similar to the Cylinder.

From the Collection of examples from



With bones CustomCylinderAndKnee

Hi, the examples are very good, but I´m just in the beginning.
I can’t use an example code for my code yet, it´s to high.

My current solution would be:

  1. I read the absolute position corner points from the (older) plane geometrie back.
  2. after that I translate the newer plane corner point in X,Y to the older plane corner point together.
  3. then I rotate in the corner point the angle difference, so that the geometries are parallel together.
  4. I repeat 1-3, for all the planes I want to create.
  5. lastly I group the correct aligned planes, mesh… scene.add(groups).

@all: Do you think that’s ok, or is this way too complicated?

For now:
how can I read the position.array ?

const geometry = new THREE.PlaneGeometry( 1, 1, 12, 12 );

i = 5; // for example
const valueOfIndex5  =  geometry.attributes.position.array[  i  ];
1 Like

const arrNew = B0Ks.getAttribute(“position”).array;

ok i got it :slight_smile: thanks.

my next problem is, can I extrude geometrys too?

let PlGeo = new THREE.PlaneGeometry(5, 10);
  var geometry = new THREE.ExtrudeGeometry(PlGeo, {
    depth: 5,
    // bevelEnabled: false,
  const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
  const mesh = new THREE.Mesh(geometry, material);

does that mean i can only extrude shapes? And not PlaneGeometry?

Yes, correct.

If I had known that before…
Ok, if I generate multiple shapes, add them together like my first post.
Then translate the shapes in +Z and (copy) the shapes in -Z, can I extrude or “shaping” them like this?

If you look at the code ( three.js/ExtrudeGeometry.js at c12c9a166a1369cdd58622fff2aff7e3a84305d7 · mrdoob/three.js · GitHub ) you will see that extrusion is quite a complex thing.

If you want to have a very special geometry, you have to create it yourself as a custom geometry. This is not that hard with a little practice. Start with a simple example and look at corresponding examples.

From the Collection of examples from

e.g. ProfileSurface , ColorStripeChanging




BumblebeeMara ( geometryMouth, geometryBody, halfSphereGeometry )


MorphBoxSphere (dynamic)

… and more.

1 Like

I think must start from the beginning.
But before a last question.
Is it possible to create an outer contour which I can then extrude?

In a way, yes, but you have to generate it yourself.

Curved2Geometry - a twofold curved geometry
ProfiledContourGeometry MultiMaterial
Construction of frames with contour/profile

1 Like

Hi folks,
in this example: ProfiledContourGeometry

I get following warnings,

can somebody help me.

Best regards

in retrospect, it is funny that my comment was accepted as a solution. the procedure outlined there only works for line segments specifically placed so that there could be an arc joining them, but then its center has to be known in advance

The tread was, aligning plane and ring geometries.
Find vertices, calculate distance, move Geometries together… finish!