# Diagonal Edge Touching

**URL:** <https://discourse.threejs.org/t/diagonal-edge-touching/72451>\
**Category:** Questions\
**Tags:** geometry\
**Created:** [October 5, 2024, 6:31pm UTC](https://discourse.threejs.org/t/diagonal-edge-touching/72451 "2024-10-05T18:31:10Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kevalv](https://avatars.discourse-cdn.com/v4/letter/k/82dd89/32.png) [@Kevalv](https://discourse.threejs.org/u/Kevalv)\
**Post date:** [October 5, 2024, 6:31pm UTC](https://discourse.threejs.org/t/diagonal-edge-touching/72451/1 "2024-10-05T18:31:10Z")

</div>

Hello everyone, this is my first time posting on this so excuse my unfamiliarity. The issue I’m having is I am trying to have 7 cubes in which they are translated vertically. Then they are rotated by 20 degrees with respect to each other. Then I need to exactly have the edges of the cubes touch. What I mean is I need the bottom right edge of the next cube to touch the top left edge of the previous cube. Heres my code to attempt to do that, which is fairly close, however not exact.

```javascript

function touchingCornerTranslationMatrix(modelTransformation, p) {
    const l = p/6;
    // Define local positions for top-right and bottom-left corners of the cube in local space
    const bottomLeft = new THREE.Vector3(-l, -l, 0); // Bottom-left corner in local space
    const topRight = new THREE.Vector3(l, l, 0); // Top-right corner in local space

    // Apply the current transformation matrix to both corners
    bottomLeft.applyMatrix4(modelTransformation);
    topRight.applyMatrix4(modelTransformation);

    // Compute the translation needed to align bottom-left of next cube with top-right of previous cube
    const xTranslation = topRight.x - bottomLeft.x;
    const yTranslation = topRight.y - bottomLeft.y;

    // Return the translation matrix to apply
    return translationMatrix(xTranslation, yTranslation, 0); // Use positive translations
}

```

And heres my implementation of it also including the rotation and translation, which must be done first.

```javascript
const rotation = rotationMatrixZ(20 * Math.PI/180); //rotation matrix by 20 degrees
const translation = translationMatrix(0, 2*l, 0); // Translate 2l units in the y direction
let model_transformation = new THREE.Matrix4(); // model transformation matrix we will update
let previousPosition = new THREE.Vector3();
let touching = touchingCornerTranslationMatrix(model_transformation, l);

for (let i = 0; i < cubes.length; i++) {

    //change to matrix.copy
	cubes[i].matrix.copy(model_transformation);
    //shifting vertically
    model_transformation.multiplyMatrices(translation, model_transformation); 
    //rotating by 20 degrees
    model_transformation.multiplyMatrices(rotation, model_transformation); 
    //shifting it so that they now touch corners
    model_transformation.multiplyMatrices(touching, model_transformation);

    //for debugging 
    let position = new THREE.Vector3();
    position.setFromMatrixPosition(model_transformation);
    console.log("Current Position: ", position);
    console.log("Previous Position: ", previousPosition);
    console.log(" ");

    previousPosition.copy(position);

}

```

 ![Screenshot 2024-10-05 110928](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/e/1/e18d7d80c6073e448d1a53ab570b276578126285.png)

The console.log statements are just for debugging however, they aren’t really much help to my untrained eye. Any help would be appreciated. Thanks in advance!

---

<div class="post-metadata">

**Author:** ![PavelBoytchev](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/pavelboytchev/32/38639_2.png) [@PavelBoytchev](https://discourse.threejs.org/u/PavelBoytchev)\
**Post date:** [October 5, 2024, 7:00pm UTC](https://discourse.threejs.org/t/diagonal-edge-touching/72451/2 "2024-10-05T19:00:05Z")

</div>

What does happen if you try with 45° instead of 20°? Does the result provide any clues? Does the mismatch depend on the angle between two cubes?

If I had to do something like this, I’d chain the cubes, so they have their edges connected by design. The following demo does not resolve your problem, it only demonstrates an alternative way.

[https://codepen.io/boytchev/full/ZEgOexb](https://codepen.io/boytchev/full/ZEgOexb)

[![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/c/8/c8a8cb4d344d5b8e2ac9278a086407d23b087f3b.png)](https://codepen.io/boytchev/full/ZEgOexb)

Also: [this](https://www.writing-skills.com/thanks-in-advance-no-thank-you) and [that](https://web.archive.org/web/20220930131230/https://macademic.org/2011/06/08/never-end-your-email-with-thanks-in-advance/)

---

<div class="post-metadata">

**Author:** ![Kevalv](https://avatars.discourse-cdn.com/v4/letter/k/82dd89/32.png) [@Kevalv](https://discourse.threejs.org/u/Kevalv)\
**Post date:** [October 5, 2024, 7:20pm UTC](https://discourse.threejs.org/t/diagonal-edge-touching/72451/3 "2024-10-05T19:20:03Z")

</div>

The mismatch does depend on the angle because, if I do change the angle to 45, then I get the following. Chaining does seem to be exact answer I was looking for. May I ask how did you chain the cubes together? I’m a beginner so I can’t really tell where the chaining together comes into play, in the code.

 ![Screenshot 2024-10-05 121532](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/b/5/b5a3e698d74a6d9f560ceab56da652ede225e964.png)

---

<div class="post-metadata">

**Author:** ![vielzutun.ch](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/vielzutun.ch/32/21366_2.png) [@vielzutun.ch](https://discourse.threejs.org/u/vielzutun.ch)\
**Post date:** [October 6, 2024, 7:44am UTC](https://discourse.threejs.org/t/diagonal-edge-touching/72451/4 "2024-10-06T07:44:45Z")

</div>

This is actually a 2D problem.

If you rotate a rigid body (shape, mesh, whatever) about a fixed point/axis, all its points are rotated about the same angle, like so (rotation about coordinate origin, for simplicity):

 ![scetch](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/b/2/b21ff1a9d4f940070cfc245c506f6affda1d7cd3.png)

black square: initial state  
blue square: rotated about origin by 20°  
red square: rotated and translated such as lower **left** corner of rotated square aligns with upper **left** corner of original square.

Note how each rotation involves an **_implicit_** translation of points along an arc about the center of rotation, marked as thin arrows in the sketch. Translation vector is shown as dashed red arrow.

For a perfect alignment, you’ll need to account for that implicit translation, too. [**See this**](https://academo.org/demos/rotation-about-point/), for the mathematics involved.

---

<div class="post-metadata">

**Author:** ![grml](https://avatars.discourse-cdn.com/v4/letter/g/e36b37/32.png) [@grml](https://discourse.threejs.org/u/grml)\
**Post date:** [October 6, 2024, 9:18am UTC](https://discourse.threejs.org/t/diagonal-edge-touching/72451/5 "2024-10-06T09:18:52Z")

</div>

Pavel’s approach boils down to this:

(1) Shift the geometry to move the pivot point from the center of the box to the lower left edge:  
`var geometry = new THREE.BoxGeometry( 1, 1, 1 ).translate(0.5,0.5,0),`  
The box will now rotate around that edge.

(2) make each box the child of the previous one (that’s the “chaining”):  
`cubes[i-1].add( cubes[i] );`  
The boxes are now in a hierarchy; rotating one box will propagate the rotation to all children.

(3) rotate each box (bar the first one) around the z axis by 20° to get your desired result:  
`cubes[i].rotation.z = 20 * (Math.PI / 180)`

(NB: the “move the boxes upwards” step is missing from this explanation; I’ll leave it as an exercise for the reader)

---

<div class="post-metadata">

**Author:** ![vielzutun.ch](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/vielzutun.ch/32/21366_2.png) [@vielzutun.ch](https://discourse.threejs.org/u/vielzutun.ch)\
**Post date:** [October 6, 2024, 9:45am UTC](https://discourse.threejs.org/t/diagonal-edge-touching/72451/6 "2024-10-06T09:45:54Z")

</div>

Admitted, @PavelBoytchev’s approach is a very elegant solution that avoids math (almost) altogether.

---

<div class="post-metadata">

**Author:** ![trueshko](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/trueshko/32/26031_2.png) [@trueshko](https://discourse.threejs.org/u/trueshko)\
**Post date:** [October 6, 2024, 2:54pm UTC](https://discourse.threejs.org/t/diagonal-edge-touching/72451/7 "2024-10-06T14:54:22Z")

</div>

All mathematics is there “under the hood”🙂

---

<div class="post-metadata">

**Author:** ![trueshko](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/trueshko/32/26031_2.png) [@trueshko](https://discourse.threejs.org/u/trueshko)\
**Post date:** [October 6, 2024, 3:17pm UTC](https://discourse.threejs.org/t/diagonal-edge-touching/72451/8 "2024-10-06T15:17:49Z")

</div>

> [@Kevalv](#):
>
> how did you chain the cubes together? I’m a beginner so I can’t really tell where the chaining together comes into play, in the code.

Each next cube added to the previous, thus the transformation of the previous one is applied to it. The cube geometry is shifted in such a way that its center point is on the edge with which the cube touches the previous one (`translate(0.5,0.5,0)` in line 47), so when it is rotated, this edge will remain stationary, stuck to the edge of the previous one.

---

<div class="post-metadata">

**Author:** ![Kevalv](https://avatars.discourse-cdn.com/v4/letter/k/82dd89/32.png) [@Kevalv](https://discourse.threejs.org/u/Kevalv)\
**Post date:** [October 7, 2024, 12:31am UTC](https://discourse.threejs.org/t/diagonal-edge-touching/72451/9 "2024-10-07T00:31:16Z")

</div>

Yep following that logic I did get the corners to touch, I then scaled them, and I believe I did the hierarchy correctly, so that the cubes are now “chained” together. Now flipping this problem a bit. I want to animate the 20 degree rotation, that I did previously.

```javascript
let cubes = [];
for (let i = 0; i < 7; i++) {
    let cube = new THREE.Mesh(custom_cube_geometry, phong_material);
    cube.matrixAutoUpdate = false;
    cubes.push(cube);
    scene.add(cube);
}

// TODO: Transform cubes
// Translate the cubes.
const rotation = rotationMatrixZ(20 * Math.PI / 180); // Rotate by 20 degrees around Z-axis
const translation = translationMatrix(0, 2 * l, 0); // Translate 2l units in the y-direction
const translationTest = translationMatrix(0.141, 0.03, 0); // Adjust translation for corner touch
const scaler = scalingMatrix(1, 1.5, 1); // Scale height by 1.5
let model_transformation = new THREE.Matrix4(); // Initialize transformation matrix

for (let i = 0; i < cubes.length; i++) {
    if (i === 0) {
        // Apply initial transformation to the first cube
        model_transformation.identity(); // Reset to identity for the first cube
        //model_transformation.multiplyMatrices(scaler, model_transformation); // Scale the first cube
        cubes[i].matrix.copy(model_transformation); // Copy the transformation to the first cube
    } else {
        // Chain transformations for subsequent cubes
        model_transformation.multiplyMatrices(translation, model_transformation); // Translate by 2l units
        model_transformation.multiplyMatrices(rotation, model_transformation); // Rotate by 20 degrees
        model_transformation.multiplyMatrices(translationTest, model_transformation); // Adjust translation for corner touch
        model_transformation.multiplyMatrices(scaler, model_transformation); // Scale height of the cube
        cubes[i].matrix.copy(model_transformation); // Copy the chained transformation to each cube
    }

    // Debugging: Print the position of each cube
    const position = new THREE.Vector3();
    position.setFromMatrixPosition(cubes[i].matrix);
    console.log(`Cube ${i} Position: `, position);
}

```

The above is my static Cube code, which I want to animate. I tried to do something like the following, where I then pasted my for loop inside the animate function.

```javascript
let animation_time = 0;
let delta_animation_time;
let rotation_angle;
const clock = new THREE.Clock();
const MAX_ANGLE = 20 * Math.PI / 360; // 20 degrees converted to radians
const T = 3; // Oscillation period in seconds
const MAX_TRANSLATION_X = 1.5;

function animate() {
    delta_animation_time = clock.getDelta();
    animation_time += delta_animation_time;

    // Sinusoidal movement for rotation (between 0 and -20 degrees), because trying to move it 20 degrees from the previous cube and then back. 
    rotation_angle = -MAX_ANGLE * Math.sin((2 * Math.PI / T) * animation_time);

    // Render the scene and update controls
    renderer.render(scene, camera);
    controls.update();

    // Continue the animation
    requestAnimationFrame(animate);
}

renderer.setAnimationLoop(animate);

```

However this doesn’t accomplish what I want for one main reason. Each of the cubes seem to rotate independently of each other. Not from the corners touching which leads me to believe that I did the hierarchy incorrectly. I’ve attached a screenshot of what my static code looks like. Note that I have also scaled the cubes by a factor of 1.5.

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/8/9/896d262d5c27701fa7d9df37f74b5c4f8f4ef1fb.png)
