在(CSS-变换)点旋转之前计算坐标

Calculate coordinates before (CSS-transform) rotation of point

我想做的事: 给一个 javascript 函数一个 3d 房间中三角形的坐标作为参数,它计算 svg 路径和 css 这个对象的变换角度。

我已经想通了:

但后来我失败了。 我能够计算结果点 Pr(x|y|z) 的 Z 角和 Y 角,原点 Po(x|0) 在平面 x-y 上。 我的想法是 'fix' x 轴上的一个三角形点,然后绕 x 轴旋转......但无论如何 - 它不起作用。我以为 x 轴先旋转,但事实并非如此。


所以我需要的是给定(结果)point/triangle的未知变换矩阵及其原点三角形,可以认为是给定的,其中结果三角形位于三维房间,原点三角形在二维房间(一条svg路径)。

我真的不知道,我在 11 年级,所以对我来说有点困难。

非常感谢您的帮助!乔纳斯

终于,在经历了几天太无聊的课程之后,这是我的解决方案!

  1. 实际上你可以决定先应用哪个 CSS 变换: rotateY(~deg) rotateX(~deg) 首先绕 Y 轴旋转,然后绕 x 轴旋转.警告!坐标系的轴随着你的对象一起旋转。

这里有一个动画来向您展示我的意思:ext. link。 通常,您会期望在 Y 轴和 Z 轴旋转后 x 轴仍然在原位,但它随着 Object/SVG 旋转。所以你是绕物体的轴旋转。

  1. 不需要转换矩阵: 最后,我计算了 Y 轴和 Z 轴旋转的角度以移动第一个点 P1(x|y|z)P1'(x|0|0)。现在,通过简单的 X 轴旋转,我能够将第二个点的 z 值设置为零。最后一次应用 X 轴旋转,P1 的坐标不会改变,因为它固定在 x 轴上。

这是我的最终代码。特意给你一个有调试日志的,这样你应该能更好地理解它。

$(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>