drehen3d Kurzschrift


Antworten:


314

rotateX(50deg) ist äquivalent zu rotate3d(1, 0, 0, 50deg)

rotateY(20deg) ist äquivalent zu rotate3d(0, 1, 0, 20deg)

rotateZ(15deg) ist äquivalent zu rotate3d(0, 0, 1, 15deg)

Damit...

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

ist äquivalent zu

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


Für ein Generikum rotate3d(x, y, z, α)haben Sie die Matrix

generische Rotationsmatrix

wo

Erläuterung


Sie erhalten nun die Matrizen für jede der 3 rotate3dTransformationen und multiplizieren sie. Und die resultierende Matrix ist die Matrix, die der resultierenden Single entspricht rotate3d. Ich bin mir nicht sicher, wie einfach es ist, die Werte daraus zu extrahieren rotate3d, aber es ist sicher einfach, diese für eine einzelne zu extrahieren matrix3d.


Im ersten Fall ( rotateX(50deg)oder rotate3d(1, 0, 0, 50deg)) haben Sie:

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

Die erste Zeile der Matrix ist in diesem Fall also 1 0 0 0.

Der zweite ist 0 cos(50deg) -sin(50deg) 0.

Der dritte 0 sin(50deg) cos(50deg) 0.

Und der vierte ist offensichtlich 0 0 0 1.


Im zweiten Fall haben Sie x = 0, y = 1, z = 0, α = 20deg.

Erste Reihe : cos(20deg) 0 sin(20deg) 0.

Zweite Reihe : 0 1 0 0.

Dritte Reihe : -sin(20) 0 cos(20deg) 0.

Vierte: 0 0 0 1


Im dritten Fall, haben Sie x = 0, y = 0, z = 1, α = 15deg.

Erste Reihe : cos(15deg) -sin(15deg) 0 0.

Zweite Reihe sin(15deg) cos(15deg) 0 0.

Und die dritte und die vierte Reihe sind 0 0 1 0und 0 0 0 1jeweils.


Hinweis : Möglicherweise haben Sie bemerkt, dass die Vorzeichen der Sin-Werte für die rotateY-Transformation anders sind als für die beiden anderen Transformationen. Es ist kein Rechenfehler. Der Grund dafür ist, dass für den Bildschirm die y-Achse nach unten und nicht nach oben zeigt.


Dies sind also die drei 4x4Matrizen, die Sie multiplizieren müssen, um die 4x4Matrix für die resultierende einzelne rotate3dTransformation zu erhalten. Wie gesagt, ich bin mir nicht sicher, wie einfach es sein kann, die 4 Werte herauszuholen, aber die 16 Elemente in der 4x4-Matrix sind genau die 16 Parameter des matrix3dÄquivalents der verketteten Transformation.


EDIT :

Eigentlich stellt sich heraus, dass es ziemlich einfach ist ... Sie berechnen die Spur (Summe der diagonalen Elemente) der Matrix für die rotate3dMatrix.

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

Sie berechnen dann die Kurve für das Produkt der drei 4x4Matrizen und setzen das Ergebnis mit 2 + 2*cos(α)Ihrem Extrakt gleich α. Dann berechnen Sie x, y, z.

In diesem speziellen Fall 4x4lautet die Spur der Matrix, die sich aus dem Produkt der drei Matrizen ergibt , wenn ich richtig berechnet habe :

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

Also cos(α) = (T - 2)/2 = T/2 - 1, was bedeutet das α = acos(T/2 - 1).


6
Ja, ich weiß nicht einmal, wie ich das überprüfen soll. Ich wollte total, bis ich die Sünde sah. weil es meinen Geist geöffnet hat. als ich die Sünde sah. Shoutout Ass der Basis
Andrew Luhring

1
@ AndrewLuhring Erstaunlich.
aendrew

1
Beachten Sie, dass die Rotationsmatrix nur anwendbar ist, wenn der [x,y,z]Vektor normalisiert ist, dh nur, wenn die Vektorlänge Math.sqrt(x*x + y*y + z*z)eins ist. Wenn es nicht normiert ist, kann es leicht in ein normiertes eines umgewandelt werden, durch Tauchen jedem x, yund zdurch ihre Länge.
Jose Rui Santos

Sie müssen einen Master of Fine Arts in Mathematik besitzen. Danke für dieses Gedicht, Ana!
Ida Ebkes

@ Andrew: Mach dir keine Sorgen, die Sünde wird besser von vielen von uns ... seufz.
David sagt, Monica

15

Syntax:

rotate3d(x, y, z, a)

Werte:

  • x Wird eine <number>Beschreibung der x-Koordinate des Vektors , der die Drehachse angibt.
  • y Ist eine <number>Beschreibung der y-Koordinate des Vektors, der die Rotationsachse bezeichnet.
  • z Ist eine <number>Beschreibung der z-Koordinate des Vektors, der die Rotationsachse bezeichnet.
  • a Ist eine <angle>Darstellung des Drehwinkels. Ein positiver Winkel bezeichnet eine Drehung im Uhrzeigersinn, ein negativer Winkel eine Drehung gegen den Uhrzeigersinn.

Wie in :

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

Hier herumgespielt

Caniuse es hier

Weitere Dokumente dazu


Beantwortet wie ein Herr. +1
Michael

6
Vielleicht bin ich dick, aber ich denke, er bittet um einen Algorithmus, der von der verketteten Transformation zu einer einzigen übergeht rotate3d, nicht um die Definition von rotate3d.
Ana

3
Ich denke, er möchte wissen, wie man rotateX (50deg) rotateY (20deg) rotateZ (15deg) in Kurzschrift rotate3d () in CSS
Milche Patern

7

Abhängig davon, was Sie versuchen, könnte dieser "Hack" Ihnen helfen. Angenommen, Sie führen eine Animation durch und möchten eine Transformation nach der anderen hinzufügen, und Sie möchten nicht, dass das CSS so aussieht, als würde es Hunderte von Transformationen ausführen:

Dies funktioniert in Chrome: 1. Wenden Sie die gewünschte Transformation auf ein Element an. 2. Wenn Sie das nächste Mal eine Transformation hinzufügen möchten, fügen Sie sie der berechneten Transformation hinzu: "window.getComputedStyle (element) .transform" - stellen Sie jedoch sicher, dass Sie die neue Transformation links platzieren. 3. Jetzt würde Ihre Transformation wie folgt aussehen: "rotateZ (30deg) matrix3d ​​(......). 4. Wenn Sie das nächste Mal eine weitere Transformation hinzufügen möchten, wiederholen Sie den Vorgang - Chrome reduziert die Transformationen immer auf die Matrix3d-Notation.

TL; DR - Wenden Sie die gewünschten Transformationen an und erhalten Sie dann die berechnete Matrix3d-Transformation.

Mit diesem Trick können Sie auch schnell (dh ohne selbst zu rechnen) eine Funktion erstellen, mit der ein Objekt in Bezug auf Ihren Referenzrahmen in eine beliebige Richtung gedreht wird. Siehe das folgende Beispiel:

EDIT : Ich habe auch xyz-Übersetzungen hinzugefügt. Auf diese Weise wäre es sehr einfach, Objekte an bestimmten 3D-Orten mit bestimmten Ausrichtungen zu platzieren. Oder ... stellen Sie sich einen Würfel vor, der mit jedem Sprung seine Drehachse springt und ändert, je nachdem, wie er landet!

	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>


Dies ist einer der nützlichsten Beiträge aller Zeiten, danke
Damiano Celent

3

Der genaue Wert ist rotate3d(133,32,58,58deg)

Siehe die Geige (Für Chrome und Safari mit -webkit-transform)


12
Wie genau berechnen Sie es?
Ana

1
@ Anna ich nicht, deshalb ist deine Antwort 10x besser :)
Bigood
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.