3D-"Flächenmodelle" in geeigneter Reihenfolge zeichnen

"Flächenmodelle" zeichnen

Verzögerung

Das wesentliche Problem beim Zeichnen eines "3D-Flächenmodells", das mit zwei Arrays definiert wird, wie es auf der Seite "Einfache 3D-Modelle" beschrieben wird, besteht darin, dass sich die Flächen gegenseitig (komplett oder teilweise) überdecken. Dies wird wie folgt gelöst und im Beispiel-Programm "Polyarea 1" realisiert:

Nebenstehend sieht man eine Zeichenfläche, die einen kleinen Teil des oben genannten Beispiel-Programms realisiert, dafür aber zusätzlich die beschriebene Strategie verdeutlicht. Man kann sich nach Klicken auf "Verzögerung einschalten" vorführen lassen, wie dieses "Step-by-step"-Zeichnen des Objekts das Bild aufbaut.

Nachfolgend wird der Algorithmus beschrieben, der im Beispiel-Programm "Polyarea 1" realisiert ist:

      function init () {

         gi = new canvasGI ("canvas") ;            // Ein "CanvasGI-Objekt" wird erzeugt
         gi.setcurrentviewport (0 , 0 , gi.getcanvaswidth() , gi.getcanvasheight () , gi.XYBOTTOMLEFT) ;
         xyz  = cubexyz  ;                         // Beim Start soll der Wuerfel ...
         area = cubearea ;                         // erscheinen

         var limits = gi.ptlimits (xyz) ;          // ermittelt Grenzen der "User coordinates"
         gi.setusercoordsi (limits.xumin , limits.yumin , limits.xumax , limits.yumax , 20) ;

         fillinput () ;                            // ... fuellt die Eingabefelder
         draw () ;                                 // ... zeichnet das Modell
      }

Die nachfolgend gelistete Funktion draw wird weiter unten erklärt:

      function draw () {

         var points = new Array () ;                    // ... fuer die Koordinaten eines Polygons
         gi.clearcanvas ("silver" , "black") ;          // ... fuellt Canvas-Bereich mit Hintergrundfarbe
                                                        //     ("silver") und zeichnet schwarzen Rahmen
         for (var i = 0 ; i < area.length ; i++) {
            var np = area[i].length - 1 ;               // ... weil letztes Element die Farbe ist
            for (var j = 0 ; j < np ; j++) {
               points[j] = xyz[area[i][j]] ;            // ... sammelt Punktkoordinaten eines Polygons
            }
            area[i].unshift (gi.wtsymbdist (points , np)) ;  // ... berechnet symbolischen Abstand vom Betrachter
         }                                              //     und fuegt diesen Wert an der Array-Spitze an

         gi.sortbyindex (area , 0) ;                    // ... sortiert nach den Werten an der Array-Spitze

         for (var i = 0 ; i < area.length ; i++) {
            area[i].shift() ;                           // ... entfernt den Wert an der Array-Spitze wieder
            var np = area[i].length - 1 ;
            for (var j = 0 ; j < np ; j++) {
               points[j] = xyz[area[i][j]] ;            // ... sammelt Punktkoordinaten eines Polygons
            }
            gi.wtdrawfarea (points , np , area[i][np] , "black") ;
         }

         var txt = (gi.getprojectiontype() == gi.PROJ_PARALLEL) ? "Parallelprojektion" : "Zentralprojektion" ;
         gi.vdrawtext (txt , 10 , 10 , "black" , "16pt sans-serif") ;
      }

Beipiel-Programm "Polyarea"

Das Beipiel-Programm "Polyarea" enthält neben den oben beschriebenen Funktionen noch wesentlich mehr Angebote. Es startet mit folgendem Bild:

Weiterlesen