rotate3d

Jak połączyć rotateX(50deg) rotateY(20deg) rotateZ(15deg) w stenogramie rotate3d()?

Author: Artem Svirskyi, 2013-03-04

4 answers

rotateX(50deg) jest równoważne rotate3d(1, 0, 0, 50deg)

rotateY(20deg) jest równoważne rotate3d(0, 1, 0, 20deg)

rotateZ(15deg) jest równoważne rotate3d(0, 0, 1, 15deg)

Więc...

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

Jest równoważne

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


Dla ogólnego rotate3d(x, y, z, α) macierz

generic rotate matrix

Gdzie

Wyjaśnienie


Otrzymujesz teraz macierze dla każdej z 3 przekształceń rotate3d i mnożysz je. A otrzymaną macierzą jest macierz odpowiadająca wynikowy pojedynczy rotate3d. Nie wiem, jak łatwo jest wyodrębnić z niego wartości dla rotate3d, ale na pewno łatwo jest wyodrębnić je dla pojedynczego matrix3d.


W pierwszym przypadku (rotateX(50deg) lub rotate3d(1, 0, 0, 50deg)), masz:

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

Więc pierwszy rząd macierzy w tym przypadku to 1 0 0 0.

Drugi to 0 cos(50deg) -sin(50deg) 0.

Trzeci 0 sin(50deg) cos(50deg) 0.

A czwarty to oczywiście 0 0 0 1.


W drugim przypadku, masz x = 0, y = 1, z = 0, α = 20deg.

Pierwszy wiersz: cos(20deg) 0 sin(20deg) 0.

Drugi rząd: 0 1 0 0.

Trzeci rząd: -sin(20) 0 cos(20deg) 0.

Czwarty: 0 0 0 1


W trzecim przypadku, masz x = 0, y = 0, z = 1, α = 15deg.

Pierwszy wiersz: cos(15deg) -sin(15deg) 0 0.

Drugi rząd sin(15deg) cos(15deg) 0 0.

Oraz trzeci i czwarty rząd to odpowiednio 0 0 1 0 i 0 0 0 1.


Uwaga: być może zauważyłeś, że znaki grzechu wartości dla transformacji rotateY ' a są inne niż dla pozostałych dwóch przekształceń. To nie jest błąd obliczeniowy. Powodem tego jest to, że na ekranie masz oś y skierowaną w dół, a nie w górę.


Więc są to trzy 4x4 macierze, które trzeba mnożyć, aby uzyskać 4x4 macierz dla wynikowego przekształcenia pojedynczego rotate3d. Jak już powiedziałem, nie jestem pewien, jak łatwo można wyciągnąć 4 wartości, ale 16 elementów w matrycy 4x4 to dokładnie 16 parametry matrix3d odpowiednika transformacji łańcuchowej.


EDIT :

Okazuje się, że to całkiem proste... Obliczasz ślad (sumę elementów przekątnych) macierzy dla rotate3d macierzy.

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

Następnie obliczasz ślad dla iloczynu trzech 4x4 macierzy, porównujesz wynik z 2 + 2*cos(α) wyciągasz α. Następnie Oblicz x, y, z.

W tym konkretnym przypadku, jeśli obliczyłem w rzeczywistości, ślad macierzy wynikający z iloczynu trzech macierzy 4x4 będzie wynosił:

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

Więc cos(α) = (T - 2)/2 = T/2 - 1, co oznacza, że α = acos(T/2 - 1).

 315
Author: Ana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-12 20:25:48

Składnia:

rotate3d(x, y, z, a)

Wartości:

  • x Jest <number> opisującym współrzędną x wektora wyznaczającego oś obrotu.
  • y Jest <number> opisującym współrzędną y wektora wyznaczającego oś obrotu.
  • z Jest <number> opisującym współrzędną z wektora oznaczającą oś obrotu.
  • a Jest <angle> reprezentującym kąt obrotu. Kąt dodatni oznacza obrót zgodnie z ruchem wskazówek zegara, kąt ujemny a przeciwnie do ruchu wskazówek zegara.

Jak w :

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

Fiddled here

Można go używać tutaj

Więcej dokumentów na ten temat

 15
Author: Milche Patern,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-08 09:08:27

Zależy od tego, co próbujesz zrobić, ten "hack" może Ci pomóc. Załóżmy, że wykonujesz animację i chcesz dodać transformację za transformacją itd., a nie chcesz, aby CSS wyglądał tak, jakby robił 100 transformacji: {]}

To działa w chrome: 1. Zastosuj dowolną transformację do elementu. 2. Następnym razem, gdy chcesz dodać transformację, dodaj ją do przekształcenia obliczonego: "okno.getComputedStyle (element).transform " - ale upewnij się, aby umieścić nowy / align = "left" / 3. Teraz twoja transformacja będzie wyglądać jak " rotateZ (30deg) matrix3d (......). 4. Następnym razem, gdy chcesz dodać kolejną transformację, powtórz proces-Chrome zawsze redukuje transformacje do notacji matrix3d.

TL;DR-zastosuj dowolne transformaty, a następnie uzyskaj obliczoną transformację matrix3d.

Ta sztuczka pozwala również szybko (to znaczy bez robienia żadnej matematyki samodzielnie) stworzyć funkcjonalność, która obraca obiekt w odniesieniu do odniesienia rama w dowolnym kierunku. Zobacz przykład poniżej:

EDIT : dodałem również tłumaczenia xyz. Dzięki temu bardzo łatwo byłoby umieścić obiekty w określonych lokalizacjach 3d z myślą o określonych orientacjach. Albo...wyobraź sobie sześcian, który odbija się i zmienia oś obrotu z każdym odbiciem w zależności od tego, jak wyląduje!

	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>
 7
Author: Roman Rekhler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-07 13:47:33

Dokładna wartość to rotate3d(133,32,58,58deg)

[1]} Zobacz fiddle (dla chrome i Safari, przy użyciu-webkit-transform)
 3
Author: Bigood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-04 18:09:11