КП: Эффект Магнуса — различия между версиями
Shvarevng (обсуждение | вклад) (→Общие сведения по теме) |
(→Обсуждение результатов и выводы) |
||
(не показано 29 промежуточных версий 3 участников) | |||
Строка 15: | Строка 15: | ||
== Аннотация проекта == | == Аннотация проекта == | ||
− | Данный проект посвящен изучению [https://ru.wikipedia.org/wiki/%D0%AD%D1%84%D1%84%D0%B5%D0%BA%D1%82_%D0%9C%D0%B0%D0%B3%D0%BD%D1%83%D1%81%D0%B0 эффекта Магнуса], возникающего в различных видах спорта, а также использующегося в баллистике, летательных аппаратах и [https://en.wikipedia.org/wiki/E-Ship_1 кораблях].В ходе работы над проектом были рассмотрены траектории полета мяча в зависимости от различных начальных параметров (радиуса | + | Данный проект посвящен изучению [https://ru.wikipedia.org/wiki/%D0%AD%D1%84%D1%84%D0%B5%D0%BA%D1%82_%D0%9C%D0%B0%D0%B3%D0%BD%D1%83%D1%81%D0%B0 эффекта Магнуса], возникающего в различных видах спорта, а также использующегося в баллистике, летательных аппаратах и [https://en.wikipedia.org/wiki/E-Ship_1 кораблях].В ходе работы над проектом были рассмотрены траектории полета мяча и цилиндра в зависимости от различных начальных параметров (радиуса, динамической вязкости среды, плотности воздуха, линейной и угловой скорости). Программа написана на языке [https://ru.wikipedia.org/wiki/JavaScript JavaScript] с использование библиотеки [https://threejs.org Three.js]. |
== Формулировка задачи == | == Формулировка задачи == | ||
− | Построение и исследование математической модели движения объекта (в нашем случае - футбольного мяча), получение уравнения его движения и построение траектории в трехмерном пространстве с учётом различных внешних факторов, влияющих на движение, таких как сила сопротивления воздуха и эффект Магнуса. | + | Построение и исследование математической модели движения объекта (в нашем случае - футбольного мяча и цилиндра), получение уравнения его движения и построение траектории в трехмерном пространстве с учётом различных внешних факторов, влияющих на движение, таких как сила сопротивления воздуха и эффект Магнуса. |
== Общие сведения по теме == | == Общие сведения по теме == | ||
− | [[Файл: | + | [[Файл:PiXHK4A.gif|thumb|Пример влияния силы Магнуса на траекторию движения мяча[http://imgur.com/r/gifts/piXHK4A]|450px]] |
Эффект Магнуса - образование подъемной силы, действующей на вращающееся тело при обтекании его потоком жидкости или газа, широко использующейся в спорте, баллистике, летательных аппаратах и кораблях. <ref>[https://ru.wikipedia.org/wiki/%D0%AD%D1%84%D1%84%D0%B5%D0%BA%D1%82_%D0%9C%D0%B0%D0%B3%D0%BD%D1%83%D1%81%D0%B0 Сила Магнуса]</ref> | Эффект Магнуса - образование подъемной силы, действующей на вращающееся тело при обтекании его потоком жидкости или газа, широко использующейся в спорте, баллистике, летательных аппаратах и кораблях. <ref>[https://ru.wikipedia.org/wiki/%D0%AD%D1%84%D1%84%D0%B5%D0%BA%D1%82_%D0%9C%D0%B0%D0%B3%D0%BD%D1%83%D1%81%D0%B0 Сила Магнуса]</ref> | ||
− | Данный эффект возникает в результате разности давлений (в соответствии с законом Бернулли<ref>[https://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BA%D0%BE%D0%BD_%D0%91%D0%B5%D1%80%D0%BD%D1%83%D0%BB%D0%BB%D0%B8 Уравнение Бернулли]</ref>) на стенках | + | Данный эффект возникает в результате разности давлений (в соответствии с законом Бернулли<ref>[https://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BA%D0%BE%D0%BD_%D0%91%D0%B5%D1%80%D0%BD%D1%83%D0%BB%D0%BB%D0%B8 Уравнение Бернулли]</ref>) на стенках объекта из-за разных скоростей движения воздуха. Возникающий дисбаланс заставляет объект отклоняться. |
== Решение == | == Решение == | ||
− | Силу сопротивления воздуха будем считать с помощью закона Стокса<ref>[https://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BA%D0%BE%D0%BD_%D0%A1%D1%82%D0%BE%D0%BA%D1%81%D0%B0 Закон Стокса]</ref>: | + | Силу сопротивления воздуха для мяча будем считать с помощью закона Стокса<ref>[https://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BA%D0%BE%D0%BD_%D0%A1%D1%82%D0%BE%D0%BA%D1%81%D0%B0 Закон Стокса]</ref>: |
<big><math>\vec{F} = -6πrη\vec{v} </math></big> , где | <big><math>\vec{F} = -6πrη\vec{v} </math></big> , где | ||
Строка 45: | Строка 45: | ||
Силу Магнуса примем вида<ref>[http://www.your-own-science.org/this-is-not-a-pipes Формула Силы Магнуса]</ref>: | Силу Магнуса примем вида<ref>[http://www.your-own-science.org/this-is-not-a-pipes Формула Силы Магнуса]</ref>: | ||
− | <big><math>\vec{F} = | + | <big><math>\vec{F} = 2Sρr\vec{u}\times\vec{ω} </math></big> , где |
<math>\vec{F}</math> - сила Магнуса, | <math>\vec{F}</math> - сила Магнуса, | ||
+ | |||
+ | <math>S</math> - площадь действия силы, | ||
<math>ρ</math> - плотность воздуха, | <math>ρ</math> - плотность воздуха, | ||
− | <math>r</math> - радиус | + | <math>r</math> - радиус, |
− | <math>\vec{u}</math> - относительная скорость | + | <math>\vec{u}</math> - относительная скорость, |
− | <math>\vec{ω}</math> - угловая скорость | + | <math>\vec{ω}</math> - угловая скорость. |
Строка 62: | Строка 64: | ||
<big><math> | <big><math> | ||
\begin{cases} | \begin{cases} | ||
− | v_x^{i+1} = v_x^i + (-6πrηv_x^i/m + | + | v_x^{i+1} = v_x^i + (-6πrηv_x^i/m + 2Sρr(u_y^iω_z - u_z^iω_y)/m)\Delta t \\ |
− | v_y^{i+1} = v_y^i + (-6πrηv_y^i/m + | + | v_y^{i+1} = v_y^i + (-6πrηv_y^i/m + 2Sρr(u_z^iω_w - u_x^iω_z)/m)\Delta t \\ |
− | v_z^{i+1} = v_z^i + (-6πrηv_z^i/m - g + | + | v_z^{i+1} = v_z^i + (-6πrηv_z^i/m - g + 2Sρr(u_x^iω_y - u_y^iω_x)/m)\Delta t \\ |
\end{cases} | \end{cases} | ||
</math></big> | </math></big> | ||
Строка 77: | Строка 79: | ||
− | + | Реализация алгоритма. | |
+ | |||
+ | Возможности программы: | ||
+ | * поочередный запуск мяча и цилиндра, | ||
+ | * изменение параметров как в начале, так и во время полета, | ||
+ | * просмотр картинки в трехмерном изображении с помощью мыши | ||
+ | * сброс всех данных до начальных при нажатии кнопки "Reload" | ||
+ | |||
+ | {{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Shvarev/4.html |width=1100 |height=500 |border=0 }} | ||
+ | |||
+ | |||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | '''Текст программы на языке JavaScript:''' <div class="mw-collapsible-content"> | ||
+ | Файл '''"4.js"''' | ||
+ | <syntaxhighlight lang="javascript" line start="1" enclose="div"> | ||
+ | |||
+ | function main() | ||
+ | { | ||
+ | var scene = new THREE.Scene(); | ||
+ | var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); | ||
+ | var render = new THREE.WebGLRenderer(); | ||
+ | render.setClearColor(0x87CEFA, 1); | ||
+ | render.setSize(800, 400); | ||
+ | |||
+ | var axes = new THREE.AxisHelper(20); | ||
+ | scene.add(axes); | ||
+ | |||
+ | /** | ||
+ | var planeGeometry = new THREE.PlaneGeometry(105,68,50,1); | ||
+ | */ | ||
+ | var planeGeometry = new THREE.PlaneGeometry(1000,500,50,1); | ||
+ | var planeMaterial = new THREE.MeshLambertMaterial({color:0x068000}); | ||
+ | var plane = new THREE.Mesh(planeGeometry, planeMaterial); | ||
+ | plane.position.x=0; | ||
+ | plane.position.y=0; | ||
+ | plane.position.z=-0.11; | ||
+ | |||
+ | scene.add(plane); | ||
+ | |||
+ | var ballGeometry = new THREE.SphereGeometry( 0.11, 16, 16 ); | ||
+ | var ballMaterial = new THREE.MeshBasicMaterial( {color: 0xffff00,wireframe:true} ); | ||
+ | var ball = new THREE.Mesh( ballGeometry, ballMaterial ); | ||
+ | scene.add( ball ); | ||
+ | ball.castShadow = true; | ||
+ | |||
+ | |||
+ | var cylinderGeometry = new THREE.CylinderGeometry(0.11,0.11,1,16); | ||
+ | var cylinderMaterial = new THREE.MeshLambertMaterial({color:0xffff00}); | ||
+ | var cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial) | ||
+ | cylinder.position.x=0; | ||
+ | cylinder.position.y=0; | ||
+ | cylinder.position.z=0; | ||
+ | scene.add(cylinder); | ||
+ | cylinder.castShadow = true; | ||
+ | |||
+ | var trajectoryGeometryB = new THREE.SphereGeometry(0.05, 16, 16); | ||
+ | var trajectoryMaterialB = new THREE.MeshBasicMaterial( {color: 0x000000,wireframe:true} ); | ||
+ | |||
+ | var trajectoryGeometryC = new THREE.SphereGeometry(0.05, 16, 16); | ||
+ | var trajectoryMaterialC = new THREE.MeshBasicMaterial( {color: 0xFF0000,wireframe:true} ); | ||
+ | |||
+ | var traMaterialB = new THREE.MeshBasicMaterial({color: 0xffffff}); | ||
+ | var traGeometryB = new THREE.CircleGeometry( 0.05, 16); | ||
+ | |||
+ | var traMaterialC = new THREE.MeshBasicMaterial({color: 0xFF9900}); | ||
+ | var traGeometryC = new THREE.CircleGeometry( 0.05, 16); | ||
+ | |||
+ | |||
+ | /** | ||
+ | var cubeGeometry = new THREE.CubeGeometry(4,4,4); | ||
+ | var cubeMesh = new THREE.MeshLambertMaterial({color:0xff0000, wireframe:false}); | ||
+ | var cube = new THREE.Mesh(cubeGeometry, cubeMesh); | ||
+ | cube.position.x=-4; | ||
+ | cube.position.y=3; | ||
+ | cube.position.z=0; | ||
+ | scene.add(cube); | ||
+ | |||
+ | |||
+ | var cylinderGeometry = new THREE.CylinderGeometry(4,4,5,16); | ||
+ | var cylinderMaterial = new THREE.MeshLambertMaterial({color:0xaaee00}); | ||
+ | var cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial) | ||
+ | cylinder.position.x=10; | ||
+ | cylinder.position.y=10; | ||
+ | cylinder.position.z=0; | ||
+ | |||
+ | scene.add(cylinder); | ||
+ | */ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | var spotLight = new THREE.SpotLight(0xffffff); | ||
+ | spotLight.position.set(0,0,1500); | ||
+ | scene.add(spotLight); | ||
+ | |||
+ | |||
+ | spotLight.castShadow = true; | ||
+ | |||
+ | |||
+ | |||
+ | render.shadowMapEnabled = true; | ||
+ | plane.receiveShadow = true; | ||
+ | |||
+ | /** | ||
+ | cube.castShadow = true; | ||
+ | cylinder.castShadow = true; | ||
+ | */ | ||
+ | |||
+ | |||
+ | |||
+ | var a = new THREE.Vector3( 5, 2, -1 ); | ||
+ | var b = new THREE.Vector3( -1, 1, 1 ); | ||
+ | |||
+ | var c = new THREE.Vector3(); | ||
+ | c.crossVectors( a, b ); | ||
+ | |||
+ | camera.position.x= -30; | ||
+ | camera.position.y= 0; | ||
+ | camera.position.z= 60; | ||
+ | camera.lookAt(c); | ||
+ | |||
+ | camera.lookAt(scene.position); | ||
+ | $("#webGL").append(render.domElement); | ||
+ | |||
+ | |||
+ | |||
+ | var controls = new function() { | ||
+ | this.WindPowerX = 0; | ||
+ | this.WindPowerY = 0; | ||
+ | this.WindPowerZ = 0; | ||
+ | this.Mass = 0.45; | ||
+ | this.Radius = 0.11; | ||
+ | this.Height = 0.22; | ||
+ | this.Viscosity = 0.000178; | ||
+ | this.AirDensity = 1.2754; | ||
+ | this.g = 9.8 | ||
+ | this.Vx = 15; | ||
+ | this.Vy = 0; | ||
+ | this.Vz = 5; | ||
+ | this.OmegaX = 0; | ||
+ | this.OmegaY = 0; | ||
+ | this.OmegaZ = -10; | ||
+ | } | ||
+ | var gui = new dat.GUI(); | ||
+ | gui.add(controls, 'WindPowerX',-10,10); | ||
+ | gui.add(controls, 'WindPowerY',-10,10); | ||
+ | gui.add(controls, 'WindPowerZ',-10,10); | ||
+ | gui.add(controls, 'Mass',0.41,0.45); | ||
+ | gui.add(controls, 'Radius',0.01,0.21); | ||
+ | gui.add(controls, 'Height',0.1, 1); | ||
+ | gui.add(controls, 'Viscosity',0.00001, 0.001) | ||
+ | gui.add(controls, 'AirDensity',1, 1000) | ||
+ | gui.add(controls, 'g',0, 20) | ||
+ | gui.add(controls, 'Vx',0,40); | ||
+ | gui.add(controls, 'Vy',0,40); | ||
+ | gui.add(controls, 'Vz',0,40); | ||
+ | gui.add(controls, 'OmegaX',-10,10); | ||
+ | gui.add(controls, 'OmegaY',-10,10); | ||
+ | gui.add(controls, 'OmegaZ',-10,10); | ||
+ | |||
+ | |||
+ | contr = new THREE.OrbitControls(camera); | ||
+ | contr.dumping = 0.2; | ||
+ | |||
+ | |||
+ | |||
+ | /**contr = new THREE.TrackballControls(camera); | ||
+ | contr.rotateSpeed = 1.0; | ||
+ | contr.zoomSpeed = 1.2; | ||
+ | contr.panSpeed = 0.8; | ||
+ | contr.noZoom = false; | ||
+ | contr.noPan = false; | ||
+ | contr.staticMoving = true; | ||
+ | contr.dynamicDampingFactor = 0.3; | ||
+ | contr.keys = [65,83,68]; | ||
+ | */ | ||
+ | |||
+ | |||
+ | /**window.addEventListener('resize',onWindowResize,false); | ||
+ | function onWindowResize() | ||
+ | { | ||
+ | camera.aspect = window.innerWidth/window.innerHeight; | ||
+ | camera.updateProjectionMatrix(); | ||
+ | render.setSize(window.innerWidth,window.innerHeight); | ||
+ | |||
+ | renderer(); | ||
+ | } | ||
+ | */ | ||
+ | |||
+ | var stats = initStats(); | ||
+ | var step = 0; | ||
+ | |||
+ | |||
+ | Vx = 0; | ||
+ | Vy = 0; | ||
+ | Vz = 0; | ||
+ | Mass = 0; | ||
+ | Viscosity = 0; | ||
+ | dt = 0.01; | ||
+ | Radius = 0; | ||
+ | g = 0; | ||
+ | WindX = 0; | ||
+ | WindY = 0; | ||
+ | WindZ = 0; | ||
+ | AirDensity = 0; | ||
+ | |||
+ | Height = 1; | ||
+ | |||
+ | var VxB =controls.Vx; | ||
+ | var VxC =controls.Vx; | ||
+ | var VyB =controls.Vy; | ||
+ | var VyC =controls.Vy; | ||
+ | var VzB =controls.Vz; | ||
+ | var VzC =controls.Vz; | ||
+ | |||
+ | OmegaXB = controls.OmegaX; | ||
+ | OmegaXC = controls.OmegaX; | ||
+ | OmegaYB = controls.OmegaY; | ||
+ | OmegaYC = controls.OmegaY; | ||
+ | OmegaZB = controls.OmegaZ; | ||
+ | OmegaZC = controls.OmegaZ; | ||
+ | |||
+ | |||
+ | pppB = 0; | ||
+ | pppC = 0; | ||
+ | kkk = 0; | ||
+ | |||
+ | function renderer() | ||
+ | { | ||
+ | /** | ||
+ | cube.rotation.x+=controls.rotationSpeed; | ||
+ | cube.rotation.y+=controls.rotationSpeed; | ||
+ | cube.rotation.z+=controls.rotationSpeed; | ||
+ | |||
+ | cylinder.position.x = 20+(10*(Math.cos(step))); | ||
+ | cylinder.position.y = 2+(10*(Math.abs(Math.sin(step)))); | ||
+ | |||
+ | |||
+ | */ | ||
+ | |||
+ | if (pppB == 0) | ||
+ | { | ||
+ | VxB+=controls.Vx; | ||
+ | VyB+=controls.Vy; | ||
+ | VzB+=controls.Vz; | ||
+ | WindX = controls.WindPowerX; | ||
+ | WindY = controls.WindPowerY; | ||
+ | WindZ = controls.WindPowerZ; | ||
+ | |||
+ | OmegaXB = controls.OmegaX; | ||
+ | OmegaYB = controls.OmegaY; | ||
+ | OmegaZB = controls.OmegaZ; | ||
+ | |||
+ | |||
+ | pppB = 1; | ||
+ | |||
+ | } | ||
+ | |||
+ | UxB = VxB - WindX; | ||
+ | UyB = VyB - WindY; | ||
+ | UzB = VzB - WindZ; | ||
+ | |||
+ | Mass=controls.Mass; | ||
+ | Radius=controls.Radius; | ||
+ | Viscosity = controls.Viscosity; | ||
+ | g = controls.g; | ||
+ | |||
+ | AirDensity = controls.AirDensity; | ||
+ | |||
+ | |||
+ | if (ball.position.z >= 0) | ||
+ | { | ||
+ | |||
+ | /** | ||
+ | VxB += (-6*Math.PI*Viscosity*Radius*VxB/Mass + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UyB*OmegaZB - UzB*OmegaYB)/Mass)*dt; | ||
+ | VyB += (-6*Math.PI*Viscosity*Radius*VyB/Mass + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UzB*OmegaXB - UxB*OmegaZB)/Mass )*dt; | ||
+ | VzB += (-6*Math.PI*Viscosity*Radius*VzB/Mass - g + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UxB*OmegaYB - UyB*OmegaXB)/Mass)*dt; | ||
+ | |||
+ | OmegaXB += -6*Math.PI*Viscosity*Radius*OmegaXB*Radius/Mass; | ||
+ | OmegaYB += -6*Math.PI*Viscosity*Radius*OmegaYB*Radius/Mass; | ||
+ | OmegaZB += -6*Math.PI*Viscosity*Radius*OmegaZB*Radius/Mass; | ||
+ | |||
+ | */ | ||
+ | |||
+ | VxB += (2*Math.PI*AirDensity*Radius*Radius*Radius*(UyB*OmegaZB - UzB*OmegaYB)/Mass)*dt; | ||
+ | VyB += (2*Math.PI*AirDensity*Radius*Radius*Radius*(UzB*OmegaXB - UxB*OmegaZB)/Mass )*dt; | ||
+ | VzB += (-g + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UxB*OmegaYB - UyB*OmegaXB)/Mass)*dt; | ||
+ | |||
+ | ball.position.x += VxB*dt; | ||
+ | ball.position.y += VyB*dt; | ||
+ | ball.position.z += VzB*dt; | ||
+ | |||
+ | |||
+ | |||
+ | ball.rotation.x += OmegaXB*dt; | ||
+ | ball.rotation.y += OmegaYB*dt; | ||
+ | ball.rotation.z += OmegaZB*dt; | ||
+ | |||
+ | var trajectoryB = new THREE.Mesh(trajectoryGeometryB, trajectoryMaterialB); | ||
+ | trajectoryB.position.x = ball.position.x; | ||
+ | trajectoryB.position.y = ball.position.y; | ||
+ | trajectoryB.position.z = ball.position.z; | ||
+ | |||
+ | scene.add( trajectoryB ); | ||
+ | |||
+ | |||
+ | var traB = new THREE.Mesh( traGeometryB, traMaterialB); | ||
+ | traB.position.x = ball.position.x; | ||
+ | traB.position.y = ball.position.y; | ||
+ | traB.position.z = 0; | ||
+ | scene.add(traB); | ||
+ | |||
+ | document.getElementById("td1").innerHTML = ball.position.y ; | ||
+ | document.getElementById("td2").innerHTML = ball.position.x ; | ||
+ | |||
+ | } | ||
+ | |||
+ | requestAnimationFrame(renderer); | ||
+ | |||
+ | contr.update(); | ||
+ | |||
+ | render.render(scene,camera); | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | alpha1 = 0; | ||
+ | alpha2 = 0; | ||
+ | alpha3 = 0; | ||
+ | rot1 = 0; | ||
+ | rot2 = 0; | ||
+ | rot3 = 0; | ||
+ | |||
+ | function renderer2() | ||
+ | { | ||
+ | |||
+ | |||
+ | if (pppC == 0) | ||
+ | { | ||
+ | VyC+=controls.Vy; | ||
+ | VxC+=controls.Vx; | ||
+ | VzC+=controls.Vz; | ||
+ | WindX = controls.WindPowerX; | ||
+ | WindY = controls.WindPowerY; | ||
+ | WindZ = controls.WindPowerZ; | ||
+ | |||
+ | OmegaXC = controls.OmegaX; | ||
+ | OmegaYC = controls.OmegaY; | ||
+ | OmegaZC = controls.OmegaZ; | ||
+ | |||
+ | |||
+ | pppC = 1; | ||
+ | |||
+ | } | ||
+ | |||
+ | UxC = VxC - WindX; | ||
+ | UyC = VyC - WindY; | ||
+ | UzC = VzC - WindZ; | ||
+ | |||
+ | Mass=controls.Mass; | ||
+ | Radius=controls.Radius; | ||
+ | Viscosity = controls.Viscosity; | ||
+ | g = controls.g; | ||
+ | Height = controls.Height; | ||
+ | AirDensity = controls.AirDensity; | ||
+ | |||
+ | var cylinderGeometry = new THREE.CylinderGeometry(2*Radius,2*Radius, Height, 16); | ||
+ | |||
+ | cylinder.geometry = cylinderGeometry; | ||
+ | |||
+ | |||
+ | if (cylinder.position.z >= 0) | ||
+ | { | ||
+ | /** | ||
+ | VxC += (-6*Math.PI*Viscosity*Radius*VxC/Mass + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UyC*OmegaZC - UzC*OmegaYC)/Mass)*dt; | ||
+ | VyC += (-6*Math.PI*Viscosity*Radius*VyC/Mass + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UzC*OmegaXC - UxC*OmegaZC)/Mass )*dt; | ||
+ | VzC += (-6*Math.PI*Viscosity*Radius*VzC/Mass - g + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UxC*OmegaYC - UyC*OmegaXC)/Mass)*dt; | ||
+ | |||
+ | OmegaXC += -6*Math.PI*Viscosity*Radius*OmegaXC*Radius/Mass; | ||
+ | OmegaYC += -6*Math.PI*Viscosity*Radius*OmegaYC*Radius/Mass; | ||
+ | OmegaZC += -6*Math.PI*Viscosity*Radius*OmegaZC*Radius/Mass; | ||
+ | */ | ||
+ | /** | ||
+ | VxC += (2*Math.PI*AirDensity*Radius*Radius*Radius*(UyC*OmegaZC - UzC*OmegaYC)/Mass)*dt; | ||
+ | VyC += (2*Math.PI*AirDensity*Radius*Radius*Radius*(UzC*OmegaXC - UxC*OmegaZC)/Mass )*dt; | ||
+ | VzC += (-g + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UxC*OmegaYC - UyC*OmegaXC)/Mass)*dt; | ||
+ | */ | ||
+ | |||
+ | |||
+ | alpha1 = (cylinder.rotation.x - rot1)/(2*Math.PI); | ||
+ | alpha2 = (cylinder.rotation.y - rot2)/(2*Math.PI); | ||
+ | alpha3 = (cylinder.rotation.z - rot3)/(2*Math.PI); | ||
+ | |||
+ | rot1 = cylinder.rotation.x; | ||
+ | rot2 = cylinder.rotation.y; | ||
+ | rot3 = cylinder.rotation.z; | ||
+ | |||
+ | VxC += (2*AirDensity*Radius*(2*Radius*Height*Math.cos(alpha1) + Math.PI*Radius*Radius*Math.sin(alpha1) )*(UyC*OmegaZC - UzC*OmegaYC)/Mass)*dt; | ||
+ | VyC += (2*AirDensity*Radius*(2*Radius*Height*Math.sin(alpha2) + Math.PI*Radius*Radius*Math.cos(alpha2))*(UzC*OmegaXC - UxC*OmegaZC)/Mass )*dt; | ||
+ | VzC += (-g + 2*AirDensity*Radius*(2*Radius*Height*Math.cos(alpha3) + Math.PI*Radius*Radius*Math.sin(alpha3))*(UxC*OmegaYC - UyC*OmegaXC)/Mass)*dt; | ||
+ | |||
+ | cylinder.position.x += VxC*dt; | ||
+ | cylinder.position.y += VyC*dt; | ||
+ | cylinder.position.z += VzC*dt; | ||
+ | |||
+ | cylinder.rotation.x += OmegaXC*dt; | ||
+ | cylinder.rotation.y += OmegaYC*dt; | ||
+ | cylinder.rotation.z += OmegaZC*dt; | ||
+ | |||
− | + | ||
+ | var trajectoryC = new THREE.Mesh(trajectoryGeometryC, trajectoryMaterialC); | ||
+ | trajectoryC.position.x = cylinder.position.x; | ||
+ | trajectoryC.position.y = cylinder.position.y; | ||
+ | trajectoryC.position.z = cylinder.position.z; | ||
+ | |||
+ | scene.add( trajectoryC ); | ||
+ | |||
+ | var traC = new THREE.Mesh( traGeometryC, traMaterialC); | ||
+ | traC.position.x = cylinder.position.x; | ||
+ | traC.position.y = cylinder.position.y; | ||
+ | traC.position.z = 0; | ||
+ | scene.add(traC); | ||
+ | |||
+ | document.getElementById("td3").innerHTML = cylinder.position.y ; | ||
+ | document.getElementById("td4").innerHTML = cylinder.position.x; | ||
+ | |||
+ | } | ||
+ | |||
+ | requestAnimationFrame(renderer2); | ||
+ | |||
+ | contr.update(); | ||
+ | |||
+ | render.render(scene,camera); | ||
+ | |||
+ | } | ||
+ | |||
+ | this.start = renderer; | ||
+ | this.start2 = renderer2; | ||
+ | |||
+ | |||
+ | |||
+ | } | ||
+ | function initStats() | ||
+ | { | ||
+ | var stats = new Stats(); | ||
+ | stats.setMode(0); | ||
+ | stats.domElement.style.position='absolute'; | ||
+ | stats.domElement.style.left = '0px'; | ||
+ | stats.domElement.style.top = '0px'; | ||
+ | $("#Stats").append(stats.domElement); | ||
+ | return stats; | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | </syntaxhighlight> | ||
+ | </div> | ||
== Обсуждение результатов и выводы == | == Обсуждение результатов и выводы == | ||
Строка 87: | Строка 546: | ||
Разработанный алгоритм был реализован в среде программирования Javascript с использование библиотеки Three.js. Была построена траектория движения и произведены эксперименты, результаты которых находятся в таблице ниже: | Разработанный алгоритм был реализован в среде программирования Javascript с использование библиотеки Three.js. Была построена траектория движения и произведены эксперименты, результаты которых находятся в таблице ниже: | ||
+ | Шар: | ||
{| border="1" | {| border="1" | ||
Строка 96: | Строка 556: | ||
|<math>ω_y</math> | |<math>ω_y</math> | ||
|<math>ω_z</math> | |<math>ω_z</math> | ||
− | |<math> | + | |<math>m</math> |
− | |<math> | + | |<math>r</math> |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
|<math>Δ_y</math> | |<math>Δ_y</math> | ||
|- | |- | ||
− | | | + | |15 |
|0 | |0 | ||
|5 | |5 | ||
|0 | |0 | ||
|0 | |0 | ||
− | | - | + | | -10 |
− | | | + | |0.45 |
+ | |0.11 | ||
+ | |14.585 | ||
+ | |- | ||
+ | |15 | ||
+ | |0 | ||
|5 | |5 | ||
|0 | |0 | ||
− | |||
− | |||
|0 | |0 | ||
+ | | -10 | ||
+ | |0.41 | ||
+ | |0.11 | ||
+ | |15.945 | ||
+ | |- | ||
+ | |15 | ||
|0 | |0 | ||
− | |||
− | |||
|5 | |5 | ||
+ | |0 | ||
|0 | |0 | ||
| -10 | | -10 | ||
− | | | + | |0.45 |
+ | |0.01 | ||
+ | |0.011 | ||
|- | |- | ||
− | | | + | |15 |
|0 | |0 | ||
|5 | |5 | ||
Строка 136: | Строка 596: | ||
|0 | |0 | ||
| -5 | | -5 | ||
− | | | + | |0.45 |
+ | |0.11 | ||
+ | |7.399 | ||
+ | |- | ||
+ | |7.5 | ||
+ | |0 | ||
|5 | |5 | ||
|0 | |0 | ||
− | |||
− | |||
|0 | |0 | ||
+ | | -10 | ||
+ | |0.45 | ||
+ | |0.11 | ||
+ | |7.292 | ||
+ | |} | ||
+ | |||
+ | Цилиндр: | ||
+ | |||
+ | {| border="1" | ||
+ | |- | ||
+ | |<math>V_x</math> | ||
+ | |<math>V_y</math> | ||
+ | |<math>V_z</math> | ||
+ | |<math>ω_x</math> | ||
+ | |<math>ω_y</math> | ||
+ | |<math>ω_z</math> | ||
+ | |<math>m</math> | ||
+ | |<math>r</math> | ||
+ | |<math>h</math> | ||
+ | |<math>Δ_y</math> | ||
+ | |- | ||
+ | |15 | ||
|0 | |0 | ||
− | |||
− | |||
|5 | |5 | ||
+ | |0 | ||
|0 | |0 | ||
| -10 | | -10 | ||
− | | | + | |0.45 |
+ | |0.11 | ||
+ | |0.22 | ||
+ | |14.508 | ||
|- | |- | ||
|15 | |15 | ||
Строка 155: | Строка 642: | ||
|0 | |0 | ||
|0 | |0 | ||
− | | - | + | | -10 |
− | | | + | |0.41 |
+ | |0.11 | ||
+ | |0.22 | ||
+ | |15.844 | ||
+ | |- | ||
+ | |15 | ||
+ | |0 | ||
|5 | |5 | ||
|0 | |0 | ||
− | |||
− | |||
|0 | |0 | ||
+ | | -10 | ||
+ | |0.45 | ||
+ | |0.01 | ||
+ | |0.22 | ||
+ | |0.011 | ||
+ | |- | ||
+ | |15 | ||
|0 | |0 | ||
− | |||
− | |||
|5 | |5 | ||
+ | |0 | ||
|0 | |0 | ||
| -10 | | -10 | ||
− | |13. | + | |0.45 |
+ | |0.11 | ||
+ | |1 | ||
+ | |13.287 | ||
|- | |- | ||
− | | | + | |15 |
|0 | |0 | ||
|5 | |5 | ||
Строка 176: | Строка 676: | ||
|0 | |0 | ||
| -5 | | -5 | ||
− | | | + | |0.45 |
+ | |0.11 | ||
+ | |0.22 | ||
+ | |7.389 | ||
+ | |- | ||
+ | |7.5 | ||
+ | |0 | ||
|5 | |5 | ||
− | |||
− | |||
− | |||
|0 | |0 | ||
|0 | |0 | ||
| -10 | | -10 | ||
− | | | + | |0.45 |
− | | | + | |0.11 |
− | |0 | + | |0.22 |
− | | | + | |7.254 |
− | |||
|} | |} | ||
− | где <math>V_x</math>, <math>V_y</math>, <math>V_z</math> - начальные линейные скорости, <math>ω_x</math>, <math>ω_y</math>, <math>ω_z</math> - начальные угловые скорости, а <math>Δ_y</math> - полученное смещение по оси <math>y</math>. | + | |
+ | где <math>V_x</math>, <math>V_y</math>, <math>V_z</math> - начальные линейные скорости, <math>ω_x</math>, <math>ω_y</math>, <math>ω_z</math> - начальные угловые скорости, <math>m</math> - масса объекта, <math>r</math> - радиус объекта, <math>h</math> - высота цилиндра, а <math>Δ_y</math> - полученное смещение по оси <math>y</math>. | ||
+ | |||
+ | '''Вывод:''' Исходя из численных данных, полученных после проведения экспериментов, можно сделать вывод, что относительное смещение зависит от угловой скорости, радиуса, массы и силы тяжести, но не зависит от линейной скорости. Например, при уменьшении угловой скорости в 2 раза следует уменьшение относительного отклонения в ~2 раза, а при уменьшении линейной скорости в 2 раза относительное отклонение остается таким же. | ||
<br> | <br> | ||
− | Скачать отчет: | + | Скачать отчет: [[Медиа:CourseworkShvarevNikolay.doc|doc]]. |
<br> | <br> | ||
− | Скачать презентацию: | + | Скачать презентацию: [[Медиа:CourseworkShvarevNikolay.pptx|pptx]]. |
== Ссылки по теме == | == Ссылки по теме == |
Текущая версия на 13:51, 3 июня 2015
А.М. Кривцов > Теоретическая механика > Курсовые проекты ТМ 2015 > Эффект Магнуса
Курсовой проект по Теоретической механике
Исполнитель: Шварёв Николай
Группа: 09 (23604)
Семестр: весна 2015
Содержание
Аннотация проекта[править]
Данный проект посвящен изучению эффекта Магнуса, возникающего в различных видах спорта, а также использующегося в баллистике, летательных аппаратах и кораблях.В ходе работы над проектом были рассмотрены траектории полета мяча и цилиндра в зависимости от различных начальных параметров (радиуса, динамической вязкости среды, плотности воздуха, линейной и угловой скорости). Программа написана на языке JavaScript с использование библиотеки Three.js.
Формулировка задачи[править]
Построение и исследование математической модели движения объекта (в нашем случае - футбольного мяча и цилиндра), получение уравнения его движения и построение траектории в трехмерном пространстве с учётом различных внешних факторов, влияющих на движение, таких как сила сопротивления воздуха и эффект Магнуса.
Общие сведения по теме[править]
Эффект Магнуса - образование подъемной силы, действующей на вращающееся тело при обтекании его потоком жидкости или газа, широко использующейся в спорте, баллистике, летательных аппаратах и кораблях. [2]
Данный эффект возникает в результате разности давлений (в соответствии с законом Бернулли[3]) на стенках объекта из-за разных скоростей движения воздуха. Возникающий дисбаланс заставляет объект отклоняться.
Решение[править]
Силу сопротивления воздуха для мяча будем считать с помощью закона Стокса[4]:
, где
- сила Стокса,
- радиус мяча,
- динамическая вязкость среды,
- скорость мяча.
Силу Магнуса примем вида[5]:
, где
- сила Магнуса,
- площадь действия силы,
- плотность воздуха,
- радиус,
- относительная скорость,
- угловая скорость.
Применив метод Эйлера, получим формулы для нахождения скорости и координаты мяча:
Реализация алгоритма.
Возможности программы:
- поочередный запуск мяча и цилиндра,
- изменение параметров как в начале, так и во время полета,
- просмотр картинки в трехмерном изображении с помощью мыши
- сброс всех данных до начальных при нажатии кнопки "Reload"
Файл "4.js"
1 function main()
2 {
3 var scene = new THREE.Scene();
4 var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);
5 var render = new THREE.WebGLRenderer();
6 render.setClearColor(0x87CEFA, 1);
7 render.setSize(800, 400);
8
9 var axes = new THREE.AxisHelper(20);
10 scene.add(axes);
11
12 /**
13 var planeGeometry = new THREE.PlaneGeometry(105,68,50,1);
14 */
15 var planeGeometry = new THREE.PlaneGeometry(1000,500,50,1);
16 var planeMaterial = new THREE.MeshLambertMaterial({color:0x068000});
17 var plane = new THREE.Mesh(planeGeometry, planeMaterial);
18 plane.position.x=0;
19 plane.position.y=0;
20 plane.position.z=-0.11;
21
22 scene.add(plane);
23
24 var ballGeometry = new THREE.SphereGeometry( 0.11, 16, 16 );
25 var ballMaterial = new THREE.MeshBasicMaterial( {color: 0xffff00,wireframe:true} );
26 var ball = new THREE.Mesh( ballGeometry, ballMaterial );
27 scene.add( ball );
28 ball.castShadow = true;
29
30
31 var cylinderGeometry = new THREE.CylinderGeometry(0.11,0.11,1,16);
32 var cylinderMaterial = new THREE.MeshLambertMaterial({color:0xffff00});
33 var cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial)
34 cylinder.position.x=0;
35 cylinder.position.y=0;
36 cylinder.position.z=0;
37 scene.add(cylinder);
38 cylinder.castShadow = true;
39
40 var trajectoryGeometryB = new THREE.SphereGeometry(0.05, 16, 16);
41 var trajectoryMaterialB = new THREE.MeshBasicMaterial( {color: 0x000000,wireframe:true} );
42
43 var trajectoryGeometryC = new THREE.SphereGeometry(0.05, 16, 16);
44 var trajectoryMaterialC = new THREE.MeshBasicMaterial( {color: 0xFF0000,wireframe:true} );
45
46 var traMaterialB = new THREE.MeshBasicMaterial({color: 0xffffff});
47 var traGeometryB = new THREE.CircleGeometry( 0.05, 16);
48
49 var traMaterialC = new THREE.MeshBasicMaterial({color: 0xFF9900});
50 var traGeometryC = new THREE.CircleGeometry( 0.05, 16);
51
52
53 /**
54 var cubeGeometry = new THREE.CubeGeometry(4,4,4);
55 var cubeMesh = new THREE.MeshLambertMaterial({color:0xff0000, wireframe:false});
56 var cube = new THREE.Mesh(cubeGeometry, cubeMesh);
57 cube.position.x=-4;
58 cube.position.y=3;
59 cube.position.z=0;
60 scene.add(cube);
61
62
63 var cylinderGeometry = new THREE.CylinderGeometry(4,4,5,16);
64 var cylinderMaterial = new THREE.MeshLambertMaterial({color:0xaaee00});
65 var cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial)
66 cylinder.position.x=10;
67 cylinder.position.y=10;
68 cylinder.position.z=0;
69
70 scene.add(cylinder);
71 */
72
73
74
75
76 var spotLight = new THREE.SpotLight(0xffffff);
77 spotLight.position.set(0,0,1500);
78 scene.add(spotLight);
79
80
81 spotLight.castShadow = true;
82
83
84
85 render.shadowMapEnabled = true;
86 plane.receiveShadow = true;
87
88 /**
89 cube.castShadow = true;
90 cylinder.castShadow = true;
91 */
92
93
94
95 var a = new THREE.Vector3( 5, 2, -1 );
96 var b = new THREE.Vector3( -1, 1, 1 );
97
98 var c = new THREE.Vector3();
99 c.crossVectors( a, b );
100
101 camera.position.x= -30;
102 camera.position.y= 0;
103 camera.position.z= 60;
104 camera.lookAt(c);
105
106 camera.lookAt(scene.position);
107 $("#webGL").append(render.domElement);
108
109
110
111 var controls = new function() {
112 this.WindPowerX = 0;
113 this.WindPowerY = 0;
114 this.WindPowerZ = 0;
115 this.Mass = 0.45;
116 this.Radius = 0.11;
117 this.Height = 0.22;
118 this.Viscosity = 0.000178;
119 this.AirDensity = 1.2754;
120 this.g = 9.8
121 this.Vx = 15;
122 this.Vy = 0;
123 this.Vz = 5;
124 this.OmegaX = 0;
125 this.OmegaY = 0;
126 this.OmegaZ = -10;
127 }
128 var gui = new dat.GUI();
129 gui.add(controls, 'WindPowerX',-10,10);
130 gui.add(controls, 'WindPowerY',-10,10);
131 gui.add(controls, 'WindPowerZ',-10,10);
132 gui.add(controls, 'Mass',0.41,0.45);
133 gui.add(controls, 'Radius',0.01,0.21);
134 gui.add(controls, 'Height',0.1, 1);
135 gui.add(controls, 'Viscosity',0.00001, 0.001)
136 gui.add(controls, 'AirDensity',1, 1000)
137 gui.add(controls, 'g',0, 20)
138 gui.add(controls, 'Vx',0,40);
139 gui.add(controls, 'Vy',0,40);
140 gui.add(controls, 'Vz',0,40);
141 gui.add(controls, 'OmegaX',-10,10);
142 gui.add(controls, 'OmegaY',-10,10);
143 gui.add(controls, 'OmegaZ',-10,10);
144
145
146 contr = new THREE.OrbitControls(camera);
147 contr.dumping = 0.2;
148
149
150
151 /**contr = new THREE.TrackballControls(camera);
152 contr.rotateSpeed = 1.0;
153 contr.zoomSpeed = 1.2;
154 contr.panSpeed = 0.8;
155 contr.noZoom = false;
156 contr.noPan = false;
157 contr.staticMoving = true;
158 contr.dynamicDampingFactor = 0.3;
159 contr.keys = [65,83,68];
160 */
161
162
163 /**window.addEventListener('resize',onWindowResize,false);
164 function onWindowResize()
165 {
166 camera.aspect = window.innerWidth/window.innerHeight;
167 camera.updateProjectionMatrix();
168 render.setSize(window.innerWidth,window.innerHeight);
169
170 renderer();
171 }
172 */
173
174 var stats = initStats();
175 var step = 0;
176
177
178 Vx = 0;
179 Vy = 0;
180 Vz = 0;
181 Mass = 0;
182 Viscosity = 0;
183 dt = 0.01;
184 Radius = 0;
185 g = 0;
186 WindX = 0;
187 WindY = 0;
188 WindZ = 0;
189 AirDensity = 0;
190
191 Height = 1;
192
193 var VxB =controls.Vx;
194 var VxC =controls.Vx;
195 var VyB =controls.Vy;
196 var VyC =controls.Vy;
197 var VzB =controls.Vz;
198 var VzC =controls.Vz;
199
200 OmegaXB = controls.OmegaX;
201 OmegaXC = controls.OmegaX;
202 OmegaYB = controls.OmegaY;
203 OmegaYC = controls.OmegaY;
204 OmegaZB = controls.OmegaZ;
205 OmegaZC = controls.OmegaZ;
206
207
208 pppB = 0;
209 pppC = 0;
210 kkk = 0;
211
212 function renderer()
213 {
214 /**
215 cube.rotation.x+=controls.rotationSpeed;
216 cube.rotation.y+=controls.rotationSpeed;
217 cube.rotation.z+=controls.rotationSpeed;
218
219 cylinder.position.x = 20+(10*(Math.cos(step)));
220 cylinder.position.y = 2+(10*(Math.abs(Math.sin(step))));
221
222
223 */
224
225 if (pppB == 0)
226 {
227 VxB+=controls.Vx;
228 VyB+=controls.Vy;
229 VzB+=controls.Vz;
230 WindX = controls.WindPowerX;
231 WindY = controls.WindPowerY;
232 WindZ = controls.WindPowerZ;
233
234 OmegaXB = controls.OmegaX;
235 OmegaYB = controls.OmegaY;
236 OmegaZB = controls.OmegaZ;
237
238
239 pppB = 1;
240
241 }
242
243 UxB = VxB - WindX;
244 UyB = VyB - WindY;
245 UzB = VzB - WindZ;
246
247 Mass=controls.Mass;
248 Radius=controls.Radius;
249 Viscosity = controls.Viscosity;
250 g = controls.g;
251
252 AirDensity = controls.AirDensity;
253
254
255 if (ball.position.z >= 0)
256 {
257
258 /**
259 VxB += (-6*Math.PI*Viscosity*Radius*VxB/Mass + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UyB*OmegaZB - UzB*OmegaYB)/Mass)*dt;
260 VyB += (-6*Math.PI*Viscosity*Radius*VyB/Mass + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UzB*OmegaXB - UxB*OmegaZB)/Mass )*dt;
261 VzB += (-6*Math.PI*Viscosity*Radius*VzB/Mass - g + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UxB*OmegaYB - UyB*OmegaXB)/Mass)*dt;
262
263 OmegaXB += -6*Math.PI*Viscosity*Radius*OmegaXB*Radius/Mass;
264 OmegaYB += -6*Math.PI*Viscosity*Radius*OmegaYB*Radius/Mass;
265 OmegaZB += -6*Math.PI*Viscosity*Radius*OmegaZB*Radius/Mass;
266
267 */
268
269 VxB += (2*Math.PI*AirDensity*Radius*Radius*Radius*(UyB*OmegaZB - UzB*OmegaYB)/Mass)*dt;
270 VyB += (2*Math.PI*AirDensity*Radius*Radius*Radius*(UzB*OmegaXB - UxB*OmegaZB)/Mass )*dt;
271 VzB += (-g + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UxB*OmegaYB - UyB*OmegaXB)/Mass)*dt;
272
273 ball.position.x += VxB*dt;
274 ball.position.y += VyB*dt;
275 ball.position.z += VzB*dt;
276
277
278
279 ball.rotation.x += OmegaXB*dt;
280 ball.rotation.y += OmegaYB*dt;
281 ball.rotation.z += OmegaZB*dt;
282
283 var trajectoryB = new THREE.Mesh(trajectoryGeometryB, trajectoryMaterialB);
284 trajectoryB.position.x = ball.position.x;
285 trajectoryB.position.y = ball.position.y;
286 trajectoryB.position.z = ball.position.z;
287
288 scene.add( trajectoryB );
289
290
291 var traB = new THREE.Mesh( traGeometryB, traMaterialB);
292 traB.position.x = ball.position.x;
293 traB.position.y = ball.position.y;
294 traB.position.z = 0;
295 scene.add(traB);
296
297 document.getElementById("td1").innerHTML = ball.position.y ;
298 document.getElementById("td2").innerHTML = ball.position.x ;
299
300 }
301
302 requestAnimationFrame(renderer);
303
304 contr.update();
305
306 render.render(scene,camera);
307
308
309
310
311 }
312
313 alpha1 = 0;
314 alpha2 = 0;
315 alpha3 = 0;
316 rot1 = 0;
317 rot2 = 0;
318 rot3 = 0;
319
320 function renderer2()
321 {
322
323
324 if (pppC == 0)
325 {
326 VyC+=controls.Vy;
327 VxC+=controls.Vx;
328 VzC+=controls.Vz;
329 WindX = controls.WindPowerX;
330 WindY = controls.WindPowerY;
331 WindZ = controls.WindPowerZ;
332
333 OmegaXC = controls.OmegaX;
334 OmegaYC = controls.OmegaY;
335 OmegaZC = controls.OmegaZ;
336
337
338 pppC = 1;
339
340 }
341
342 UxC = VxC - WindX;
343 UyC = VyC - WindY;
344 UzC = VzC - WindZ;
345
346 Mass=controls.Mass;
347 Radius=controls.Radius;
348 Viscosity = controls.Viscosity;
349 g = controls.g;
350 Height = controls.Height;
351 AirDensity = controls.AirDensity;
352
353 var cylinderGeometry = new THREE.CylinderGeometry(2*Radius,2*Radius, Height, 16);
354
355 cylinder.geometry = cylinderGeometry;
356
357
358 if (cylinder.position.z >= 0)
359 {
360 /**
361 VxC += (-6*Math.PI*Viscosity*Radius*VxC/Mass + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UyC*OmegaZC - UzC*OmegaYC)/Mass)*dt;
362 VyC += (-6*Math.PI*Viscosity*Radius*VyC/Mass + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UzC*OmegaXC - UxC*OmegaZC)/Mass )*dt;
363 VzC += (-6*Math.PI*Viscosity*Radius*VzC/Mass - g + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UxC*OmegaYC - UyC*OmegaXC)/Mass)*dt;
364
365 OmegaXC += -6*Math.PI*Viscosity*Radius*OmegaXC*Radius/Mass;
366 OmegaYC += -6*Math.PI*Viscosity*Radius*OmegaYC*Radius/Mass;
367 OmegaZC += -6*Math.PI*Viscosity*Radius*OmegaZC*Radius/Mass;
368 */
369 /**
370 VxC += (2*Math.PI*AirDensity*Radius*Radius*Radius*(UyC*OmegaZC - UzC*OmegaYC)/Mass)*dt;
371 VyC += (2*Math.PI*AirDensity*Radius*Radius*Radius*(UzC*OmegaXC - UxC*OmegaZC)/Mass )*dt;
372 VzC += (-g + 2*Math.PI*AirDensity*Radius*Radius*Radius*(UxC*OmegaYC - UyC*OmegaXC)/Mass)*dt;
373 */
374
375
376 alpha1 = (cylinder.rotation.x - rot1)/(2*Math.PI);
377 alpha2 = (cylinder.rotation.y - rot2)/(2*Math.PI);
378 alpha3 = (cylinder.rotation.z - rot3)/(2*Math.PI);
379
380 rot1 = cylinder.rotation.x;
381 rot2 = cylinder.rotation.y;
382 rot3 = cylinder.rotation.z;
383
384 VxC += (2*AirDensity*Radius*(2*Radius*Height*Math.cos(alpha1) + Math.PI*Radius*Radius*Math.sin(alpha1) )*(UyC*OmegaZC - UzC*OmegaYC)/Mass)*dt;
385 VyC += (2*AirDensity*Radius*(2*Radius*Height*Math.sin(alpha2) + Math.PI*Radius*Radius*Math.cos(alpha2))*(UzC*OmegaXC - UxC*OmegaZC)/Mass )*dt;
386 VzC += (-g + 2*AirDensity*Radius*(2*Radius*Height*Math.cos(alpha3) + Math.PI*Radius*Radius*Math.sin(alpha3))*(UxC*OmegaYC - UyC*OmegaXC)/Mass)*dt;
387
388 cylinder.position.x += VxC*dt;
389 cylinder.position.y += VyC*dt;
390 cylinder.position.z += VzC*dt;
391
392 cylinder.rotation.x += OmegaXC*dt;
393 cylinder.rotation.y += OmegaYC*dt;
394 cylinder.rotation.z += OmegaZC*dt;
395
396
397
398 var trajectoryC = new THREE.Mesh(trajectoryGeometryC, trajectoryMaterialC);
399 trajectoryC.position.x = cylinder.position.x;
400 trajectoryC.position.y = cylinder.position.y;
401 trajectoryC.position.z = cylinder.position.z;
402
403 scene.add( trajectoryC );
404
405 var traC = new THREE.Mesh( traGeometryC, traMaterialC);
406 traC.position.x = cylinder.position.x;
407 traC.position.y = cylinder.position.y;
408 traC.position.z = 0;
409 scene.add(traC);
410
411 document.getElementById("td3").innerHTML = cylinder.position.y ;
412 document.getElementById("td4").innerHTML = cylinder.position.x;
413
414 }
415
416 requestAnimationFrame(renderer2);
417
418 contr.update();
419
420 render.render(scene,camera);
421
422 }
423
424 this.start = renderer;
425 this.start2 = renderer2;
426
427
428
429 }
430 function initStats()
431 {
432 var stats = new Stats();
433 stats.setMode(0);
434 stats.domElement.style.position='absolute';
435 stats.domElement.style.left = '0px';
436 stats.domElement.style.top = '0px';
437 $("#Stats").append(stats.domElement);
438 return stats;
439 }
Обсуждение результатов и выводы[править]
Разработанный алгоритм был реализован в среде программирования Javascript с использование библиотеки Three.js. Была построена траектория движения и произведены эксперименты, результаты которых находятся в таблице ниже:
Шар:
15 | 0 | 5 | 0 | 0 | -10 | 0.45 | 0.11 | 14.585 |
15 | 0 | 5 | 0 | 0 | -10 | 0.41 | 0.11 | 15.945 |
15 | 0 | 5 | 0 | 0 | -10 | 0.45 | 0.01 | 0.011 |
15 | 0 | 5 | 0 | 0 | -5 | 0.45 | 0.11 | 7.399 |
7.5 | 0 | 5 | 0 | 0 | -10 | 0.45 | 0.11 | 7.292 |
Цилиндр:
15 | 0 | 5 | 0 | 0 | -10 | 0.45 | 0.11 | 0.22 | 14.508 |
15 | 0 | 5 | 0 | 0 | -10 | 0.41 | 0.11 | 0.22 | 15.844 |
15 | 0 | 5 | 0 | 0 | -10 | 0.45 | 0.01 | 0.22 | 0.011 |
15 | 0 | 5 | 0 | 0 | -10 | 0.45 | 0.11 | 1 | 13.287 |
15 | 0 | 5 | 0 | 0 | -5 | 0.45 | 0.11 | 0.22 | 7.389 |
7.5 | 0 | 5 | 0 | 0 | -10 | 0.45 | 0.11 | 0.22 | 7.254 |
где
, , - начальные линейные скорости, , , - начальные угловые скорости, - масса объекта, - радиус объекта, - высота цилиндра, а - полученное смещение по оси .Вывод: Исходя из численных данных, полученных после проведения экспериментов, можно сделать вывод, что относительное смещение зависит от угловой скорости, радиуса, массы и силы тяжести, но не зависит от линейной скорости. Например, при уменьшении угловой скорости в 2 раза следует уменьшение относительного отклонения в ~2 раза, а при уменьшении линейной скорости в 2 раза относительное отклонение остается таким же.
Скачать отчет: doc.
Скачать презентацию: pptx.