2016-04-05 10 views
0

Ich arbeite an einem interaktiven Solarsystem Leinwand mit HTML5 Leinwand. Ich möchte die Planeten an bestimmten Koordinaten auf der Leinwand positionieren können, wenn die Seite geladen wurde. Im Moment habe ich sie alle auf einer horizontalen Linie aufgereiht, also weiß ich, wie weit ihre jeweiligen Abstände voneinander entfernt sind. Wie Sie in dem kleinen Bild sehen können.Positionierung auf Leinwand mit dynamischen Koordinaten

enter image description here

Aber hier ist mein Problem, weil die x- und y-Koordinaten immer auf der Funktion basiert zu ändern, die sie drehen macht, habe ich keine Ahnung, wie genau die Planeten auf der Leinwand zu positionieren, so dass sie von zu verbreiten sind einander und nichts wie, wie sie auf dem Bild sind, während sie immer noch so positioniert sind, dass sie nicht in direktem Kontakt miteinander kommen, wenn sie sich drehen. Ich denke, ein bisschen Mathe ist hier involviert.

Auch: Ich realisiere verschiedene Animationsintervalle sind wahrscheinlich ein Workaround dafür, aber ich habe Probleme damit. Wenn ich neue Animationsfunktionen für jeden Planeten erstelle, sind die Planetenzeichnungen nirgends so glatt wie eine Animation. Mir ist klar, dass dies eine eigenständige Frage ist!

Hier ist der größte Teil der entsprechenden Code:

function initCanvas(){ 
var ctx = document.getElementById('my_canvas').getContext('2d'); 
var dynamicSunW = 25; 
var dynamicSunH = 0; 
var dynamicSunX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5); //dynamicSun is always at dead center of canvas 
var dynamicSunY = (ctx.canvas.height * .5) - (dynamicSunH * .5); 
var angleOfSun = 0; 


var posMercuryX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50; 
var posMercuryY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 20; 
var gravityMercury = {x: posMercuryX, y: posMercuryY }; 
var posVenusX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50; 
var posVenusY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 46; 
var gravityVenus = {x: posVenusX, y: posVenusY }; 
var posEarthX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50; 
var posEarthY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 80; 
var gravityEarth = {x: posEarthX, y: posEarthY}; 
var posMarsX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50; 
var posMarsY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 116; 
var gravityMars = {x: posMarsX, y: posMarsY }; 
var posJupiterX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50; 
var posJupiterY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 157; 
var gravityJupiter = {x: posJupiterX, y: posJupiterY }; 
var posSaturnX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50; 
var posSaturnY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 208; 
var gravitySaturn = {x: posSaturnX, y: posSaturnY }; 
var posUranusX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50; 
var posUranusY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 250; 
var gravityUranus = {x: posUranusX, y: posUranusY }; 
var posNeptuneX = (ctx.canvas.width * .5) - (Math.PI* 1 * .5) - 50; 
var posNeptuneY = (ctx.canvas.height * .5) - (dynamicSunH * .5) + 283.9; 
var gravityNeptune = {x: posNeptuneX, y: posNeptuneY }; 




    function rotate_point(pointX, pointY, originX, originY, ang) { 
      ang = Math.PI/180.0; 
      return { 
       x: Math.cos(ang) * (pointX-originX) - Math.sin(ang) * (pointY-originY) + originX, 
       y: Math.sin(ang) * (pointX-originX) + Math.cos(ang) * (pointY-originY) + originY 
      }; 
     } 

     var Solarsystem = { 
      Neptune: { 
       render: function(){ 
        ctx.beginPath(); 
        gravityNeptune = rotate_point(gravityNeptune.x, gravityNeptune.y, dynamicSunX, dynamicSunY, angleOfSun) 
        ctx.arc(gravityNeptune.x,gravityNeptune.y ,10, 0, 2*Math.PI, true); 
        ctx.fillStyle = "darkblue"; 
        ctx.closePath(); 
        ctx.fill(); 

       } 
      } 
      , Uranus: { 
       render: function(){ 
        ctx.beginPath(); 
        gravityUranus = rotate_point(gravityUranus.x, gravityUranus.y, dynamicSunX, dynamicSunY, angleOfSun) 
        ctx.arc(gravityUranus.x,gravityUranus.y ,6, 0, 2*Math.PI, true); 
        ctx.fillStyle = "rgb(64,224,208)"; 
        ctx.closePath(); 
        ctx.fill(); 
       } 
      } 
      , Saturn: { 
       render: function(){ 
        ctx.beginPath(); 
        gravitySaturn = rotate_point(gravitySaturn.x, gravitySaturn.y, dynamicSunX, dynamicSunY, angleOfSun) 
        ctx.arc(gravitySaturn.x,gravitySaturn.y ,15, 0, 2*Math.PI, true); 
        ctx.fillStyle = "rgb(186,85,211)"; 
        ctx.closePath(); 
        ctx.fill(); 

       } 
      } 
      , Jupiter: { 
       render: function(){ 
        ctx.beginPath(); 
        gravityJupiter = rotate_point(gravityJupiter.x, gravityJupiter.y, dynamicSunX, dynamicSunY, angleOfSun) 
        ctx.arc(gravityJupiter.x,gravityJupiter.y ,18, 0, 2*Math.PI, true); 
        ctx.fillStyle = "rgb(255,255,153)"; 
        ctx.closePath(); 
        ctx.fill(); 


        } 
      } 
      , Mars: { 
       render: function(){ 
        ctx.beginPath(); 
        gravityMars = rotate_point(gravityMars.x, gravityMars.y, dynamicSunX, dynamicSunY, angleOfSun) 
        ctx.arc(gravityMars.x,gravityMars.y ,7, 0, 2*Math.PI, true); 
        ctx.fillStyle = "rgb(255,99,71)"; 
        ctx.closePath(); 
        ctx.fill(); 

       } 
      } 
      , Earth: { 
       render: function(){ 
        ctx.beginPath(); 
        gravityEarth = rotate_point(gravityEarth.x, gravityEarth.y, dynamicSunX, dynamicSunY, angleOfSun) 
        ctx.arc(gravityEarth.x,gravityEarth.y ,8, 0, 2*Math.PI); 
        ctx.fillStyle = "rgba(30,144,255,1)"; 
        ctx.closePath(); 
        ctx.fill(); 

       } 
      } 
      , Venus: { 
       render: function(){ 
        ctx.beginPath(); 
        gravityVenus = rotate_point(gravityVenus.x, gravityVenus.y, dynamicSunX, dynamicSunY, angleOfSun) 
        ctx.arc(gravityVenus.x,gravityVenus.y ,7, 0, 2*Math.PI); 
        ctx.fillStyle = "rgba(255,165,0,1)"; 
        ctx.closePath(); 
        ctx.fill(); 
       } 
      } 
      , Mercury: { 
       render: function(){ 
       ctx.beginPath(); 
       gravityMercury = rotate_point(gravityMercury.x, gravityMercury.y, dynamicSunX, dynamicSunY, angleOfSun) 
       ctx.arc(gravityMercury.x,gravityMercury.y ,5, 0, 2*Math.PI); 
       ctx.fillStyle = "rgba(119,136,153,1)"; 
       ctx.closePath(); 
       ctx.fill(); 
       ctx.stroke(); 
       } 
      } 
      , Sun: { 
      render: function(){ 
      ctx.fillStyle = "rgba(255,255,51,1)"; 
      ctx.save(); //store ctx so it can be later reused 
      ctx.shadowColor = 'yellow'; 
      ctx.shadowBlur = 70; 
      ctx.shadowOffsetX = 0; 
      ctx.shadowOffsetY = 0; 
      ctx.beginPath(); 
      ctx.arc(dynamicSunX, dynamicSunY, dynamicSunW, dynamicSunH, Math.PI*2, true); 
      ctx.closePath(); 
      ctx.fill(); 
      ctx.restore(); //ctx at time of save 
       } 
      } 
     } 




    var bg = new Image(); 
    bg.src = "spacedef.png"; 
      function Background(){ 
      this.x = 0, this.y = 0, this.w = bg.width, this.h = bg.height; 
      this.render = function(){ 
       ctx.drawImage(bg, this.x--, 0); 
       if(this.x <= -499){ 
        this.x = 0; 
       } 
      } 
     } 

     var background = new Background(); 

     function animate(){ 
      background.render(); 
      Solarsystem.Neptune.render(); 
      Solarsystem.Uranus.render(); 
      Solarsystem.Saturn.render(); 
      Solarsystem.Jupiter.render(); 
      Solarsystem.Mars.render(); 
      Solarsystem.Earth.render(); 
      Solarsystem.Venus.render(); 
      Solarsystem.Mercury.render(); 
      Solarsystem.Sun.render(); 
     } 
     var animateInterval = setInterval(animate, 1000/60); 

    } 

Antwort

1

Intead Drehpunkten, die relativ zueinander sind, drehen Sie vielleicht alle Planeten um die Sonne Jeder Planet würde seinen eigenen Radius von der Sonne haben so Ihre mathematischen dazu (für eine Kreisbahn) reduziert:

var neptune.x=sun.x+neptune.radius*Math.cos(radianAngle); 
var neptune.y=sun.y+neptune.radius*Math.sin(radianAngle); 

Natürlich sind die Planeten Bahnen sind eigentlich eher elliptisch als kreisförmig. Sie können Punkte auf einer Ellipse wie folgt berechnen:

// Calc points on Ellipse 
function getPointsOnEllipse(cx,cy,a,b){ 
    var startAngle=-PI/2; 
    var lastX=cx-(a*Math.cos(startAngle)); 
    var lastY=cy+(b*Math.sin(startAngle)); 
    var points=[]; 
    // change 1000 to your desired count of waypoints along the ellipse 
    for(var i=0;i<1000;i++){ 
     var angle=startAngle+PI2/1000*i; 
     var x=cx-(a*Math.cos(angle)); 
     var y=cy+(b*Math.sin(angle)); 
     var dx=x-lastX; 
     var dy=y-lastY; 
     var length=parseInt(Math.sqrt(dx*dx+dy*dy)); 
     var eAngle=(Math.atan2(dy,dx)+PI2)%PI2; 
     if(length>0){ 
      points.push({x:x,y:y,angle:eAngle}); 
      lastX=x; 
      lastY=y; 
     } 
    } 
    return(points); 
} 
+1

Das ist ein gutes Stück Code, vielen Dank dafür. Ich weiß, dass sie elliptisch rotieren, ich dachte, es wäre ein echter Kopfzerbrecher, um den Code zu entwickeln, den ich dafür brauche. So danke! – Zhyohzhy