81

rotateX(50deg) rotateY(20deg) rotateZ(15deg)速記で組み合わせる方法はrotate3d()

4

4 に答える 4

315

rotateX(50deg)と同等ですrotate3d(1, 0, 0, 50deg)

rotateY(20deg)と同等ですrotate3d(0, 1, 0, 20deg)

rotateZ(15deg)と同等ですrotate3d(0, 0, 1, 15deg)

そう...

rotateX(50deg) rotateY(20deg) rotateZ(15deg)

と同等です

rotate3d(1, 0, 0, 50deg) rotate3d(0, 1, 0, 20deg) rotate3d(0, 0, 1, 15deg)


ジェネリックrotate3d(x, y, z, α)の場合、行列があります

一般的な回転行列

どこ

説明


3 つの変換のそれぞれの行列を取得し、rotate3dそれらを乗算します。結果の行列は、結果の single に対応する行列ですrotate3d。そこから値を抽出するのが簡単かどうかはわかりませんrotate3dが、単一の の値を抽出するのは確かに簡単matrix3dです。


最初のケース (rotateX(50deg)またはrotate3d(1, 0, 0, 50deg)) では、次のようになります。

x = 1y = 0z = 0α = 50deg

したがって、この場合の行列の最初の行は です1 0 0 0

二つ目は0 cos(50deg) -sin(50deg) 0.

3 つ目0 sin(50deg) cos(50deg) 0

そして 4 つ目は明らかに0 0 0 1.


2 番目のケースではx = 0y = 1z = 0、がありα = 20degます。

最初の行: cos(20deg) 0 sin(20deg) 0.

2 行目: 0 1 0 0.

3 行目: -sin(20) 0 cos(20deg) 0.

第4:0 0 0 1


3 番目のケースではx = 0y = 0z = 1、がありα = 15degます。

最初の行: cos(15deg) -sin(15deg) 0 0.

二行目sin(15deg) cos(15deg) 0 0

そして、3 行目と 4 行目はそれぞれ0 0 1 0and0 0 0 1です。


: 回転 Y 変換の sin 値の符号が、他の 2 つの変換とは異なることに気付いたかもしれません。計算ミスではありません。これは、画面の y 軸が上ではなく下を向いているためです。


したがって、これらは、結果として得られる単一の変換4x4の行列を取得するために乗算する必要がある 3 つの行列です。前述したように、4 つの値を取得するのがどれほど簡単かはわかりませんが、4x4 マトリックスの 16 要素は、連鎖変換と同等の 16 パラメーターとまったく同じです。4x4rotate3dmatrix3d


編集

実際、それは非常に簡単であることがわかりました...行列のトレース (対角要素の合計) を計算しますrotate3d

4 - 2*2*(1 - cos(α))/2 = 4 - 2*(1 - cos(α)) = 2 + 2*cos(α)

次に、3 つの行列の積のトレースを計算し、その結果を抽出4x4と同一視します。次に、 、、を計算します。2 + 2*cos(α)αxyz

この特定のケースでは、正しく計算した場合、3 つの4x4行列の積から得られる行列のトレースは次のようになります。

T = 
cos(20deg)*cos(15deg) + 
cos(50deg)*cos(15deg) - sin(50deg)*sin(20deg)*cos(15deg) + 
cos(50deg)*cos(20deg) + 
1

つまりcos(α) = (T - 2)/2 = T/2 - 1、つまりα = acos(T/2 - 1)

于 2013-03-04T18:51:06.220 に答える
15

構文:

rotate3d(x, y, z, a)

値:

  • x<number>回転軸を表すベクトルの x 座標を表す です 。
  • y<number>回転軸を表すベクトルの y 座標を表す です 。
  • z<number>回転軸を表すベクトルの z 座標を表す です 。
  • a<angle>回転の角度を表す です 。正の角度は時計回りの回転を表し、負の角度は反時計回りの回転を表します。

のように :

.will-distort{
    transform:rotate3d(10, 10, 10, 45deg);
}

ここをいじった

ここで使用できます

それに関するその他のドキュメント

于 2013-03-04T17:39:16.697 に答える
7

何をしようとしているかにもよりますが、この「ハック」が役に立ちます。アニメーションを行っていて、変換後に変換などを追加したい場合、CSS が何百もの変換を行っているように見せたくない場合を考えてみましょう:

これは chrome で機能します: 1. 必要な変換を要素に適用します。2. 次に変換を追加する場合は、計算された変換に追加します: "window.getComputedStyle(element).transform" - ただし、新しい変換を必ず左側に配置してください。3. これで、変換は "rotateZ(30deg) matrix3d(......) のようになります。

TL;DR-必要な変換を適用してから、計算されたmatrix3d変換を取得します。

このトリックを使用すると、参照フレームに対してオブジェクトを任意の方向に回転させる機能をすばやく (つまり、自分で計算を行わずに) 作成することもできます。以下のサンプルを参照してください。

編集: xyz 翻訳も追加しました。これを使用すると、特定の方向を念頭に置いて特定の 3D 位置にオブジェクトを配置することが非常に簡単になります。または...立方体がバウンドし、着地方法に応じてバウンドするたびにスピン軸が変化することを想像してみてください。

	var boxContainer = document.querySelector('.translator'),
	    cube = document.getElementById('cube'),
	    optionsContainer = document.getElementById('options');
	var dims = ['x', 'y', 'z'];
	var currentTransform;
	var currentTranslate;
	var init = function () {
	    optionsContainer.querySelector('.xRotation input')
	        .addEventListener('input', function (event) {
	        if (currentTransform != 'none') {
	            var newTransform = 'rotateX(' + (360 - event.target.value) + 'deg) ' + currentTransform;
	        } else {
	            var newTransform = 'rotateX(' + (360 - event.target.value) + 'deg)';
	        }
	        cube.style.transform = newTransform;
	    }, false);

	    optionsContainer.querySelector('.yRotation input')
	        .addEventListener('input', function (event) {
	        if (currentTransform != 'none') {
	            var newTransform = 'rotateY(' + (360 - event.target.value) + 'deg) ' + currentTransform;
	        } else {
	            var newTransform = 'rotateY(' + (360 - event.target.value) + 'deg)';
	        }
	        cube.style.transform = newTransform;
	    }, false);

	    optionsContainer.querySelector('.zRotation input')
	        .addEventListener('input', function (event) {

	        if (currentTransform != 'none') {
	            var newTransform = 'rotateZ(' + (360 - event.target.value) + 'deg) ' + currentTransform;
	        } else {
	            var newTransform = 'rotateZ(' + (360 - event.target.value) + 'deg)';
	        }
	        cube.style.transform = newTransform;
	    }, false);

	    optionsContainer.querySelector('.xTranslation input')
	        .addEventListener('input', function (event) {

	        if (currentTranslate != 'none') {
	            var newTransform = 'translateX(' + (100 - event.target.value) + 'px) ' + currentTranslate;
	        } else {
	            var newTransform = 'translateX(' + (100 - event.target.value) + 'px)';
	        }
	        boxContainer.style.transform = newTransform;
	    }, false);

	    optionsContainer.querySelector('.yTranslation input')
	        .addEventListener('input', function (event) {

	        if (currentTranslate != 'none') {
	            var newTransform = 'translateY(' + (100 - event.target.value) + 'px) ' + currentTranslate;
	        } else {
	            var newTransform = 'translateY(' + (100 - event.target.value) + 'px)';
	        }
	        boxContainer.style.transform = newTransform;
	    }, false);
	    optionsContainer.querySelector('.zTranslation input')
	        .addEventListener('input', function (event) {

	        if (currentTranslate != 'none') {
	            var newTransform = 'translateZ(' + (500 - event.target.value) + 'px) ' + currentTranslate;
	        } else {
	            var newTransform = 'translateZ(' + (500 - event.target.value) + 'px)';
	        }
	        boxContainer.style.transform = newTransform;
	    }, false);



reset();

	};

	function reset() {
	    currentTransform = window.getComputedStyle(cube).transform;
	    currentTranslate = window.getComputedStyle(boxContainer).transform;
	    optionsContainer.querySelector('.xRotation input').value = 360;
	    optionsContainer.querySelector('.yRotation input').value = 360;
	    optionsContainer.querySelector('.zRotation input').value = 360;
	    optionsContainer.querySelector('.xTranslation input').value = 100;
	    optionsContainer.querySelector('.yTranslation input').value = 100;
	    optionsContainer.querySelector('.zTranslation input').value = 500;


	}


	window.addEventListener('DOMContentLoaded', init, false);
	document.addEventListener('mouseup', reset, false);
.translator
{
	height: 200px;
	position: absolute;
	width: 200px;
    transform-style: preserve-3d;
}
.threeSpace
{
	height: 200px;
	moz-perspective: 1200px;
	o-perspective: 1200px;
	perspective: 200px;
	position: absolute;
	transform-origin: 50px 50px 100px;
	webkit-perspective: 1200px;
	width: 100px;
    perspective-origin: 100px 25px;
    transform-style: preserve-3d;
}
#pointer{
    position:relative;
    height:2px;
    width:2px;
    top:25px;
    left:100px;
    background:blue;
    z-index:9999;
    
}



#cube
{
	height: 100%;
	moz-transform-origin: 90px 110px 0px;
	moz-transform-style: preserve-3d;
	o-transform-origin: 90px 110px 0px;
	o-transform-style: preserve-3d;
	position: absolute;
	transform-origin: 90px 110px 0px;
	transform-style: preserve-3d;
	webkit-transform-origin: 90px 110px 0px;
	webkit-transform-style: preserve-3d;
	width: 100%;
}
#cube .midPoint{
    position:absolute;
    top:48px;
    left:48px;
    height:1px;
    width:1px;
    background:green;
}

#cube figure
{
	border: 2px solid black;
	color: white;
	display: block;
	font-size: 60px;
	font-weight: bold;
	height: 96px;
	line-height: 96px;
	position: absolute;
	text-align: center;
	width: 96px;
    /* transform-style: preserve-3d; */
}
#cube .front
{
	background: hsl(0, 100%, 50%);
}

#cube .back
{
	background: hsl(60, 100%, 50%);
}
#cube .right
{
	background: hsl(120, 100%, 50%);
}
#cube .left
{
	background: hsl(180, 100%, 50%);
}
#cube .top
{
	background: hsl(240, 100%, 50%);
}
#cube .bottom
{
	background: hsl(300, 100%, 50%);
}
#cube .front
{
	moz-transform: translateZ(50px);
	o-transform: translateZ(50px);
	transform: translateZ(50px);
	webkit-transform: translateZ(50px);
}



#cube .back
{
	moz-transform: rotateX(-180deg) translateZ(50px);
	o-transform: rotateX(-180deg) translateZ(50px);
	transform: rotateX(-180deg) translateZ(50px);
	webkit-transform: rotateX(-180deg) translateZ(50px);
}
#cube .right
{
	moz-transform: rotateY(90deg) translateZ(50px);
	o-transform: rotateY(90deg) translateZ(50px);
	transform: rotateY(90deg) translateZ(50px);
	webkit-transform: rotateY(90deg) translateZ(50px);
}
#cube .left
{
	moz-transform: rotateY(-90deg) translateZ(50px);
	o-transform: rotateY(-90deg) translateZ(50px);
	transform: rotateY(-90deg) translateZ(50px);
	webkit-transform: rotateY(-90deg) translateZ(50px);
}
#cube .top
{
	moz-transform: rotateX(90deg) translateZ(50px);
	o-transform: rotateX(90deg) translateZ(50px);
	transform: rotateX(90deg) translateZ(50px);
	webkit-transform: rotateX(90deg) translateZ(50px);
}
#cube .bottom
{
	moz-transform: rotateX(-90deg) translateZ(50px);
	o-transform: rotateX(-90deg) translateZ(50px);
	transform: rotateX(-90deg) translateZ(50px);
	webkit-transform: rotateX(-90deg) translateZ(50px);
}
#options{
    position:absolute;
    width:80%;
    top:40%;
    
    
}
#options input
{
	width: 60%;
}
<body>
    
     <div class="threeSpace">
         <div id="pointer"></div>
    <div class="translator">
        <div id="cube">
            <figure class="front"><div class='midPoint'></div></figure>
            <figure class="back"></figure>
            <figure class="right"></figure>
            <figure class="left"></figure>
            <figure class="top"></figure>
            <figure class="bottom"></figure>
        </div>
    </div>
    </div>
    <section id="options">
        <p class="xRotation">
            <label>xRotation</label>
            <input type="range" min="0" max="720" value="360" data-units="deg" />
        </p>
        <p class="yRotation">
            <label>yRotation</label>
            <input type="range" min="0" max="720" value="360" data-units="deg" />
        </p>
        <p class="zRotation">
            <label>zRotation</label>
            <input type="range" min="0" max="720" value="360" data-units="deg" />
        </p>
        <p class="xTranslation">
            <label>xTranslation</label>
            <input type="range" min="0" max="200" value="100" data-units="deg" />
        </p>
        <p class="yTranslation">
            <label>yTranslation</label>
            <input type="range" min="0" max="200" value="100" data-units="deg" />
        </p>
        <p class="zTranslation">
            <label>zTranslation</label>
            <input type="range" min="0" max="1000" value="500" data-units="deg" />
        </p>
    </section>
</body>

于 2015-03-07T04:27:51.417 に答える
3

正確な値はrotate3d(133,32,58,58deg)

フィドルを参照してください(chrome および Safari の場合、-webkit-transform を使用)

于 2013-03-04T18:09:11.073 に答える