Top.Mail.Ru
Ответы

Математическое моделирование эффекта Джанибекова

Здравствуйте! Захотел решить задачу об эффекте Джанибекова с визуализацией в 3D на javasrypt с помощью библиотеки Three.js. Решал дифференциальные уравнения Эйлера, итого некоторые потуги на поворот в 180 градусов присутствуют, однако что-то идет не так. Прошу помочь с проблемой. Код на html + js прилагаю

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
 // Сцена и камера 
const scene = new THREE.Scene(); 
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); 
camera.position.x = 15; 
camera.position.y = 15; 
camera.position.z = 25; 
 
const renderer = new THREE.WebGLRenderer({ alpha: true }); 
renderer.setClearColor(0xffffff, 1); 
renderer.setSize(window.innerWidth, window.innerHeight); 
document.body.appendChild(renderer.domElement); 
 
//Оси координат 
const axesHelper = new THREE.AxesHelper(5); 
scene.add(axesHelper); 
 
// Прямоугольник 
var den = 1 
var posx = 8 
var posy = 1 
var posz = 3 
var m = posx * posy * posz * den 
var Ix = m * (posy * posy + posz * posz)/12 
var Iy = m * (posx * posx + posz * posz)/12 
var Iz = m * (posy * posy + posx * posx)/12 
 
const material = new THREE.MeshStandardMaterial({ color: 0x00aaff, roughness: 0.5, metalness: 0.5 }); 
material.shadowSide = THREE.DoubleSide; 
const geometry = new THREE.BoxGeometry(posx, posy, posz); 
const rectangle = new THREE.Mesh(geometry, material); 
scene.add(rectangle); 
 
//Плоскость 
const planeGeometry = new THREE.PlaneGeometry(window.innerWidth, window.innerHeight); 
const planeMaterial = new THREE.MeshStandardMaterial({ color: 0xbebebe }); 
const plane = new THREE.Mesh(planeGeometry, planeMaterial); 
plane.rotation.x = -Math.PI / 2; 
plane.position.y = -20 
scene.add(plane); 

//свет 
 
const directionalLight = new THREE.DirectionalLight(0xffffff, 1); 
directionalLight.position.set(0, 10, 0); 
directionalLight.castShadow = true; 
scene.add(directionalLight); 
 
renderer.shadowMap.enabled = true; 
rectangle.castShadow = true; 
plane.receiveShadow = true; 
 
// камера
const controls = new THREE.OrbitControls(camera, renderer.domElement); 
 
//движение (вокруг красной оси z ) 
 
var time = 10000 
var dt = 0.001 
 
var phinewx 
var phinewy 
var phinewz 
 
var omeganewx 
var omeganewy 
var omeganewz 
 
var phioldx = 0 
var phioldy = 0 
var phioldz = 0 
 
var omegaoldx = 0.00000001 * 2 * Math.PI 
var omegaoldy = 0.00000001 * 2 * Math.PI 
var omegaoldz = 1 * 2 * Math.PI 
 
var X = [0] 
var Y = [0] 
var Z = [0] 
 
for (var i = 1; i<time; i++){ 
 
	omeganewx = omegaoldx + (Iy - Iz)/Ix * omegaoldy * omegaoldz * dt 
	omeganewy = omegaoldy + (Iz - Ix)/Iy * omegaoldx * omegaoldz * dt 
	omeganewz = omegaoldz + (Ix - Iy)/Iz * omegaoldx * omegaoldy * dt 
 
	phinewx = phioldx + omeganewx * dt 
	phinewy = phioldy + omeganewy * dt 
	phinewz = phioldz + omeganewz * dt 
 
	omegaoldx = omeganewx 
	omegaoldy = omeganewy 
	omegaoldz = omeganewz 
 
	phioldx = phinewx 
	phioldy = phinewy 
	phioldz = phinewz 
 
	X[i] = phinewx 
	Y[i] = phinewy 
	Z[i] = phinewz 
} 
i = 1 
function animate() { 
 
	rectangle.rotation.x = X[i] 
	rectangle.rotation.y = Y[i] 
	rectangle.rotation.z = Z[i] 
 
	if (i<time-1){ 
		i++ 
		axesHelper.rotation.copy(rectangle.rotation); 
	} 
	requestAnimationFrame(animate); 
  	controls.update(); 
  	renderer.render(scene, camera); 
} 
 
animate(); 
Дополнен

код на html

По дате
По рейтингу
Аватар пользователя
Новичок

Попробуй уменьшить разницу между Ix, Iy, Iz. Пусть даже оставить posx, posy, posz прежними; а скорректировать формулы для I (сделать материал неоднородным)

Аватар пользователя
Искусственный Интеллект

Кто то бесплатно возиться будет. Ага,жди...