КП: Эффект Магнуса — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
(Обсуждение результатов и выводы)
(Обсуждение результатов и выводы)
 
(не показано 60 промежуточных версий 5 участников)
Строка 10: Строка 10:
 
'''Семестр:''' весна 2015
 
'''Семестр:''' весна 2015
  
[[Файл:Magnus force.svg|thumb|Сила Магнуса|450px]]
+
[[Файл:Magnus force.svg|thumb|Сила Магнуса<ref>[http://en.wikipedia.org/wiki/Magnus_effect Эффект Магнуса]</ref>
 +
|450px]]
  
 
== Аннотация проекта ==
 
== Аннотация проекта ==
  
 +
Данный проект посвящен изучению [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].
  
 
== Формулировка задачи ==
 
== Формулировка задачи ==
Построение и исследование математической модели движения объекта (в нашем случае футбольного мяча), получение уравнения его движения и построение траектории в трехмерном пространстве с учётом различных внешних факторов, влияющих на движение, таких как сила сопротивления воздуха и эффект Магнуса.
+
Построение и исследование математической модели движения объекта (в нашем случае - футбольного мяча и цилиндра), получение уравнения его движения и построение траектории в трехмерном пространстве с учётом различных внешних факторов, влияющих на движение, таких как сила сопротивления воздуха и эффект Магнуса.
  
 
== Общие сведения по теме ==
 
== Общие сведения по теме ==
Эффект Магнуса - образование подъемной силы, действующей на вращающееся тело при обтекании его потоком жидкости или газа. <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>
 
  
[[Файл:g33viT3.gif|thumb|Пример влияния силы Магнуса на траекторию движения мяча|450px]]
+
[[Файл: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%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> , где
Строка 41: Строка 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} = 8πρr^3\vec{u}\times\vec{ω} </math></big> , где
+
<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> - угловая скорость.
  
  
Строка 58: Строка 64:
 
<big><math>
 
<big><math>
 
\begin{cases}
 
\begin{cases}
v_x^{i+1} = v_x^i + (-6πrηv_x^i/m + 8πρr^3(u_y^iω_z - u_z^iω_y)/m)\Delta t  \\
+
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 + 8πρr^3(u_z^iω_w - u_x^iω_z)/m)\Delta t  \\
+
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 + 8πρr^3(u_x^iω_y - u_y^iω_x)/m)\Delta t  \\
+
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>
Строка 73: Строка 79:
  
  
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Shvarev/4.html |width=1000 |height=800 |border=0 }}
+
Реализация алгоритма.
 +
 
 +
Возможности программы:
 +
* поочередный запуск мяча и цилиндра,
 +
* изменение параметров как в начале, так и во время полета,
 +
* просмотр картинки в трехмерном изображении с помощью мыши
 +
* сброс всех данных до начальных при нажатии кнопки "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>
  
 
== Обсуждение результатов и выводы ==
 
== Обсуждение результатов и выводы ==
  
[[Файл:Balltrajectory.png|thumb|Пример траектории мяча|450px]]
+
[[Файл:Balltrajectory2.png|thumb|Пример траектории мяча|450px]]
  
 +
Разработанный алгоритм был реализован в среде программирования Javascript с использование библиотеки Three.js. Была построена траектория движения и произведены эксперименты, результаты которых находятся в таблице ниже:
  
 +
Шар:
  
 
{| border="1"
 
{| border="1"
Строка 89: Строка 556:
 
  |<math>ω_y</math>
 
  |<math>ω_y</math>
 
  |<math>ω_z</math>
 
  |<math>ω_z</math>
 +
|<math>m</math>
 +
|<math>r</math>
 
  |<math>Δ_y</math>
 
  |<math>Δ_y</math>
 +
|-
 +
|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
 +
|}
 +
 +
Цилиндр:
 +
 +
{| border="1"
 +
|-
 +
|<math>V_x</math>
 +
|<math>V_y</math>
 +
|<math>V_z</math>
 
  |<math>ω_x</math>
 
  |<math>ω_x</math>
 
  |<math>ω_y</math>
 
  |<math>ω_y</math>
 
  |<math>ω_z</math>
 
  |<math>ω_z</math>
  |<math>Δ_y</math>
+
  |<math>m</math>
  |<math>ω_x</math>
+
  |<math>r</math>
  |<math>ω_y</math>
+
  |<math>h</math>
|<math>ω_z</math>
 
|<math>Δ_y</math>
 
|<math>ω_x</math>
 
|<math>ω_y</math>
 
|<math>ω_z</math>
 
 
  |<math>Δ_y</math>
 
  |<math>Δ_y</math>
 
  |-
 
  |-
 +
|15
 +
|0
 
  |5
 
  |5
 
  |0
 
  |0
|5
 
 
  |0
 
  |0
 +
| -10
 +
|0.45
 +
|0.11
 +
|0.22
 +
|14.508
 +
|-
 +
|15
 
  |0
 
  |0
|-5
 
|2.4644
 
 
  |5
 
  |5
 
  |0
 
  |0
|-5
 
|3.2022
 
 
  |0
 
  |0
 +
| -10
 +
|0.41
 +
|0.11
 +
|0.22
 +
|15.844
 +
|-
 +
|15
 
  |0
 
  |0
|-10
 
|4.8584
 
 
  |5
 
  |5
 
  |0
 
  |0
  |-10
+
|0
  |5.4070
+
  | -10
 +
  |0.45
 +
|0.01
 +
|0.22
 +
|0.011
 
  |-
 
  |-
  |10
+
  |15
 
  |0
 
  |0
 
  |5
 
  |5
 
  |0
 
  |0
 
  |0
 
  |0
  |-5
+
  | -10
  |4.9289
+
  |0.45
 +
|0.11
 +
|1
 +
|13.287
 +
|-
 +
|15
 +
|0
 
  |5
 
  |5
 
  |0
 
  |0
|-5
 
|5.4903
 
 
  |0
 
  |0
 +
| -5
 +
|0.45
 +
|0.11
 +
|0.22
 +
|7.389
 +
|-
 +
|7.5
 
  |0
 
  |0
|-10
 
|9.9168
 
 
  |5
 
  |5
 
  |0
 
  |0
  |-10
+
|0
  |9.6552
+
  | -10
 +
  |0.45
 +
|0.11
 +
|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>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

Сила Магнуса[1]

Аннотация проекта[править]

Данный проект посвящен изучению эффекта Магнуса, возникающего в различных видах спорта, а также использующегося в баллистике, летательных аппаратах и кораблях.В ходе работы над проектом были рассмотрены траектории полета мяча и цилиндра в зависимости от различных начальных параметров (радиуса, динамической вязкости среды, плотности воздуха, линейной и угловой скорости). Программа написана на языке JavaScript с использование библиотеки Three.js.

Формулировка задачи[править]

Построение и исследование математической модели движения объекта (в нашем случае - футбольного мяча и цилиндра), получение уравнения его движения и построение траектории в трехмерном пространстве с учётом различных внешних факторов, влияющих на движение, таких как сила сопротивления воздуха и эффект Магнуса.

Общие сведения по теме[править]

Пример влияния силы Магнуса на траекторию движения мяча[1]

Эффект Магнуса - образование подъемной силы, действующей на вращающееся тело при обтекании его потоком жидкости или газа, широко использующейся в спорте, баллистике, летательных аппаратах и кораблях. [2]

Данный эффект возникает в результате разности давлений (в соответствии с законом Бернулли[3]) на стенках объекта из-за разных скоростей движения воздуха. Возникающий дисбаланс заставляет объект отклоняться.

Решение[править]

Силу сопротивления воздуха для мяча будем считать с помощью закона Стокса[4]:

[math]\vec{F} = -6πrη\vec{v} [/math] , где

[math]\vec{F}[/math] - сила Стокса,

[math]r[/math] - радиус мяча,

[math]η[/math] - динамическая вязкость среды,

[math]\vec{v}[/math] - скорость мяча.


Силу Магнуса примем вида[5]:

[math]\vec{F} = 2Sρr\vec{u}\times\vec{ω} [/math] , где

[math]\vec{F}[/math] - сила Магнуса,

[math]S[/math] - площадь действия силы,

[math]ρ[/math] - плотность воздуха,

[math]r[/math] - радиус,

[math]\vec{u}[/math] - относительная скорость,

[math]\vec{ω}[/math] - угловая скорость.


Применив метод Эйлера, получим формулы для нахождения скорости и координаты мяча:

[math] \begin{cases} 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 + 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 + 2Sρr(u_x^iω_y - u_y^iω_x)/m)\Delta t \\ \end{cases} [/math]

[math] \begin{cases} x^{i+1} = x^i + v_x^i\Delta t \\ y^{i+1} = y^i + v_y^i\Delta t \\ z^{i+1} = z^i + v_z^i\Delta t \\ \end{cases} [/math]


Реализация алгоритма.

Возможности программы:

  • поочередный запуск мяча и цилиндра,
  • изменение параметров как в начале, так и во время полета,
  • просмотр картинки в трехмерном изображении с помощью мыши
  • сброс всех данных до начальных при нажатии кнопки "Reload"


Текст программы на языке JavaScript:

Файл "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. Была построена траектория движения и произведены эксперименты, результаты которых находятся в таблице ниже:

Шар:

[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]Δ_y[/math]
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

Цилиндр:

[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 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

где [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 раза относительное отклонение остается таким же.



Скачать отчет: doc.
Скачать презентацию: pptx.

Ссылки по теме[править]

См. также[править]