LepBJ
LepBJ

Reputation: 41

Calculate coordinates before (CSS-transform) rotation of point

What I want to do: Give a javascript function the coordinates for a triangle in a 3d-room as parameter and it calculates the svg path and the css transformation angles for this object.

What I've already figured out:

But then I've failed. I was able to calculate the Z- and Y-angles for a resulting point Pr(x|y|z) with a origin point Po(x|0) on the plane x-y. My thought was to 'fix' one triangle point on the x-axis, and then rotate around the x-axis ... but anyway - it's not working. I thought the x-axis gets rotated first, but thats not the case.


So what I need is the unknown transformation Matrix for given (resulting) point/triangle and its origin triangle, which can be considered as given, where the resulting triangle is located in the three-dimensional room, the origin triangle is in the two-dimensional room (a svg path).

I really don't have a clue, I'm in the 11th grade so it's kind of difficult to figure it out for me.

Thanks a lot for any kind of help! Jonas.

Upvotes: 0

Views: 1437

Answers (1)

LepBJ
LepBJ

Reputation: 41

Finally, after a few days with too boring lessons, here my solution!

  1. Actually you can decide which CSS transformation should be applied first: rotateY(~deg) rotateX(~deg) rotates firstly around the Y-axis, then around the x-axis. Caution! The axis of the coordinate system get rotated, together with you object.

Here an animation to show you what I mean: ext. link. Normally, you would expect that the x-axis is still in place after a Y- and Z- rotation, but it gets rotated with the Object/SVG. So you are rotating around the axis of the object.

  1. There is no need for an transformation matrix: At the end, I calculated the angles for the Y- and Z-rotation to move the first point P1(x|y|z) to P1'(x|0|0). Now with a simple X-rotation I was able to set the z-value of the second point to zero. Applying the X-rotation as the last one, the coordinates of P1 do not change, since it is fixed on the x-axis.

So here my final code. Intentionally, I will give you the one with debugging logs, so you are probably able to understand it better.

$(document).ready(function() {
  calcTransf(80, 20, 40, 40, 100, 100);
});

function calcTransf(x1, y1, z1, x2, y2, z2) {

  $(".cube").append('<svg class="C_R0"><path fill="rgba(80, 204, 04, 0.5)" stroke-width="0" d="M0,0 L20,20 L20,0 Z"></path></svg>');
  $(".cube").append('<svg class="C_R1"><path fill="rgba(80, 204, 04, 0.5)" stroke-width="0" d="M0,0 L20,20 L20,0 Z"></path></svg>');
  $(".cube").append('<svg class="C_R2"><path fill="rgba(80, 204, 04, 0.5)" stroke-width="0" d="M0,0 L20,20 L20,0 Z"></path></svg>');
  $(".C_R0").css("transform", "translateX(0px) translateY(0px) translateZ(0px) rotateX(0deg) rotateY(0deg) rotateZ(0deg)");
  $(".C_R1").css("transform", "translateX(" + x1 + "px) translateY(" + y1 + "px) translateZ(" + z1 + "px) rotateX(0deg) rotateY(0deg) rotateZ(0deg)");
  $(".C_R2").css("transform", "translateX(" + x2 + "px) translateY(" + y2 + "px) translateZ(" + z2 + "px) rotateX(0deg) rotateY(0deg) rotateZ(0deg)");

  var Yalpha = -Math.atan2(z1, x1);
  var LX = Math.sqrt(Math.pow(z1, 2) + Math.pow(x1, 2));

  x1 = LX;
  y1 = y1;
  z1 = 0;

  DEGYalpha = Yalpha / Math.PI * 180;
  console.log("Yalpha " + DEGYalpha);

  var Zalpha = Math.atan2(y1, x1);
  var LX = Math.sqrt(Math.pow(y1, 2) + Math.pow(x1, 2));

  x1 = LX;
  y1 = 0;
  z1 = 0;

  DEGZalpha = Zalpha / Math.PI * 180;
  console.log("Zalpha " + DEGZalpha);

  /* -----------------2. Punkt-------------------*/

  var x2Ay = x2 * Math.cos(Yalpha) - z2 * Math.sin(Yalpha);
  var z2Ay = z2 * Math.cos(Yalpha) + x2 * Math.sin(Yalpha);

  x2 = x2Ay;
  y2 = y2;
  z2 = z2Ay;

  console.log("Ay: " + x2 + " " + y2 + " " + z2);

  Zalpha = -Zalpha;
  var x2Az = x2 * Math.cos(Zalpha) - y2 * Math.sin(Zalpha);
  var y2Az = y2 * Math.cos(Zalpha) + x2 * Math.sin(Zalpha);

  x2 = x2Az;
  y2 = y2Az;
  z2 = z2;

  console.log("Az: " + x2 + " " + y2 + " " + z2);

  //Winkel z-y

  var Xalpha = Math.atan2(z2, y2);
  DEGXalpha = Xalpha / Math.PI * 180;
  console.log("Xalpha " + DEGXalpha);

  var z2Ax = z2 * Math.cos(Xalpha) - y2 * Math.sin(Xalpha);
  var y2Ax = y2 * Math.cos(Xalpha) + z2 * Math.sin(Xalpha);

  x2 = x2;
  y2 = y2Ax;
  z2 = z2Ax;

  console.log("Ax: " + x2 + " " + y2 + " " + z2);

  $(".cube").append('<svg class="C_RE"><path fill="rgba(80, 4, 4, 0.5)" stroke-width="0" d="M0,0 L' + x1 + ',0 L' + x2 + ',' + y2 + ' Z"></path></svg>');
  $(".C_RE").css("transform", 'translateX(0px) translateY(0px) translateZ(0px) rotateY(' + DEGYalpha + 'deg) rotateZ(' + DEGZalpha + 'deg) rotateX(' + DEGXalpha + 'deg)');

}
body {
	margin: 0; 
	height: 100%; 
	width: 100%;
	perspective: 500px;
}

.center {
	transform-style: preserve-3d;
	transform: translateX(50px) translateY(50px) translateZ(0px) rotateX(0deg) rotateY(0deg) rotateZ(0deg);
}

.cube {
	transform-style: preserve-3d;
	transform: translateX(0px) translateY(0px) translateZ(0px) rotateX(0deg) rotateY(0deg) rotateZ(0deg);
}

svg {
	transform-origin: left top;
	position: absolute;
	height: 150px;
	width: 150px;
}
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>

<body style="height: 150px; width: 150px;">

  <div class="center" style="height: 50px; width: 50px;">
    <div class="cube" style="height: 50px; width: 50px;">

    </div>
  </div>

</body>

</html>

Upvotes: 3

Related Questions