在(CSS-变换)点旋转之前计算坐标
Calculate coordinates before (CSS-transform) rotation of point
我想做的事: 给一个 javascript 函数一个 3d 房间中三角形的坐标作为参数,它计算 svg 路径和 css 这个对象的变换角度。
我已经想通了:
- 要计算这 3 个点之间的三角形,我只需要计算它所有 3 个边在房间中的长度。然后我就可以在 x-y 坐标系中绘制它(角度可以用 3 边计算)
- 此外,我需要三角形必须旋转的角度才能达到我想要的结果
- 为此,我将三角形的一个点定义为变换的原点
(0|0|0)
,稍后可以平移。
但后来我失败了。
我能够计算结果点 Pr(x|y|z)
的 Z 角和 Y 角,原点 Po(x|0)
在平面 x-y
上。
我的想法是 'fix' x 轴上的一个三角形点,然后绕 x 轴旋转......但无论如何 - 它不起作用。我以为 x 轴先旋转,但事实并非如此。
所以我需要的是给定(结果)point/triangle的未知变换矩阵及其原点三角形,可以认为是给定的,其中结果三角形位于三维房间,原点三角形在二维房间(一条svg路径)。
我真的不知道,我在 11 年级,所以对我来说有点困难。
非常感谢您的帮助!乔纳斯
终于,在经历了几天太无聊的课程之后,这是我的解决方案!
- 实际上你可以决定先应用哪个 CSS 变换:
rotateY(~deg) rotateX(~deg)
首先绕 Y 轴旋转,然后绕 x 轴旋转.警告!坐标系的轴随着你的对象一起旋转。
这里有一个动画来向您展示我的意思:ext. link。
通常,您会期望在 Y 轴和 Z 轴旋转后 x 轴仍然在原位,但它随着 Object/SVG 旋转。所以你是绕物体的轴旋转。
- 不需要转换矩阵: 最后,我计算了 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>
我想做的事: 给一个 javascript 函数一个 3d 房间中三角形的坐标作为参数,它计算 svg 路径和 css 这个对象的变换角度。
我已经想通了:
- 要计算这 3 个点之间的三角形,我只需要计算它所有 3 个边在房间中的长度。然后我就可以在 x-y 坐标系中绘制它(角度可以用 3 边计算)
- 此外,我需要三角形必须旋转的角度才能达到我想要的结果
- 为此,我将三角形的一个点定义为变换的原点
(0|0|0)
,稍后可以平移。
但后来我失败了。
我能够计算结果点 Pr(x|y|z)
的 Z 角和 Y 角,原点 Po(x|0)
在平面 x-y
上。
我的想法是 'fix' x 轴上的一个三角形点,然后绕 x 轴旋转......但无论如何 - 它不起作用。我以为 x 轴先旋转,但事实并非如此。
所以我需要的是给定(结果)point/triangle的未知变换矩阵及其原点三角形,可以认为是给定的,其中结果三角形位于三维房间,原点三角形在二维房间(一条svg路径)。
我真的不知道,我在 11 年级,所以对我来说有点困难。
非常感谢您的帮助!乔纳斯
终于,在经历了几天太无聊的课程之后,这是我的解决方案!
- 实际上你可以决定先应用哪个 CSS 变换:
rotateY(~deg) rotateX(~deg)
首先绕 Y 轴旋转,然后绕 x 轴旋转.警告!坐标系的轴随着你的对象一起旋转。
这里有一个动画来向您展示我的意思:ext. link。 通常,您会期望在 Y 轴和 Z 轴旋转后 x 轴仍然在原位,但它随着 Object/SVG 旋转。所以你是绕物体的轴旋转。
- 不需要转换矩阵: 最后,我计算了 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>