Изчислете координатите преди (CSS-трансформация) завъртане на точка

Какво искам да направя: Дайте на функция на javascript координатите за триъгълник в 3d-стая като параметър и тя изчислява пътя на svg и ъглите на трансформация на css за този обект.

Какво вече разбрах:

  • за да изчисля триъгълника между 3-те точки, просто ще трябва да изчисля дължините в стаята на всичките 3 страни от него. Тогава ще мога да го начертая в координатна система x-y (ъглите могат да се изчислят с 3 страни)
  • освен това имам нужда от ъглите, с които триъгълникът трябва да се завърти, за да постигна желания резултат
  • за да направя това, дефинирах една точка от триъгълника като начало на трансформацията (0|0|0), тя може да бъде преведена по-късно.

Но тогава се провалих. Успях да изчисля Z- и Y-ъглите за получена точка Pr(x|y|z) с начална точка Po(x|0) в равнината x-y. Мисълта ми беше да "фиксирам" една триъгълна точка на оста x и след това да завъртя около оста x ... но както и да е - не работи. Мислех, че оста x се завърта първо, но това не е така.


И така, това, от което се нуждая, е неизвестната трансформационна матрица за дадена (резултантна) точка/триъгълник и нейния начален триъгълник, който може да се счита за даден, където полученият триъгълник се намира в триизмерната стая, началният триъгълник е в двуизмерната стая (път на svg).

Наистина нямам представа, аз съм в 11 клас, така че ми е малко трудно да го разбера.

Благодаря много за всякакъв вид помощ! Джонас.


person LepBJ    schedule 15.03.2015    source източник


Отговори (1)


Най-накрая, след няколко дни с твърде скучни уроци, ето моето решение!

  1. Всъщност можете да решите коя CSS трансформация да се приложи първа: rotateY(~deg) rotateX(~deg) се завърта първо около оста Y, след това около оста x. Внимание! Оста на координатната система се завърта заедно с вашия обект.

Ето една анимация, за да ви покажа какво имам предвид: ext. връзка. Обикновено бихте очаквали, че оста x е все още на мястото си след Y- и Z- ротация, но тя се завърта с Object/SVG. Така че вие ​​се въртите около оста на обекта.

  1. Няма нужда от матрица за трансформация: Накрая изчислих ъглите за 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>

person LepBJ    schedule 19.03.2015