rotate3d 속기


답변:


314

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않지만 단일 .NET에 대한 값 을 추출하는 것은 쉽습니다 matrix3d.


첫 번째 경우 ( rotateX(50deg)또는 rotate3d(1, 0, 0, 50deg))는 다음과 같습니다.

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

따라서이 경우 행렬의 첫 번째 행은입니다 1 0 0 0.

두 번째는 0 cos(50deg) -sin(50deg) 0입니다.

세 번째 0 sin(50deg) cos(50deg) 0.

그리고 네 번째는 분명히 0 0 0 1.


두 번째 경우에, 당신은 x = 0, y = 1, z = 0, α = 20deg.

첫 번째 행 : cos(20deg) 0 sin(20deg) 0.

두 번째 행 : 0 1 0 0.

세 번째 행 : -sin(20) 0 cos(20deg) 0.

네번째: 0 0 0 1


세 번째 경우에, 당신은 x = 0, y = 0, z = 1, α = 15deg.

첫 번째 행 : cos(15deg) -sin(15deg) 0 0.

두 번째 행 sin(15deg) cos(15deg) 0 0.

그리고 세 번째와 네 번째 행은 각각 0 0 1 00 0 0 1입니다.


참고 : rotateY 변환에 대한 sin 값의 부호가 다른 두 변환에 대한 것과 다르다는 것을 알 수 있습니다. 계산 실수가 아닙니다. 그 이유는 화면의 경우 y 축이 위쪽이 아닌 아래쪽을 가리 키기 때문입니다.


따라서 이들은 결과 단일 변환에 대한 행렬 4x4을 얻기 위해 곱해야하는 세 개의 행렬입니다 . 내가 말했듯이 4 개의 값을 얻는 것이 얼마나 쉬운 지 잘 모르겠지만, 4x4 행렬의 16 개 요소는 정확히 연결 변환에 해당 하는 16 개의 매개 변수입니다 .4x4rotate3dmatrix3d


수정 :

사실, 그것은 매우 쉽다는 것이 밝혀졌습니다 ... 당신은 행렬에 대한 rotate3d행렬 의 트레이스 (대각선 요소의 합)를 계산합니다 .

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

그런 다음 세 4x4행렬 의 곱에 대한 추적을 계산하고 결과 2 + 2*cos(α)를 추출한 결과와 동일시합니다 α. 그런 다음 계산 x, y, z.

이 특별한 경우에 내가 올바르게 계산했다면 세 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).


6
네, 사실을 확인하는 방법도 모릅니다. 나는 죄를 볼 때까지 완전히 갔다. 내 마음을 열었거든요 내가 죄를 보았을 때. 베이스의 shoutout 에이스
앤드류 Luhring

1
트윗 담아 가기
aendrew

1
회전 행렬은 [x,y,z]벡터가 정규화 된 경우, 즉 벡터 길이 Math.sqrt(x*x + y*y + z*z)가 1 인 경우에만 적용 할 수 있습니다. 가 정상화되지 않으면 쉽게 다이빙 각에 의해, 정규화 된 하나에 변환 할 수 있습니다 x, y그리고 z그 길이에 의해.
Jose Rui Santos

수학 석사 학위를 소지하고 있어야합니다. 이시 고마워, 아나!
Ida

@ 앤드류 : 걱정하지 마세요, 죄는 우리 중 많은 사람들에게 더 나아집니다 ... 한숨.
다윗은 분석 재개 모니카 말한다

15

통사론:

rotate3d(x, y, z, a)

값 :

  • x A는 <number>묘화 회전축을 나타내는 벡터의 X 좌표를.
  • y A는 <number>(가) 회전축 선을 나타내는 벡터의 y 좌표를 나타내는.
  • z A는 <number>(가) 회전축 선을 나타내는 벡터의 Z 좌표를 설명.
  • a<angle>회전의 각도를 나타내는이. 양의 각도는 시계 방향 회전을, 음의 각도는 시계 반대 방향을 나타냅니다.

다음과 같이 :

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

여기에 빠져

여기에서 Caniuse

그것에 대한 더 많은 문서


6
아마도 나는 두껍지 만 그가 rotate3d정의가 아닌 체인 변환에서 단일으로 이동하는 알고리즘을 요구하고 있다고 생각 rotate3d합니다.
Ana

3
나는 그가 (50deg) rotateY (20deg) rotateZ (15deg)의 속기 ROTATE3D ()에서 CSS rotateX 결합하는 방법을 알고 싶어 생각
Milche patern입니다

7

수행하려는 작업에 따라이 '해킹'이 도움이 될 수 있습니다. 애니메이션을하고 있고 변형 후 변형 등을 추가하고 CSS가 100 번의 변형을 수행하는 것처럼 보이기를 원하지 않는다고 가정 해 보겠습니다.

이것은 크롬에서 작동합니다. 1. 요소에 원하는 변형을 적용합니다. 2. 다음에 변환을 추가하려면 계산 된 변환에 추가하십시오. "window.getComputedStyle (element) .transform"-새 변환을 왼쪽에 두십시오. 3. 이제 변환은 "rotateZ (30deg) matrix3d ​​(......)와 같습니다. 4. 다음에 다른 변환을 추가하려면 프로세스를 반복하십시오. Chrome은 항상 변환을 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>


이것은 당신을 thnak, 지금까지 가장 유용한 게시물 중 하나입니다
다미아노 Celent의

3

정확한 값은 rotate3d(133,32,58,58deg)

바이올린 보기 (Chrome 및 Safari의 경우 -webkit-transform 사용)


12
정확히 어떻게 계산합니까?
Ana

1
그렇게하지 @Ana 당신의 대답은 :) 10 배 더 좋은 이유, 그건
Bigood
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.