Projekt: Mathematische Funktionen mit Canvas Grafik und Devicekontext


Zu diesem Projekt gehören Teile von Mathematik, wie das Darstellen von parametrisierten Kurven, Ortskurven, grafische Darstellungen und dem Canvas-Device-Kontext. In diesem Zusammenhang stehen auch Gebiete, wie z.B. Lineare Regression , Methode der kleinsten Fehler-Quadrate , Curve fitting, Regressionsanalyse ( allgemein ), Statistik und Regressionsanalyse ( grafische Darstellung der Regressionsanalyse, Statistik ) und Data-Driven Documents ( D3 ).
Zu diesem Projekt gehören Grundkenntnisse der Computergrafik, die grafische Web-Präsentation von (Statistik-) Daten, Canvas2d-Web-Grafik mit DC und mehr.


Grafik-Grundkenntnisse auffrischen ... Weblinks OpenGL, WebGL, SVG, Canvas

Ein Wissen um die Bedienung von Grafik-Programmen ist für eine erfolgreiche Toolchen-Entwicklung, der Erstellung einer "self-made" Canvas-Bibliothek wohl nicht hinreichend, wenn Events bei Grafische Elementen und mauszentrierte Applikationsentwicklungen benötigt werden. "Plagiate sind out".

Seit den Anfängen der elektronischen Datenverarbeitung gibt es zahlreiche, kommerzielle, umfangreiche Grafik-Programme, siehe z.B. de.wikipedia Grafiksoftware.


Grafischer Device-Context DC und Canvas

Wird in der Veranstaltung behandelt.

Neu: canvas.toDataURL() ctx.setTransform() ?ctx.getTransform() ?ctx.resetTransform() meint ctx.setTransform(1,0,0,1,0,0) var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var a = 0.866, c =-0.500, e = 0, b = 0.500, d = 0.866, f = 0; ctx.setTransform(a,b, c,d, e,f); ctx.fillRect(0, 0, 100, 100);

Gesichtspunkte für die zu entwickelnde App sind Einfachheit, Robustheit, prägnant Klarheit, Paxisnähe. Die eigenen App-Ideen ( mit Alleinstellungsmerkmal ) können z.B. hin gerichtet sein auf

Beispiele für dieses App-Projekt sind z.B. 2 1/2 D Präsentationsgrafiken, Mediengestaltungen, Balkendiagramme, Tortendiagramme, Geo-Algebra, geometrische Formen ( de.wikipedia: Dreieck , Sierpinski-Dreieck , mathworld: Perfektes Rechteck , usw. ), 3D digitales Geländemodelle siehe de.wikipedia Polygonfläche und Schwerpunkt ( Gauß-Ellington ), usw.


Canvas ( Funktionsnamen ) Weblinks

HTML5 ermöglicht die eingebettete Verwendung von Canvas-Tags, die als Grafik-Flächen dienen. Eine "elektronische Zeichenfläche" wird engl. auch Canvas ( Leinwand, Gewebe ) genannt. Die Canvas-Unterstützung erfordert ECMAScript. Canvas bietet eine infache "nativ"-Schnittstelle.

Obwohl Canvas2DContext leichtgewichtig gegnüber WebGL, OpenGL, Silverlight ist, so gibt es doch nützliche Funktionen und Properties, wie z.B. ctx.translate(), ctx.translate(), ctx.scale(), ctx.createLinearGradient(), ctx.createRadialGradient() und shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor . Es gibt:

Canvas2DContext hat u.a. Funktionen für 
'arc','arcTo','beginPath','bezierCurveTo','clearRect','clip',  
'closePath','drawImage','fill','fillRect','fillText','lineTo','moveTo',  
'quadraticCurveTo','rect','restore','rotate','save','scale','setTransform',  
'stroke','strokeRect','strokeText','transform','translate'
Properties, wie z.B.
'canvas','fillStyle','font','globalAlpha','globalCompositeOperation',  
'lineCap','lineJoin','lineWidth','miterLimit',
'shadowOffsetX','shadowOffsetY', 'shadowBlur','shadowColor',
'strokeStyle','textAlign','textBaseline'

Einige Canvas-Weblinks:

whatwg  
the-canvas-element

whatwg  
beginPath()

en.wikipedia 
Canvas_element

de.wikipedia Canvas-HTML-Element,
whatwg.org the-canvas-element 2012,
simon Canva-Referenz-Karte, alles auf einen Blick
w3schools Canvas-Referenz, alles auf einen Blick
w3schools Canvas, Einführung
html5canvastutorials HTML5 Canvas-Tutorial,
opera  html-5-canvas-the-basics ,
opera  html-5-canvas-painting ,
mozilla  Canvas tutorial ,
mozilla DOM/EventTarget.addEventListener ,
apple Safari HTML5 Canvas Guide 

Die Canvas-Browser-Unterstützung zeigt en.wikipedia: en.wikipedia: Comparison_of_layout_engines_&HTML5_Canvas

Canvas Kontext ( ctx und ctx.canvas ) default build-in

Was enthält der Canvas-Kontext ctx? Etwa ...

canvas:[object HTMLCanvasElement]      fillStyle:#000000
font:10px sans-serif                   globalAlpha:1
globalCompositeOperation:source-over   lineCap:butt
lineJoin:miter                         lineWidth:1
miterLimit:10                          shadowBlur:0
shadowColor:rgba(0, 0, 0, 0.0)         shadowOffsetX:0
shadowOffsetY:0                        strokeStyle:#000000
textAlign:start                        textBaseline:alphabetic

Was enthält das HTMLCanvasElement ctx.canvas? Etwa ...

ctx=accessKey:                       all:[object HTMLCollection]
attributes:[object NamedNodeMap]     baseURI: ...dat.htm
childElementCount:0                  childNodes:[object NodeList]
children:[object HTMLCollection]     classList:
className:                           clientHeight:220
clientLeft:6                         clientTop:6
clientWidth:320                      contentEditable:inherit
currentPage:0                        currentStyle:[object CSSStyleDeclaration]
dataset:[object DOMStringMap]        dir:
draggable:false                      dropzone:
firstChild:[object Text]             firstElementChild:null
height:200                           hidden:false
id:POLYGON_FLAECHE                   innerHTML:Browser kann kein Canvas
innerText:Browser kann kein Canvas   isContentEditable:false
itemId:                              itemProp:
itemRef:                             itemScope:false
itemType:                            itemValue:null
lang:                                lastChild:[object Text]
lastElementChild:null                localName:canvas
namespaceURI:http://www.w3.org/1999/xhtml 
nextElementSibling:[object HTMLScriptElement]
nextSibling:[object Text]            nodeName:CANVAS
nodeType:1                           nodeValue:null
offsetHeight:232                     offsetLeft:14
offsetParent:[object HTMLBodyElement] offsetTop:2535
offsetWidth:332
outerHTML:<canvas id="MYID" width="300" height="200" style="...">Browser braucht Canvas</canvas>
outerText:Browser kann kein Canvas   ownerDocument:[object HTMLDocument]
pageCount:1                          parentElement:[object HTMLElement]
parentNode:[object HTMLElement]      prefix:null
previousElementSibling:[object HTMLParagraphElement]
previousSibling:[object Text]        properties:[object HTMLPropertiesCollection]
scrollHeight:232                     scrollLeft:0
scrollTop:0                          scrollWidth:332
spellcheck:true                      style:[object CSSStyleDeclaration]
tabIndex:-1                          tagName:CANVAS
textContent:Browser kann kein Canvas title:
unselectable:      width:300         onscroll:null          onfocusin:null
onfocusout:null    onclick:null      onmousedown:null       onmouseup:null
onmouseover:null   onmouseenter:null onmousemove:null       onmouseout:null
onmouseleave:null  onmousewheel:null onkeypress:null        onkeydown:null
onkeyup:null       onload:null       onunload:null          onabort:null
onerror:null       onfocus:null      onblur:null            ondblclick:null
oncontextmenu:null oninvalid:null    onloadstart:null       onprogress:null
onsuspend:null     onstalled:null    onloadend:null         ontimeout:null
onemptied:null     onplay:null       onpause:null           onloadedmetadata:null
onloadeddata:null  onwaiting:null    onplaying:null         onseeking:null
onseeked:null      ontimeupdate:null onended:null           oncanplay:null
oncanplaythrough:null                onratechange:null      ondurationchange:null
onvolumechange:null                  oncuechange:null       onfullscreenerror:null
onfullscreenchange:null              onpagechange:null      ondragstart:null
ondrag:null                          ondragenter:null       ondragleave:null
ondragover:null                      ondrop:null            ondragend:null
oncopy:null                          oncut:null             onpaste:null
ontextinput:null

Canvas und cnv.dataset Store Daten in Canvas-Tag

Wie können zahlreiche Parameter im Canvas-Tag gespeichert werden? Die Speicherung von numerischen Werten erfolgt als String. Beispiel: Die Objekt-Properties von var o = {id:"ID_CANVAS" mod:"isotrop", xmin:0, ymin:0, xmax:300, ymax:300, ... } werden als Strings cnv.dataset.myParameters in "ID_CANVAS" hinterlegt.


function get_cnv(id) { return document.getElemenById(id).getContext('2d'); }

function set_cnv_data(o) { var i, k, keys = Object.keys(o), cnv = get_cnv(o.id);
   if (!o.imin) { cnv.dataset.imin = 0; }
   if (!o.imax) { cnv.dataset.imax = cnv.width; }
   if (!o.jmin) { cnv.dataset.jmin = cnv.height; }
   if (!o.jmax) { cnv.dataset.jmax = 0; }
   for (i = 0; i < keys.length; i += 1) { k = keys[i]; cnv.dataset[k] = o[k]; }
 }

// global: 
var MY_CANVAS_NUM_KEYS = ["imin", "imax", "jmin", "jmax", "xmin", "xmax", "ymin", "ymax", "xTi", "xSi", "yTj", "ySj", "xMou", "yMou"]; 

function get_cnv_data(id) { var i, k, r = Object.create(null), 
 cnv = get_cnv(id), keys = Object.keys( cnv.dataset ); // keys.length === MY_CANVAS_NUM_KEYS.length ?

 for (i = 0; i < MY_CANVAS_NUM_KEYS.length; i += 1) { 
   k = MY_CANVAS_NUM_KEYS[i];  
   r[k] = parseFloat(cnv.dataset[k]); 
 } return Object.create(r);
 }

Grafik: Welt-Viewport-Abbildung Pflicht!

Hinweise in der Veranstaltung.

// Prinzip geg.:  xMax, xMin, yMax, yMin, CTX, w, h;
var w = CTX.canvas.width, h = CTX.canvas.height;
dx = xMax - xMin;  
dy = yMax - yMin;
für alle Punkte (x,y) berechne (i,j) {
i = (x - o.xMin)·w/dx;
j = (y - o.yMin)·h/dy;
// x = xmin + i·dx/w; falls i,j von Maus, ges. Weltpunkt x,y
// y = ymin + j·dy/h; 
}

Zu den 2D-Weltkoordinaten (x,y) gehören die Bereiche xMin <= x <=; xMax und yMin <= y <= yMax Reine grafische Transformationen ( Matrizen ) scheiden aus, weil in der 2D-Welt i.a. Berechnungen, wie z.B. tatsächliche Polygon-Fläche, erforderlich sind.

Welt-Viewport-Abbildung, isotrop / anisotrop, (x,y) --> (i,j)
Achtung! Anstelle des yMax-Wertes ist yMin zu verwenden und Anstelle des yMiny-Wertes ist yMax zu verwenden.

           Welt-Ebene 
    y-Achse
     | 
yMax | . . . . . . . . . . . . . . . . . 
     |                                .       
     |                                .
     |      yMin <= y <= yMax          . 
     |                                .
     |      xMin <= x <= xMax          .
     |                                .
     |                                .
yMin |----------------------------------|---  x-Achse 
   xMin                              xMax

Beispiel: Zu y = sin(x) gehört

    *xMin_yMin_xMax_yMax: -10 10 -2 2 anisotop

Eine Welt-Viewport-Abbildung macht aus (x, y) ein (i, j). Zu einer Welt gehört "isotrop" bzw. "anisotrop".

    *iMin_jMin_iMax_jMax: 0 0 600 400 

Zu den 2D-Gerätekoordinaten (i, j) gehören die Bereiche iMin <= i <= iMax und jMin <= j <= jMax

           Geräte-Ebene ( Canvas) 

      iMin=0                 iMax = cxt.canvas.width;  
jMin=0 |-------------------------|------- i-Achse 
       |    jMin <= j <= jMax    .                
       |                        .
       |    iMin <= i <= iMax    .
       |                        .
  jMax |  . . . . . . . . . . .. .  jMax = cxt.canvas.height;
       |                             
       |                             
      j-Achse

Welt-Viewport-Abbildung, isotrop / anisotrop, (x,y) --> (i,j)
Achtung! Sind y-Richtung und j-Richtung entgegengesetzt, so ist anstelle des yMax-Wertes yMin zu verwenden und anstelle des yMin-Wertes ist yMax zu verwenden.

// Prinzip geg.:  xMax, xMin, yMax, yMin, CTX, w, h;
var w = CTX.canvas.width, h = CTX.canvas.height;
dx = xMax - xMin;  
dy = yMax - yMin;
für alle Punkte (x,y) berechne (i,j) {
i = (x - o.xMin)·w/dx;
j = (y - o.yMin)·h/dy;
// x = xmin + i·dx/w; falls i,j von Maus, ges. Weltpunkt x,y
// y = ymin + j·dy/h; 
}

Welche Mathematik verbirgt sich in den grundlegenden 2D-Transformation? Transform-Matrix ( Hinweis: Alles ohne Gewähr! )

  ⎡  d  -c  c·f - d·e ⎤   ⎡ a  c  e ⎤     ⎡ 1  0  0 ⎤
  ⎢ -b   a  b·e - a·f ⎥   ⎢ b  d  f ⎥   - ⎢ 0  1  0 ⎥ · (a·d-b·c)
  ⎣  0   0  a·d - b·c ⎦   ⎣ 0  0  1 ⎦     ⎣ 0  0  1 ⎦  


 ⎡ i ⎤     ⎡  a   c  e ⎤   ⎡ x ⎤
 ⎢ j ⎥  =  ⎢  b   d  f ⎥ · ⎢ y ⎥
 ⎣ 1 ⎦     ⎣  0   0  1 ⎦   ⎣ 1 ⎦ 

 ⎡ x ⎤            -1  ⎡  d  -c   c·f-d·e ⎤   ⎡ i ⎤
 ⎢ y ⎥  = (a·d-b·c)    ⎢ -b   a   b·e-a·f ⎥ · ⎢ j ⎥
 ⎣ 1 ⎦                ⎣  0   0   a·d-b·c ⎦   ⎣ 1 ⎦ 

 Initialisierung: Koeffizenten  a = 1, d = 1 sonst 0

 i = x ·(imax-imin)/(xmax-xmin) + (imin·xmax-imax·xmin)/(xmax-xmin)
                          
 j = y ·(jmax-jmin)/(ymax-ymin) + (jmin·ymax-jmax·ymin)/(ymax-ymin)
   
 imin = 0;  jmin =  h;
 imax = w;  jmax =  0;

 i = x · imax/(xmax-xmin) - imax·xmin/(xmax-xmin)
                          
 j = -y · jmin/(ymax-ymin) + jmin·ymax/(ymax-ymin)
   
Grafik: Paramterdarstellung von Kurven x(t), y(t)

Eine interpolierende Kurve geht durch die vorgegebenen Punkten. Eine approximierende Kurve geht durch/und/oder "angenähert" zu den vorgegebenen Punkten (polynomiale Ausgleichskurven, 2D-parametrische Ausgleichskurven ( curve fit ) .. ).

Wie lauten die x(t)-, y(t) - Formeln (Paramterdarstellung) der Geraden, wenn die beiden Geraden-Punkte P1(x1,y1) und P2(x2,y2) gegeben sind?

 // Gerade:
 x(t) = (1-t)·x1  + t·x2     // Gegebene Punkte 
 y(t) = (1-t)·y1  + t·y2     // P1(x1,y1)  und P2(x2,y2)

Für <= t < 1; 0 <= x < 1; ergeben sich Geraden-Punkte P(x,y) die zwischen P1(x1,y1) und P2(x2,y2) liegen.

Für eine Ellipse:

  // Ellipse:
  x(t) = x0 + a·cos(2·π·t)      // Ellipsen-Mittelpunkt (x0, y0) 
  y(t) = y0 + b·sin(2·π·t)      // Ellipsen-Halbachsen  ( a, b )

Für 0.00 <= t < 1.00 ergeben sich Ellipsen-Punkte P(x,y) auf der Ellipse-Linie.
Für 0.50 <= t < 1.00 ergeben sich Ellipsen-Punkte P(x,y) auf der "unteren" Ellipse^n-Linie.
Mit k = 0.,1.,2.,3 ergeben sich für 0.25·k <= t < 0.25·(k+1) Ellipsen-Punkte P(x,y) auf der Ellipse im "k-ten Quadranten".

Beispiel: Interpolation mit trigonometrischen Funktionen Prinzip

Trigonometrische Funktionen stehen im engen Zusammenhang mit dem Einheitskreis und sind neben NURBS ( nicht-uniforme rationale B-Splines ) für Kurven, Flächen im Computergrafik-Bereich, CGI, CAD und zur Modellierung beliebiger geometrischer Formen geeignet.

Wegen der günstigeren Kontinuumbedingungen werden die Polynom-Gewichtsfunktionen durch trigonometrische Gewichtsfunktionen ersetzt siehe Einführung zu Splines . Zur einfachen Einführung gebe es zunächst lediglich eine Folge von 4 Punkte ( P0, P1 --- P2, P3 ). Bei mehr 4 Punkten werden die Indizes der 4 Punkte jeweils um 1 erhöht. Gezeichnet wird der Bereich zwischen P0 --- P1, indem t = 0 ... 1 durchläuft. P(t) = g0(t)·P0 + g1(t)·P1 + g2(t)·P2 + g3(t)·P3, wobei S0, S1 "Tangenten-Steigungen" entsprechen. Als Gewichte für die Interpolation ( Bild ) werden gewählt:

 Interpolation ( siehe Bild )
 co = cos(π·t/2); 
 si = sin(π·t/2);

 g0(t) = co·(co - 1)/2     rosa 
 g1(t) = si·(si + 1)/2     rot 
 g2(t) = co·(co + 1)/2     blau 
 g3(t) = si·(si - 1)/2     schwarz 

 Folgen von je 4 Punkten:  P0, P1 --- P2, P3  
 Zeichenbereich lediglich:     P1 --- P2  für t = 0...1 

  P(t) = g3(t)·P0 + g2(t)·P1 + g1(t)·P2 + g0(t)·P3  

  
  Gegeben seien  
  a) die Punkte P1, P2, ..., Pn 
  a) der Vorgänger-Punkt P0 = P[0] und 
  b) der Nachfolge-Punkt Pn+1 = P[n+1] , dann
  d) Berechne jeweils für t = 0...1 step=(ca. 1/25)

  co = cos(π·t/2); si = sin(π·t/2);
  P(t, P0,P1...P2,P3 ) = (co*(co*(P1+P3)+P1-P3) + si*(si*(P0+P2)+P2-P0))/2
  ...
  Allg. mit i = 1 ... n step 1
  P(t, P[i]...P[i+1] ) = 
       0.5*( co*(co*(P[i  ]+P[i+2])+P[i  ]-P[i+2] ) 
     +       si*(si*(P[i-1]+P[i+1])+P[i+1]-P[i-1] ) );


  Für P(t, P[i-1], P[i]..t..P[i+1], P[i+2] ): 
  berechne für t = 0...1 step=(ca. 1/25) mit 

  co = cos(π·t/2); 
  si = sin(π·t/2); 

  die Path-Punkte

  x(t) = 0.5*(co*(co*(x[i]+x[i+2])+x[i]-x[i+2]) 
            + si*(si*(x[i-1]+x[i+1])+x[i+1]-x[i-1]));

  y(t) = 0.5*(co*(co*(y[i]+y[i+2])+y[i]-y[i+2]) 
            + si*(si*(y[i-1]+y[i+1])+y[i+1]-y[i-1]));
t-spline.png

Beispiel: Polynomiale Ausgleichskurven y(x) = a0 + a1·x + a2·x^2 +...+ an·x^n

Hinweise in der Veranstaltung.


Beispiel: Berechnung der Berechnung der Regressionsgeraden Lineare Regression

Hinweise in der Veranstaltung.



ECMAScript: Funktionen dynamisch erzeugen new Function()

Wie können zum Zeichnen von mathematischen Funktionen y(x) die ECMAScript-Funktionen per Textarea-Text dynamisch erzeugt werden? Siehe z.B. im Quelltext dieser Seite die Funktion parse_tilde_key_val_strings_in_GLOB_VAR(s). Anstelle von einfachen Funktionen y(x) sind Ortskurven x(t),y(t) universeller, denn wenn x := t gesetzt wird, ergibt sich y(t) = y(x).


test_anzeige()

Plagiate sind out!
Viel Freude bei der Ausarbeitung!
Letzter Abgabetermine Do 12.00 Uhr