Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem keeping a 3D cube correctly roll on its edges using rotate and translate

Please see my js Fiddle here: https://jsfiddle.net/mauricederegt/5ozqg9uL/3/

var xAngle = 0;
var yAngle = 0;
var xPos  = 0;
var yPos  = 0;

$('body').keydown(function(evt) {
    if(evt.keyCode == 37) 
    {
        //left
        yAngle -= 90;
        xPos -= 100;
        //rotate and translate the position of the cube
        $('#cube')[0].style["WebkitTransform"] = "translateX("+xPos+"px) translateY("+yPos+"px) rotateX(" + xAngle + "deg) rotateY(" + yAngle + "deg)";
    }
    if(evt.keyCode == 39) 
    {
        //right
        yAngle -= -90;
        xPos -= -100;
        //rotate and translate the position of the cube
        $('#cube')[0].style["WebkitTransform"] = "translateX("+xPos+"px) translateY("+yPos+"px) rotateX(" + xAngle + "deg) rotateY(" + yAngle + "deg)";
    }
    if(evt.keyCode == 38) 
    {
        //up
        xAngle -= -90;
        yPos -= 100;
        //rotate and translate the position of the cube
        $('#cube')[0].style["WebkitTransform"] = "translateX("+xPos+"px) translateY("+yPos+"px) rotateX(" + xAngle + "deg) rotateY(" + yAngle + "deg)";
    }
    if(evt.keyCode == 40) 
    {
        //down
        xAngle -= 90;
        yPos -= -100;
        //rotate and translate the position of the cube
        $('#cube')[0].style["WebkitTransform"] = "translateX("+xPos+"px) translateY("+yPos+"px) rotateX(" + xAngle + "deg) rotateY(" + yAngle + "deg)";
    }
});
#scene {
    padding: 10px;
    -webkit-perspective: 800;
}

#cube {
    position: relative;
    padding-top: 0;
    margin: 0 auto;
    height: 100px;
    width: 100px;
    -webkit-transition: -webkit-transform 0.4s linear;
    -webkit-transform-style: preserve-3d;

   
}

.face {
    position: absolute;
    height: 85px;
    width: 85px;
    border-style: solid;
    border-width: 5px;
    border-color: grey;
    padding: 5px;
    background-color: rgba(190, 190, 190, 0.7);
}

#cube .one  {
    -webkit-transform: rotateX(90deg) translateZ(50px);
}

#cube .two {
    -webkit-transform: translateZ(50px);
}

#cube .three {
    -webkit-transform: rotateY(90deg) translateZ(50px);
}

#cube .four {
    -webkit-transform: rotateY(180deg) translateZ(50px);
}

#cube .five {
    -webkit-transform: rotateY(-90deg) translateZ(50px);
}

#cube .six {
    -webkit-transform: rotateX(-90deg) translateZ(50px) rotate(180deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!doctype html>
<html>
<body>
<div id="scene">
    Press the arrow keys...
    <div id="cube">
        <div class="face one">
            Face 1
        </div>
        <div class="face two">
            Face 2
        </div>
        <div class="face three">
            Face 3
        </div>
        <div class="face four">
            Face 4
        </div>
        <div class="face five">
            Face 5
        </div>
        <div class="face six">
            Face 6
        </div>
    </div>
</div>
</body>
</html>

As you can see I have a css3 3d cube which you can move by using your arrow keys. You can move it to the left, to the right, up and down. To achieve this I store the position and angle in various vars:

var xAngle = 0;
var yAngle = 0;
var xPos  = 0;
var yPos  = 0;

The cube always "rolls" correctly on its edges going up or down, but for left and right this is not always the case.

Example:

  1. At start press the left arrow key and the right as many times as you like. The cube behaves correctly
  2. Now press down once and then left twice (or right) again. The cube now rolls incorrectly
  3. BUT, if you press up or down again, it rolls correctly again going up or down

So the issue only seems to be with going left or right. How can I fix this?

like image 922
Maurice Avatar asked Mar 25 '21 23:03

Maurice


People also ask

How do you rotate a cube to stand on a corner?

Yes, here's one of several ways to do it. Select the box, then select the rotate tool, Rotate the box 45 degrees on the Y axis, then Rotate the Box 45 degrees on the X axis and you have what you were looking for.

How to perform rotation transformation over cube ‘oabcdefg’?

It is a common convention that is always followed in 3D rotation. Perform Rotation transformation over a cube ‘OABCDEFG’ and rotate it through 45* in the anticlockwise direction about the y-axis. Now, We’ll apply Rotational transformation along (parallel to) y-axis which is:

Why do my 3D prints have rough edges?

Overheating is one of the most common causes behind the 3D prints with rough edges. This is the first thing you should consider whenever you face such a problem.

What is the 3D rotating image previewer cube?

The 3D Rotating Image Previewer cube is an effect in which a set of images appear on the faces of a revolving 3D cube. This effect can be created using HTML and CSS.

How to fix 3D printer cracks and edges?

Those print imperfections contribute to those rough corners and edges that you see in 3D prints. Try to use filament material that is less prone to the problem and can work properly even at low temperatures. Use a material that has better sticking properties. Use filaments that can cool down and become solid quickly. 6.


Video Answer


1 Answers

You need to consider 3 kind of rotations which mean 3 different axis and not 2 like you are doing.

Here is an updated version of your code. Notice how I am updating the angles of an axis based on others axis.

Still not a perfect solution since I found some strange movements (probably some edge cases I missed) but a good starting point.

var xAngle = 0;
var yAngle = 0;
var zAngle = 0;
var xPos = 0;
var yPos = 0;

$('body').keydown(function(evt) {
  if (evt.keyCode == 37) {
    //left
    if (xAngle % 180 == 0)
      yAngle -= 90;
    else
      zAngle -= 90;
    xPos -= 100;
  }
  if (evt.keyCode == 39) {
    //right
    if (xAngle % 180 == 0)
      yAngle -= -90;
    else
      zAngle -= -90;

    xPos -= -100;
  }
  if (evt.keyCode == 38) {
    //up
    if (yAngle % 180 == 0)
      xAngle -= -90;
    else
      zAngle -= -90;
    yPos -= 100;
  }
  if (evt.keyCode == 40) {
    //down
    if (yAngle % 180 == 0)
      xAngle -= 90;
    else
      zAngle -= 90;
    yPos -= -100;
  }
  $('#cube').css('transform', "translateX(" + xPos + "px) translateY(" + yPos + "px) rotateX(" + xAngle + "deg) rotateY(" + yAngle + "deg) rotateZ(" + zAngle + "deg)");
});
#scene {
  padding: 10px;
  perspective: 800;
}

#cube {
  position: relative;
  padding-top: 0;
  margin: 0 auto;
  height: 100px;
  width: 100px;
  transition: transform 0.4s linear;
  transform-style: preserve-3d;
}

.face {
  position: absolute;
  height: 85px;
  width: 85px;
  border-style: solid;
  border-width: 5px;
  border-color: grey;
  padding: 5px;
  background-color: rgba(190, 190, 190, 0.7);
}

#cube .one {
  transform: rotateX(90deg) translateZ(50px);
}

#cube .two {
  transform: translateZ(50px);
}

#cube .three {
  transform: rotateY(90deg) translateZ(50px);
}

#cube .four {
  transform: rotateY(180deg) translateZ(50px);
}

#cube .five {
  transform: rotateY(-90deg) translateZ(50px);
}

#cube .six {
  transform: rotateX(-90deg) translateZ(50px) rotate(180deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="scene">
  Press the arrow keys...
  <div id="cube">
    <div class="face one">
      Face 1
    </div>
    <div class="face two">
      Face 2
    </div>
    <div class="face three">
      Face 3
    </div>
    <div class="face four">
      Face 4
    </div>
    <div class="face five">
      Face 5
    </div>
    <div class="face six">
      Face 6
    </div>
  </div>
</div>
like image 128
Temani Afif Avatar answered Oct 16 '22 12:10

Temani Afif