另一个轴上的旋转动画

杰夫·普罗德

我正在尝试使用动画在与默认轴不同的轴上旋转对象。

这实际上是我的做法。您可以单击按钮LLi它实际上可以工作。但是正如您所看到的,R按钮的旋转轴应更改。我不知道该怎么做。我是否对这种旋转动画做正确的事情?

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.set(-2, 1, 3);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight - 60); // -60 to see buttons below
const divid = document.getElementById('myid');
divid.appendChild(renderer.domElement);

// show axis
scene.add(new THREE.AxesHelper(2))

let controls = new THREE.OrbitControls(camera, renderer.domElement);

// one triangle equilateral
const sideLength = 1
const x = 0
const y = 0
const geometry = new THREE.Geometry()
geometry.vertices.push(new THREE.Vector3(x, (Math.sqrt(3) / 2 * sideLength) - (sideLength / 2), 0))
geometry.vertices.push(new THREE.Vector3(x - (sideLength / 2), y - (sideLength / 2), 0))
geometry.vertices.push(new THREE.Vector3(x + (sideLength / 2), y - (sideLength / 2), 0))
geometry.faces.push(new THREE.Face3(0, 1, 2))

const facesColors = [
  0xFFFF00, // yellow
  0xFF0000, // red
  0x0000FF, // blue
  0x008000 // green
]

const pos = [
  0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 3
]

const d = 0.05 // écart entre les triangles
let face
const facesVectors = [
  [0, 1, 2],
  [0, 2, 3],
  [0, 3, 1],
  [1, 3, 2]
]

// https://stackoverflow.com/questions/60774560/drawing-a-pyraminx-with-triangles
// coords des points d'un tétrahèdre
const s89 = Math.sqrt(8 / 9)
const s29 = Math.sqrt(2 / 9)
const s23 = Math.sqrt(2 / 3)
const v = [
  new THREE.Vector3(0, 0, 1),
  new THREE.Vector3(s89, 0, -1 / 3),
  new THREE.Vector3(-s29, s23, -1 / 3),
  new THREE.Vector3(-s29, -s23, -1 / 3)
]

const computeMidPts = (pts) => {
  const midPts = []
  for (let i = 0; i < pts.length; ++i) {
midPts.push(new THREE.Vector3().lerpVectors(pts[i], pts[(i + 1) % 3], 0.5))
  }
  return midPts
}

const computeInnerPts = (pts, d) => {
  const innerPts = []
  for (let i = 0; i < pts.length; ++i) {
const va = new THREE.Vector3().lerpVectors(pts[i], pts[(i + 1) % 3], d)
const vb = new THREE.Vector3().lerpVectors(pts[i], pts[(i + 2) % 3], d)
innerPts.push(new THREE.Vector3().lerpVectors(va, vb, 0.5))
  }
  return innerPts
}

let allfaces = [];

for (let i = 0; i < 4; ++i) {
  const pts = [v[facesVectors[i][0]], v[facesVectors[i][1]], v[facesVectors[i][2]]]

  const outerPts = computeInnerPts(pts, d)
  for (let j = 0; j < 3; ++j) {
const geometry = new THREE.Geometry()
geometry.vertices.push(outerPts[j])
geometry.vertices.push(new THREE.Vector3().lerpVectors(outerPts[j], outerPts[(j + 1) % 3], 0.5 - d / 2))
geometry.vertices.push(new THREE.Vector3().lerpVectors(outerPts[j], outerPts[(j + 2) % 3], 0.5 - d / 2))
geometry.faces.push(new THREE.Face3(0, 1, 2))
const material = new THREE.MeshBasicMaterial({ color: facesColors[i] })
face = new THREE.Mesh(geometry, material)
allfaces.push(face)
scene.add(face)
  }

  const midPts = computeMidPts(outerPts)
  const innerPts = computeInnerPts(midPts, d / 2)
  const geometry = new THREE.Geometry()
  geometry.vertices.push(...innerPts)
  geometry.faces.push(new THREE.Face3(0, 1, 2))
  const material = new THREE.MeshBasicMaterial({ color: facesColors[i] })
  face = new THREE.Mesh(geometry, material)
  allfaces.push(face)
  scene.add(face)
}

let movingL = false
let movingLi = false
let movingR = false
let pivot = null
renderer.setAnimationLoop(() => {
  if (movingL) {
pivot.rotation.z += 0.05
if (pivot.rotation.z >= (2 * Math.PI) / 3) {
  movingL = false
}
  } else if (movingLi) {
pivot.rotation.z -= 0.05
if (pivot.rotation.z <= -(2 * Math.PI) / 3) {
  movingLi = false
} 
  } else if (movingR) {
pivot.rotation.x -= 0.05
if (pivot.rotation.x <= -(2 * Math.PI) / 3) {
  movingR = false
} 
  }
  renderer.render(scene, camera);
});

document.getElementById("L").addEventListener("click", function(){
  pivot = new THREE.Group();
  scene.add(pivot);
  
  // faces to move 
  pivot.attach(allfaces[0]);
  pivot.attach(allfaces[4]);
  pivot.attach(allfaces[8]);
  
  movingL = true
});

document.getElementById("Li").addEventListener("click", function(){
  pivot = new THREE.Group();
  scene.add(pivot);
  pivot.attach(allfaces[0]);
  pivot.attach(allfaces[4]);
  pivot.attach(allfaces[8]);  
  movingLi = true
});

document.getElementById("R").addEventListener("click", function(){
  pivot = new THREE.Group();
  scene.add(pivot);
  pivot.attach(allfaces[1]);
  pivot.attach(allfaces[10]);
  pivot.attach(allfaces[12]);  
  movingR = true
});
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

<div id="myid"></div>
<button id="L">L</button>
<button id="Li">Li</button>
<button id="R">R</button>
<button id="Ri">Ri</button>
...

马奎佐

您将必须使用Quaternions,这是将旋转应用于对象的一种更强大的方法。

四元数有一种称为的方法.setFromAxisAngle(),可用于设置所需的旋转轴。

在下面的示例中,每次单击按钮时,我都会设置旋转轴并使用以下方法重置旋转角度:

axisVector.set(x, y, z).normalize();
quatAngle = 0;

(归一化可确保轴总长度为1。使用轴向量(2, 0, 0)会破坏旋转)

建立轴后,您可以使用

quatAngle += 0.05;
pivot.quaternion.setFromAxisAngle(axisVector, quatAngle);

我不确定旋转轴的位置是RU,所以我只是在视觉上估计了(1, 0, -0.33)(-0.4, 0.7, -0.3),然后我.normalize()将其长度设为1。

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.set(-2, 1, 3);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight - 60); // -60 to see buttons below
const divid = document.getElementById('myid');
divid.appendChild(renderer.domElement);

// show axis
scene.add(new THREE.AxesHelper(2))

let controls = new THREE.OrbitControls(camera, renderer.domElement);

// one triangle equilateral
const sideLength = 1
const x = 0
const y = 0
const geometry = new THREE.Geometry()
geometry.vertices.push(new THREE.Vector3(x, (Math.sqrt(3) / 2 * sideLength) - (sideLength / 2), 0))
geometry.vertices.push(new THREE.Vector3(x - (sideLength / 2), y - (sideLength / 2), 0))
geometry.vertices.push(new THREE.Vector3(x + (sideLength / 2), y - (sideLength / 2), 0))
geometry.faces.push(new THREE.Face3(0, 1, 2))

const facesColors = [
	0xFFFF00, // yellow
	0xFF0000, // red
	0x0000FF, // blue
	0x008000 // green
]

const pos = [
	0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 3
]

const d = 0.05 // écart entre les triangles
let face
const facesVectors = [
	[0, 1, 2],
	[0, 2, 3],
	[0, 3, 1],
	[1, 3, 2]
]

// https://stackoverflow.com/questions/60774560/drawing-a-pyraminx-with-triangles
// coords des points d'un tétrahèdre
const s89 = Math.sqrt(8 / 9)
const s29 = Math.sqrt(2 / 9)
const s23 = Math.sqrt(2 / 3)
const v = [
	new THREE.Vector3(0, 0, 1),
	new THREE.Vector3(s89, 0, -1 / 3),
	new THREE.Vector3(-s29, s23, -1 / 3),
	new THREE.Vector3(-s29, -s23, -1 / 3)
]

const computeMidPts = (pts) => {
	const midPts = []
	for (let i = 0; i < pts.length; ++i) {
midPts.push(new THREE.Vector3().lerpVectors(pts[i], pts[(i + 1) % 3], 0.5))
	}
	return midPts
}

const computeInnerPts = (pts, d) => {
	const innerPts = []
	for (let i = 0; i < pts.length; ++i) {
const va = new THREE.Vector3().lerpVectors(pts[i], pts[(i + 1) % 3], d)
const vb = new THREE.Vector3().lerpVectors(pts[i], pts[(i + 2) % 3], d)
innerPts.push(new THREE.Vector3().lerpVectors(va, vb, 0.5))
	}
	return innerPts
}

let allfaces = [];

for (let i = 0; i < 4; ++i) {
	const pts = [v[facesVectors[i][0]], v[facesVectors[i][1]], v[facesVectors[i][2]]]

	const outerPts = computeInnerPts(pts, d)
	for (let j = 0; j < 3; ++j) {
const geometry = new THREE.Geometry()
geometry.vertices.push(outerPts[j])
geometry.vertices.push(new THREE.Vector3().lerpVectors(outerPts[j], outerPts[(j + 1) % 3], 0.5 - d / 2))
geometry.vertices.push(new THREE.Vector3().lerpVectors(outerPts[j], outerPts[(j + 2) % 3], 0.5 - d / 2))
geometry.faces.push(new THREE.Face3(0, 1, 2))
const material = new THREE.MeshBasicMaterial({ color: facesColors[i] })
face = new THREE.Mesh(geometry, material)
allfaces.push(face)
scene.add(face)
	}

	const midPts = computeMidPts(outerPts)
	const innerPts = computeInnerPts(midPts, d / 2)
	const geometry = new THREE.Geometry()
	geometry.vertices.push(...innerPts)
	geometry.faces.push(new THREE.Face3(0, 1, 2))
	const material = new THREE.MeshBasicMaterial({ color: facesColors[i] })
	face = new THREE.Mesh(geometry, material)
	allfaces.push(face)
	scene.add(face)
}

let movingL = false
let movingLi = false
let movingR = false
let movingU = false
let pivot = null
let quatAngle = 0;
let axisVector = new THREE.Vector3();

renderer.setAnimationLoop(() => {
	if (movingL) {
		quatAngle += 0.05
		pivot.quaternion.setFromAxisAngle(axisVector, quatAngle);
		if (quatAngle >= (2 * Math.PI) / 3) {
			movingL = false
		}
	} else if (movingLi) {
		quatAngle -= 0.05
		pivot.quaternion.setFromAxisAngle(axisVector, quatAngle);
		if (quatAngle <= -(2 * Math.PI) / 3) {
			movingLi = false
		} 
	} else if (movingR) {
		quatAngle -= 0.05
		pivot.quaternion.setFromAxisAngle(axisVector, quatAngle);
		if (quatAngle <= -(2 * Math.PI) / 3) {
			movingR = false
		} 
	} else if (movingU) {
		quatAngle -= 0.05
		pivot.quaternion.setFromAxisAngle(axisVector, quatAngle);
		if (quatAngle <= -(2 * Math.PI) / 3) {
			movingU = false
		} 
	}
	renderer.render(scene, camera);
});

document.getElementById("L").addEventListener("click", function(){
	pivot = new THREE.Group();
	axisVector.set(0, 0, 1);
	quatAngle = 0;
	scene.add(pivot);
	
	// faces to move 
	pivot.attach(allfaces[0]);
	pivot.attach(allfaces[4]);
	pivot.attach(allfaces[8]);
	
	movingL = true
});

document.getElementById("Li").addEventListener("click", function(){
	pivot = new THREE.Group();
	axisVector.set(0, 0, 1);
	quatAngle = 0;
	scene.add(pivot);
	pivot.attach(allfaces[0]);
	pivot.attach(allfaces[4]);
	pivot.attach(allfaces[8]);  
	movingLi = true
});

document.getElementById("R").addEventListener("click", function(){
	pivot = new THREE.Group();
	axisVector.set(1, 0, -0.33).normalize();
	quatAngle = 0;
	scene.add(pivot);
	pivot.attach(allfaces[1]);
	pivot.attach(allfaces[10]);
	pivot.attach(allfaces[12]);  
	movingR = true
});
document.getElementById("U").addEventListener("click", function(){
	pivot = new THREE.Group();
	axisVector.set(-0.4, 0.7, -0.3).normalize();
	quatAngle = 0;
	scene.add(pivot);
	pivot.attach(allfaces[2]);
	pivot.attach(allfaces[5]);
	pivot.attach(allfaces[14]);  
	movingU = true
});
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

<div id="myid"></div>
<button id="L">L</button>
<button id="Li">Li</button>
<button id="R">R</button>
<button id="U">U</button>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在元素上动画时,为另一个动画

来自分类Dev

将旋转的div与另一个div对齐

来自分类Dev

围绕另一个任意点旋转点

来自分类Dev

使用自动版式时,如何将翻转动画从一个UIView转换为另一个UIView?

来自分类Dev

在View上连续控制旋转动画

来自分类Dev

如何将一个对象的局部轴旋转到另一个对象?

来自分类Dev

围绕另一个CGPoint旋转CGPoint

来自分类Dev

旋转节点以查看另一个节点

来自分类Dev

如何在另一个xaml的控件上应用双重动画?

来自分类Dev

围绕另一个点和X轴旋转点

来自分类Dev

悬停在一个或另一个上时无法停止所有CSS动画

来自分类Dev

围绕另一个元素旋转元素-CSS

来自分类Dev

Matplotlib / SNS:绘制直方图,但在y轴上平均另一个变量

来自分类Dev

旋转一个重复的屏幕而不旋转另一个Windows 8

来自分类Dev

在另一个图像上旋转图像

来自分类Dev

围绕另一个旋转对象

来自分类Dev

将旋转的div与另一个div对齐

来自分类Dev

围绕另一个任意点旋转点

来自分类Dev

合并两个不同的图:一个在X轴上,另一个在Y轴上

来自分类Dev

跟随另一个正在旋转的物体

来自分类Dev

从另一个GUI调用轴

来自分类Dev

围绕另一个gameObject旋转gameObjects

来自分类Dev

如何在另一个xaml的控件上应用双重动画?

来自分类Dev

CSS旋转元素并将元素放置在另一个元素的角上

来自分类Dev

在NG-Click上在AngularJS中将一个div动画化/移动到另一个div

来自分类Dev

在Android上从一个片段转到另一个片段时的动画滞后

来自分类Dev

Threejs在3d矩阵轴上围绕另一个对象旋转一个对象

来自分类Dev

围绕另一个旋转圆旋转圆圈

来自分类Dev

R:在另一个 ggplot 的 x 和 y 轴上显示 ggplots 的好方法

Related 相关文章

  1. 1

    在元素上动画时,为另一个动画

  2. 2

    将旋转的div与另一个div对齐

  3. 3

    围绕另一个任意点旋转点

  4. 4

    使用自动版式时,如何将翻转动画从一个UIView转换为另一个UIView?

  5. 5

    在View上连续控制旋转动画

  6. 6

    如何将一个对象的局部轴旋转到另一个对象?

  7. 7

    围绕另一个CGPoint旋转CGPoint

  8. 8

    旋转节点以查看另一个节点

  9. 9

    如何在另一个xaml的控件上应用双重动画?

  10. 10

    围绕另一个点和X轴旋转点

  11. 11

    悬停在一个或另一个上时无法停止所有CSS动画

  12. 12

    围绕另一个元素旋转元素-CSS

  13. 13

    Matplotlib / SNS:绘制直方图,但在y轴上平均另一个变量

  14. 14

    旋转一个重复的屏幕而不旋转另一个Windows 8

  15. 15

    在另一个图像上旋转图像

  16. 16

    围绕另一个旋转对象

  17. 17

    将旋转的div与另一个div对齐

  18. 18

    围绕另一个任意点旋转点

  19. 19

    合并两个不同的图:一个在X轴上,另一个在Y轴上

  20. 20

    跟随另一个正在旋转的物体

  21. 21

    从另一个GUI调用轴

  22. 22

    围绕另一个gameObject旋转gameObjects

  23. 23

    如何在另一个xaml的控件上应用双重动画?

  24. 24

    CSS旋转元素并将元素放置在另一个元素的角上

  25. 25

    在NG-Click上在AngularJS中将一个div动画化/移动到另一个div

  26. 26

    在Android上从一个片段转到另一个片段时的动画滞后

  27. 27

    Threejs在3d矩阵轴上围绕另一个对象旋转一个对象

  28. 28

    围绕另一个旋转圆旋转圆圈

  29. 29

    R:在另一个 ggplot 的 x 和 y 轴上显示 ggplots 的好方法

热门标签

归档