Beispiel: Viewports, "User coordinates", Marker

Aufgabe

Der Steg eines Planetengetriebes dreht sich mit der konstanten Winkelgeschwindigkeit ωS und treibt ein Planetenrad, das auf dem feststehenden Sonnenrad abrollt.

Gegeben:  R = 15 cm ;  r = 10 cm ;  a = 20 cm ;  ωS = 2 s−1 .

Zum Zeitpunkt t = 0 befindet sich das Planetenrad in der skizzierten horizontalen Lage. Die Bewegung des Punktes A im Abstand a vom Mittelpunkt des Planetenrades soll analysiert werden:

Die nebenstehend zu sehende Animation soll eine Vorstellung der zu untersuchenden Bewegung geben. Sie wird auch mit CanvasGI-Funktionen erzeugt. Dies sind allerdings nicht die hier vorzustellenden Funktionen, hier geht es nur um die für die oben formulierte Aufgabenstellung erforderlichen Funktionen.

Problemanalyse

Die Bewegung eines Planetenrades wird auf der Seite "Kinematik des Punktes, Beispiel: Punkt auf Planetenrad" ausführlich behandelt. Für die Bahnkurve des Punktes A findet man dort die in Parameterdarstellung formulierte Funktion:

Dort findet man auch die Formeln für die Geschwindigkeits-Zeit-Funktion und die Beschleunigungs-Zeit-Funktion:

Strategie für die Darstellung der Funktionen

Für die Darstellung der Bahnkurve müssen die beiden Koordinatenrichtung isotrop skaliert werden, für die Funktionen v(t) und a(t) ist dies weder erforderlich noch sinnvoll, weil auf den beiden Achsen Größen unterschiedlicher Dimension aufzutragen sind.

Das Beispiel-Programm "Planetenrad" teilt die Zeichenfläche in drei Viewports und definiert für jeden Viewport geeignete "User coordinates". Die Beschreibung der verwendeten Funktionen wird dadurch verständlicher, dass nebenstehend eine verkleinerte Version der Zeichenfläche zu sehen ist, die mit dem Beispiel-Programm erzeugt wird.

Im Body-Teil der HTML-Datei wird der Canvas-Bereich mit der id="canvas" erzeugt, die Zeichenaktion wird gestartet durch eine Anweisung im Body-Tag:

<body onLoad="init();">

In der JavaScript-Funktion init wird das cavasGI-Objekt erzeugt und einer global vereinbarten Variablen gi zugewiesen, damit es in allen anderen Funktionen verfügbar ist:

      function init() {
         gi = new canvasGI ("canvas") ;              // ... definiert ein canvasGI-Objekt
         draw () ;
      }

Im zweiten Schritt startet init die Funktion draw (die farbig gekennzeichneten Bereiche werden weiter unten erläutert):

      function draw() {

         canwidth  = gi.getcanvaswidth  () ;
         canheight = gi.getcanvasheight () ;
         gi.clearcanvas ("silver") ;

         trace    () ;                            // ... zeichnet den linken Viewport
         velocity () ;                            // ... zeichnet Viewport rechts oben
         accel    () ;                            // ... zeichnet Viewport rechts unten
       }
      function trace() {

         gi.setcurrentviewport (0 , 0 , canwidth/2 , canheight , gi.XYTOPLEFT) ;
         gi.vdrawrect (2 , 2 , canwidth/2 - 4 , canheight - 4 , "black") ;  // ... zeichnet Rahmen
         var xymax = 60 ;
         gi.setusercoordsi (-xymax , -xymax , xymax , xymax , 15) ;         // ... fuer Viewport links

         gi.udrawxaxis (25 , 2 , 2 , 10 , 10 , "x" , "black" , "black") ;
         gi.udrawyaxis (25 , 2 , 2 , 10 , 10 , "y" , "black" , "black") ;

         gi.beginpath () ;                         // ... startet "Path" fuer Bahnkurve
         gi.umoveto (R+r+a , 0) ;                  // Startpunkt fuer Bahnkurve 
         for (var t = 0.01 ; t <= tend ; t += 0.01) {
            gi.ulineto ((R+r)*Math.cos(omS*t) + a*Math.cos(Rdrp1*omS*t) ,
                                    (R+r)*Math.sin(omS*t) + a*Math.sin(Rdrp1*omS*t)) ;
         }
         gi.strokestyle ("red") ;
         gi.stroke () ;                            // ... zeichnet die Bahnkurve
      }

Der Viewport oben rechts wird von der Funktion velocity gefüllt:

      function velocity() {

         gi.setcurrentviewport (canwidth/2 , 0 , canwidth/2 , canheight/2 , gi.XYTOPLEFT) ;
         gi.vdrawrect (2 , 2 , canwidth/2 - 4 , canheight/2 - 4 , "black") ;  // ... zeichnet Rahmen

         var vmin = 0 , vmax = 200 , tanf = 0 ;
         gi.setusercoordsa (tanf , vmin , tend , vmax , 20) ;

         gi.udrawxaxis  ( 2 , 0 , 3 , 0.2 , 0.2 , "t" , "black" , "black") ;
         gi.udrawyaxis  (50 , 0 , 3 , 10  , 20  , "v" , "black" , "black") ;

         gi.beginpath () ;                         // ... startet "Path" fuer Viewport rechts oben
         gi.uraster ( 2 , 0 , 3 , 50  , 0   , 3)   ;
         gi.umoveto (0 , (R+r)*omS*Math.sqrt(1+adr*adr+2*adr)) ;                  // Startpunkt fuer v(t) bei t=0
         for (var t = 0.01 ; t <= tend ; t += 0.01) {
            gi.ulineto (t , (R+r)*omS*Math.sqrt(1+adr*adr+2*adr*Math.cos(R/r*omS*t))) ;
         }
         gi.stroke () ;                            // ... zeichnet Viewport rechts oben
      }

Der Viewport unten rechts mit der Beschleunigung-Zeit-Funktion wird exakt mit der gleichen Strategie gefüllt wie der Viewport oben rechts. Dies wird deshalb hier nicht gesondert erläutert. Das komplette Beispiel-Programm "Viewports, User coordinates, Marker" kann in einem separaten Browser-Fenster gestartet werden.

Weiterlesen

Folgende Seiten werden als Einführung in die Benutzung des CanvasGI empfohlen: