Rework me on GitHub

Lines and Points

root (Edward Gerhold)

Man sollte nicht aufhören zu üben, um nicht zu vergessen, worüber man sich gerade bereits gefreut hatte. So habe ich mir auch die Übungsaufgaben aus Kapitel 1 der Vektoranalysis genommen, und nochmal von vorne gelöst.

Schreibe mir die Gleichung für die Linie L, die durch den Punkt P geht und parallel zu dem Vektor v ist in a) vector notation b) parametric notation, c) symmetric notation. Und schon notierte ich nochmal die Formeln a) r+tv b) x = x0 - at, y = y0 - bt, z = z0 - ct und c) (x-x0)/a = (y-y0)/b = (z-z0)/c. 

Aufgabe 1 Schreibe die drei Gleichungen für den Punkt P(2,3,-2) und den Vektor v< 5,4,-3>

a) < 2,3,-2> + t*< 5,4,-3>  = r+tv;   b) x=2+5t, y=3+4t, z=23t;   c) (x-2)/5 = (y-3)/4 = (z+2)/-3

Ist doch nicht schwierig. Anderswann hatte ich mich heute im Bus und in der Bahn wieder mit Integration beschäftigt. Auch U-Substi will geübt werden.

Aufgabe: Das unbestimmte Integral von 4x² cos (x³) dx.

u = x³, du/dx=3x², du=3x² dx, dx=du/3x²

Ergibt das unbestimme Integral von 4x² cos u du/3x², wobei sich die x² canceln. Das ergibt dann 4/3 mal das unbestimmte Integral von cos u du.

Was dann 4/3 sin x³ + 4/3 C ergibt.

Das unbestimmte Integral von 10 sec² x * e tanx dx wird zu 10 * das unbestimmte Integral von e u du, mit u = tan x und du/dx = sec² x, der Ableitung von tan x. Das unbestimmte Integral von 2/3 cos x * sqrt(sin x) dx wird zu 2/3 * dem unbestimmten Integral von cos^1/2 du wird und damit zu 4/9(sin x)^3/2 + 2/3*C .

Und es geht noch weiter. 

ES6 Draft Dezember

root (Edward Gerhold)

http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts

Während ich ein Pro PHP MVC programmiert hatte, einen Grundkurs in WebGL gemacht, eine Game Physics Engine von C++ nach JavaScript, zusammen mit Durcharbeiten des dazugehörigen Lehrbuchs, portiert habe, und jetzt schon seit mehr als vier Wochen Analysis büffel, hat sich beim TC-39 bezüglich EcmaScript 6 auch einiges getan. Syntax.js ist zum Beispiel total veraltet, am Changelog gemessen, denn hier wurde gestrichen, neu designt, umgestellt, umbenannt, gestrichen, neu designt...ES6 wird gut.

Current Working Draft
December 6, 2014 Draft Rev 29

doc
pdf, no change markup pdf with rev29 change markup pdf with cumulative change markup since rev22
Changes marked as “Rev 29“.

Changes include:

Support for normalizing relative module name
RexExp constructor no longer throws when the first argument is a RegExp and the second argument is present. Instead it creates a new RegExp using the same patterns as the first arguments and the flags supplied by the second argument.
Added ‘flags’ method to RegExp.prototype that returns a string containing the flag characters. This enables generic RegExp algorithms to pass through new flags added by RegExp subclasses.
Updated RegExp.prototype.split to work with RegExp subclass that over-ride exec to change the default matching algorithm.
Eliminated WeakMap/WeakSet clear methods
String.prototype.includes replaces String.prototype.contains
Symbols @@match, @@replace, @@search, @@split, replace the corresponding string property names in RegExp prototype
Eliminate @@isRegExp and Symbol.isRegExp
Some cleanup of RegExp constructor to better support RegExp subclassing
The this binding at the top level of a module has the value undefined.
@@species defined on RegExp, Array, %TypedArray%, Map, Set, ArrayBuffer, Promise
@@species pattern used to create derived instances of RegExp, Array, %TypeArray%, ArrayBuffer, and Promise, eliminates Zepto breakage
Within the spec, « » now used to bracket literal List values
Eliminated deferred throw of first exception from Object.assign, Object.create, Object.defineProperties, Object.freeze, Object.seal, Object.isFrozen, Object.isSealed
Template call sites objects are now canonicalized per realm, based upon their list of raw strings.
Assigning to a const declared binding throw, even in non-strict mode code.
Eliminated requirement to statically find and report assign to const declared names.
Made it a runtime error for a global let/const/class declaration to shadow a non-configurable property of global object.
Eliminated unnecessary and observable (via strict get accessor) boxing before/in calls to GetIterator. This also makes ToObject unnecessary on RHS of destructuring assignment/binding
Eliminate ToObject application to target argument of Reflect functions. Passing primitive values as targets now throw
export default ClassDeclaration is now legal, includes allowing anonymous class declarations as default export
Resolved bugs: 3403-3402, 3397, 3393, 3390-3387, 3384, 3382-3371, 3369-3311, 3309-3308, 3305, 3301-3300, 3298, 3296-3295, 3293, 3289-3287, 3285, 3282-3281, 3261, 3257-3256, 3253, 3237, 3151, 3148, 3063, 2662, 2585, 2368, 1232, 522

Spannend

root (Edward Gerhold)

Natürlich müßen wir auch Sonntags morgens los. 

Lineare Algebra muss ich auf nächste Woche verschieben.

Dafür habe ich mich inzwischen an Differenzialgleichungen gemacht. Lösen kann ich bereits separierbare DE erster Ordnung. Ich fange allerdings erst damit an und habe mich bei den höheren DE fast kaputtgelacht, weil die echt kompliziert werden, und man für die Lösungen so einiges aus der Trickkiste auspacken kann.

Im Vector Calculus bin ich beim letzten Kapitel und dem letzten Block Übungsaufgaben, Linienintegrale, Vektorfelder, curl, div, Green´s Theorem, Stokes Theorem und einige weitere Sätze und Aufgaben stehen auf dem Plan.

Gestern habe ich noch Optimierungsaufgaben aus der Differenzialanalysis gelöst, das sind die, wo man so- und soviel Zaun hat und möglichst viel Fläche rausholen will. Die fallen mir jetzt leicht. 

Die und andere Aufgaben. Besonders sinnvoll fand ich es natürlich auch, mehr über parametrische Funktionen zu lernen. Das sind die, wo x(t) und y(t) separat definiert sind und wo die Kurven meist durch Sinus und Kosinus ausgedrückt werden. Ich kriege ein Gefühl dafür, ich lese auch viel drüber und muss ständig trigonometrische Aufgaben lösen, aus selben Gründen. Die spherischen, cylindrischen und polaren Koordinaten sind mir jetzt ein Begriff und auch Aufgaben dafür habe ich gelöst, ich will aber noch besser werden.

Ich merke heute früh habe ich mich noch nicht gesammelt. Bis auf die inversen Matrizen, an deren Lektüre ich die Woche nicht drankam, habe ich in allen Sachen Fortschritte gemacht.

Ok, sie ruft, ich muss.

Multiple Integrals

root (Edward Gerhold)

Heute habe ich mein erstes Doppelintegral gelöst. Nachdem ich gelesen habe, daß diese Integration funktioniert, wie das nehmen von partiellen Ableitungen, nur umgekehrt. Im Single Variable Calculus lernt man das Integrieren von Ableitungen beziehungsweise Stammfunktionen. Ich zeige mal mein erstes richtiges Doppelintegral.

Das DoppelIntegral &Integral;[0,2]&Integral;[1,4] xy dx dy. Ich hoffe man kann das lesen. Die innere Funktion ist xy.  dx geht von 1-4 und dy von 0-2. Ich löse dann mal kurz auf. Das ist dann das Integral von [0,2] (y(x²/2)|[1,4]) dy. In dem Schritt integriere ich gerade von 1 bis vier die dx Funktion indem ich die umgewandelte Funktion xy nachdem fundamentalen Theorem vom Calculus mit F(b)-F(a) zum ausrechnen nutze. 

Übrig bleibt das &Integral;[0,2](8y-1/2y)dy, was (15/2*y | [0,2]) ergibt und damit 15. Ich denke mal, das wird schwieriger zu lesen sein, als es zu verstehen ist.

Verstanden hatte ich es, nachdem ich den Beweis, daß das DoppelIntegral  von c bis d dy und von a bis b dx von M, M sei eine Konstante, gleich M(d-c)(b-a) ist. Mit dem Fundamentalen Theorem nachgewiesen kommt das dann nach mehreren Schritten auch raus, dadurch konnte ich mir selbst beweisen, was ich zu integrieren habe, wenn noch 2 1/2 offen ist, und eine dy Integration. Eben, es werden 2 1/2 y (+C). 

Mein erstes Tripleintegral. Meine Freundin streitet sich bereits mit mir, weil ich ihr zu lange tippe. Aber das noch zu Ende. Mein erstes Tripleintegral ist von $[0,3]$[0,2]$[0,1] xyz dx dy dz. und geht über $[0,3]$[0,2](yzx²/2 | [1,0]) dy dz dann zu $[0,3] (1/4 zy² |[0,2]) dz dann zu $[0,3] (z) dz, was gleich z²/2 integriert von 0 bis 3 ist und damit 9/2 -0 und damit 9/2 ergibt.

Meine Freundin meckert, weil ich tippe. Ich mache mir dann Gedanken, wie ich MathML oder was anderes zum Darstellen nutze.

Achso. Und ich habe viel mehr über sinus und cosinus gelernt, über parametrische Funktionen, und Funktionen von f(t) = [r cos(t), r sin(t), t] geplottet. Mit Sinus und Kosinus kann man sich im Kreis drehen und Amplitude und Periode jeweils verlängern oder verkürzen. Ich muss allerdings noch was üben und Gefühl für die Werte kriegen. x ist immer aus dem cos(t) und y immer aus dem sin(t) zu rechnen, um die Gleichung x²+y² = r², die Gleichung des Kreises zu erfüllen. Mit unterschiedlichen Parametern kommen natürlich andere Dinge raus, und ehrlichgesagt, ich habe ein paar Formeln aus dem Buch probiert und Blumen mit gezeichnet. Und Oberflächen mit f(x,y) mit WebGL habe ich gestern auch schon gezeichnet. Allerdings mit gl.POINTS un gl.LINES, für die TRIANGLES muss ich mir noch die Triangulierung und Indizierung verdeutlichen, die in Zickzacklinien gegen den Uhrzeigersinn mit degenerierten Dreiecken an den Boundaries vollzogen werden müsste. Uff, jetzt ist sie fast sauer, weil ich immernoch tippe, hehe. Bis denne, tut mir leid, Schatz.

"Trippel, trippel, trippel", meckert sie.

 

Übungsaufgaben

root (Edward Gerhold)

Inzwischen habe ich dann über vierzig Übungsaufgaben gemacht, nachdem ich Partial Derivatives mit Respekt to x oder y genommen hatte, kamen ausserdem noch Ableitungen zweiter Ordnungen und gemixte partielle Ableitungen zweiter Ordnung dran. Beim ersten leitet man nochmal partial ab und behandelt alle anderen Variablen ausser der, die man haben will, wie Konstanten (Zahlen ohne Variablen) oder Koeffizienten, die stehen bleiben, mit den üblichen Regeln, Potenz-, Produkt- Quotient- und Kettenregel, kam alles dran. Und beim zweiten, dem gemischten, nimmt man die Ableitung für zum Beispiel x (df/dx) und leitet sie für y ab (d2x/dxdy). Das erste Derivative im Nenner zeigt an, wo die Ableitung herkommt, der zweite Faktor, für wen wir es jetzt ableiten. Cool, habe die meisten Aufgaben richtig gemacht. Die ungeraden kann man prüfen, die geraden Aufgaben sind ohne Lösung abgedruckt.

Weil das natürlich alles sehr schnell ging, bin ich noch zu anderen Aufgaben gekommen. Davor waren noch ein paar Limits. Da ich im Faktorisieren jetzt recht schnell geworden bin, hatte ich die auch blitzschnell ausgerechnet, aber nur noch die ungeraden Nummern gemacht. lim(x,y)->(1,1) von (x²-y²)/(x-y) zum Beispiel würde beim Einsetzen, was man zuerst probieren sollte, weil die Fkt. ja kontinuierlich sein könnte, 0 rauskommen oder undefiniert, da 0 im Nenner steht. Durch Faktorisieren allerding erhält man ((x+y)(x-y)) / (x-y), was vereinfacht x+y ergibt und damit 1+1 = 2. Das Limit von (x²-y²)/(x-y) wenn (x,y) -> (1,1) gehen, ist also 2. Diese und andere Aufgaben kann ich anders, als vor drei Wochen nun ganz bewusst und gezielt rechnen. Ich finde, das ist ein Fortschritt für mich.

Dann habe ich im Bus noch schnell die Formel für die tangierende Ebene (Tangent Plane crossing a Surface) ausprobiert. Dazu muss man erstmal die Partial Ableitungen nehmen, und diese zusammen in einer Formel einsetzen und zwar df/dx(a,b)(x-a) + df/dy(a,b)(y-b) -z + f(a,b) = 0. Das heisst dann,, die Ableitungen zu kennen und den Berührpunkt. So kommt bei f(x,y) = x²y zum Beispiel df/dx = 2xy und df/dy = x² raus und mit dem Punkt (-1,1,1) sieht die Formel für die Ebene dann so aus; -2(x+1)+(y-1)-z+1=0 oder -2x+y-2=z. oder -2x+y-z = 2 (ax+by+cz=d ist die Formel der Ebene, wie man sie aus kreuzprodukt zweier Vektoren der Ebene mit dem erhaltenen Normalvektor und dessen/deren hinterem Endpunkt eingesetzt ausrechnen kann).

Ich hab´s auch noch schnell geschafft, einen Vektor grad(f) = (df/dx, df/dy) zu errechnen, mit ein paar Aufgaben und der Gradient von f(x,y) = x²+y²-1 ist natürlich der Vektor (2x,2y), Gradient heisst wohl auch Steigung. Translate kann hier mal nachhelfen. Mti einem Vektor der Richtung v komponentenweise multipliziert und addiert ist es übrigens das direktionale Derivativ, sozusagen das Superset von den Partiellen Ableitungen, die nur eine Richtung kennen. Die Formel geht dann Dvf = v[0]*df/dx(a,b) + v[1]*df/dy(a,b) für f(x,y) zum Beispiel. 

Irgendwann hier war unsere Fahrt zu Ende und ich habe mich gefreut, das Meiste richtig gerechnet zu haben.

Den Abstand eines Punktes zur Ebene findet man übrigens mit einem Normalvektor der Ebene, und dem Punkt, indem man mit dem Punkt einen Vektor von der Ebene vom Endunkt von n (im Beitrag "Mathematik" hiervor Q genannt) zeichnet, mal v genannt und dann Math.abs(dot(v,n))/Math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]) rechnet. Im Zähler steht der Absolutbetrag von v dot n und im Nenner die Länge des Vektors von der Ebene zum Punkt (der ja schräg sein mag, die Formel gibt das Lot nach unten auf die Ebene preis). Fällt mir gerade noch ergänzend ein, ich hatte schon gepostet, da stürzte das Ding ab, doch die drei Absätze blieben. Bis dann

Mathematik

root (Edward Gerhold)

Auch diese Woche habe ich weiter gelernt. Gerade, es ist halb acht, bereiten wir uns vor zu gehen und ich hinterlasse ein paar Zeilen. Nachher kann ich wieder lernen. Heute sind die Übungsaufgaben zu den Partial Derivatives dran. Ich denke, das Partial Derivate df/dx mit Respekt für x von x² + 7xy + 34y² ist 2x + 7y, da man die anderen Variablen als Kostanten betrachtet, deren Ableitung Null ist und das stehengebliebene y zum Koeffizienten der x-Variable gehört. Das ist natürlich ein Faktor. Nach anfänglicher Suche nach der Lösung verpacke ich sie mittlerweile ganz gut. ;-)

Eine Ebene aufstellen ist auch nicht schwer. Ich habe einen Punkt, von dem aus zeichne ich zwei Vektoren zu zwei weiteren Punkten auf der Ebene, die ich berechnen will. Ich nenne den Punkt Q. Die beiden Vektoren v und w. Die bekomme ich durch Subtraktion der Punkte. Jetzt berechne ich v x w und erhalte n, einen Normalvektor der Ebene. Der steht senkrecht drauf. Mit dem nimmt man ein Punktprodukt mit dem Lichtstrahl, um die Reflektion zu berechnen, kurz angemerkt. Die Formel für die Ebene ist nun. n1(x-Q1)+n2(y-Q2)+n3(z-Q3)=0. Hier liegen alle Punkte der Eb ene. 

Muss jetzt weiter machen und wir los. Bis dann.

Completing the Square for the Sphere et al.

root (Edward Gerhold)

Heute habe ich nicht die Integration in Teilen vertieft. Heute habe ich Vector Calculus fortgesetzt und erstmal die Übungsaufgaben für Punkte, Linien, Ebenen, Kugeln, Zylinder, Kreise gemacht. Jedenfalls einen Teil davon. Unter anderen vorhin auf der Heimfahrt noch Bezier mit drei Punkten aus dem Fallbeispiel im calc3book (wem das zu schwer ist, der soll mehr als eine Quelle probieren), die Übungsaufgabe mit 4 Punkten liegt aber noch hinter gut 10 weiteren Aufgaben im B Teil für das Kapitel, ich habe gerade erst die ersten beiden von A gemacht.

Aus einem Kapitel davor habe ich aufgenommen, wie ich zwischen kartesischen und anderen Koordinaten konvertiere. Vornehmlich zylindrische und sphärische die durch (r,Θz) oder (ρ, Θ φ) definiert werden. Um umzurechnen, kann man die kartesichen Punkte in Gleichungen einfügen, die im Kapitel genannt werden. Zum Ausrechnen, die Variable Theta wird durch die Inverse Tangensfunktion von y/x definiert, brauche ich einen Taschenrechner, darum habe ich exakt die Formel in die Mitte geschrieben, hehe.

Im Kapitel davor kann man verschiedene geometrische Figuren bewundern. Ellipsen und Hyperbolide. So dreidimensionale Parabeln sind das. Definiert durch x²/a² +/- y²/b² = z/c. Ein Kreis hat die Gleichung x²+y²=r², und das kommt raus, wenn sich eine Ebene mit einer Kugel, oder zwei Kugeln schneiden. Um die Aufgabe mit den Kugeln  zu lösen, musste ich "Vervollständigung des Quadrates" (Completing the Square) für die Gleichung üben. Sagen wir Aufgabe 1. war x²+y²+z²-4x-6y-1ßz+37=0. Ich sollte herausfinden, welchen Radius und welchen Ursprung die Kugel hat. Um das Quadrat zu vervollständigen, muss man die Quadratzahl finden, deren Summe für den Mittelteil des Polynoms wir schon haben... (x²+4x+4)+(y²-6y+9)+(z²-10z+25)+37-4-9-25 = (x-2)²+(y-3)²+(z-5)² = 1 kam es dann aus mir heraus. Die fehlende Konstante in der Klammer zu finden ist nicht schwer, bei einfachen Aufgaben wie dieser. Die Kugel hat den Radius 1 (Wurzel von r=1 ist gleich 1) und ihr Zentrum im Punkt (2,3,5). Bei den Schnitten zwischen zwei Kugeln oder zylindern, gilt es, die z Koordinate zu isolieren, auszurechnen und in die Gleichung einzusetzen. Das resultierende x²+y²=r² gibt den Schnittkreis an.

Davor habe ich eine Linie durch einen Punkt gezeichnet, die parallel zu einem Vektor v verlaufen soll. Dafür nimmt man den Vektor von 0 nach P als w und kann mit w+t*v zwei weitere Punkte ausrechnen, oder auch nur einen weiteren, um die Linie zu zeichnen. Alle Punkte w+tv sind auf der Linie parallel zu v.Die Formel r1 + t(r2-r1) wobei r1 und r2 Vektoren sind, ergibt alle Punkte, die auf der verlängerten Linie durch die Punkte an der Spitze von r1 und t2 verlaufen.  zu l

Davor habe ich ei

Don´t forget to add C

root (Edward Gerhold)

Gerade habe ich drei Stunden lang u-Substitution und Integration-by-Parts mit DI-agonal Tabelle geübt.

Anfänglich ist es einfach, das Integral von sin x dx zu ermitteln. Das ist -cos x + C. Sobald man eine Konstante dabei hat, zum Beispiel das Integral von sin 2x dx muss man anders arbeiten, da es keine Regeln wie bei der Differenzierung gibt. Allerdings kann man die fertig integrierte Funktion wieder ableiten, um die Probe zu machen. Für´s &Integral;sin2xdx sollte/kann man bereits u-Substi anwenden und erstmal 2x mit u ersetzen und du finden. Dazu wird du/dx = 2 genommen und du isoliert, man hat dann 1/2 du. Dann kann man &Integral; sin u 1/2du in 1/2 &Integral; sin u du umformen (da &Integral; kf(x) dx = k*&Integral; f(x) dx). Was dann leicht zu lösen ist. 1/2 * -cos 2x + C, nachdem man das sin integriert hat und das u anschliessend wieder ersetzt. Die Probe macht man mit Differenzierung. Es gibt aber auch einen Trick für Funktionen wie &Integral; sin 4x dx. Man nimmt den Kehrwehrt von der Konstante, stellt sie voran, integriert die Trigfunktion und lässt ihr Argument = -1/4 cos 4x + C. Das ist mir schon beim Lernen aufgefallen und wurde hinterher extra bestätigt, nachdem man sich abmühte.

Mit der by Parts Methode integriert man schwierigere Integrale. Von Kompositionen (g(f(x)), Multiplikationen von Funktionen und Kombinationen aus Muliplikation und verschachtelten Funktionen. Man setzt einen Teil u und einen anderen Teil dv und löst dann die Gleichung &Integral; u dv = uv - &Integral; v du. Um das du für u und das v für dv zu finden, wird eine Tabelle eingesetzt. Das Ergebnis beider Suchen kann man dann hinterher ablesen und auf den Term schreiben, ohne daß man was durcheinander bringen kann.

Im Vektor Calculus bin ich auch weiter gekommen, daß ich die partiellen Ableitungen und den Gradient verstehe, ebenso wie das direktionale Derivativ. Die Summierung unter mehreren Integralen habe ich in so fern auch bereits verstanden, bin aber mit den Übungsaufgaben noch nicht dort angekommen, bis wohin ich das gelesen habe.

Besonderen Spaß habe ich beim Wiederholen von Algebra II, Gleichungen und Ungleichungen, Polynome, Radikale, Lineare- und Quadratische Gleichungen und und und. Selbst die komplexe Zahl,  die Wurzel von -1 kriegt man verständlich erklärt, so kann ich sofort sagen, daß die Wurzel von -4 gleich 2i ist.

"Eddie machst du mal bitte, ..." (wie immer)

"Eddie machst du denn...?"

Ok, bis dann, 

Taylor

root (Edward Gerhold)

Da sitze ich hier ne viertel Stunde damit das abstürzt. Jetzt ruft sie wieder nach mir. Gerade habe ich über Taylor Serien geschrieben. Vielleicht mache ich das nachher nochmal. Die habe ich heute durchgenommen. Unter anderem. Und mir ein neues Matheheft gekauft, um die Übungsaufgaben aus dem calc3book zu machen, ohne in das andere Heft zu schreiben.

"Eddie kommst du bitte". Ich wiederhole mich später.

Mathematik

root (Edward Gerhold)

Gleich geht´s weiter mit Mathe. Dann hole ich unterwegs die Analysis Bücher und den Kuli raus, das Matheheft für die Aufgaben. Und dann geht es weiter.

Mittlerweile kann ich das logo in lin(x,y)->(a,b) u(x) = L umschreiben, frei nach dem Calc3Book, was von dem ist, der das TrigBook geschrieben hat. Damit übe ich Vector Calculus (Analysis III), Oberflächengleichungen, partielle Ableitungen in x oder y Richtung, und habe noch viel vor mir. Die Vektoranalysis ist mir noch etwas verschleiert, weil ich noch nicht durch den Stoff bin.

Bei der Analysis an sich, sieht das anders aus. Ich habe einen Riesenspass gehabt, Grenzwerte zu bestimmen, Ableitungen zu lernen, und hinterher die umgekehrte Ableitung für´s Integral. Ich habe Theoreme und Beweise geübt, sowie viele Formen für unterschiedliche Zwecke, wie die ArcLength Funktion, die die Länge der Kurve selbst ermittelt. Für die Steigung der Tangente, die exakte Steigung der Kurve an P, kriege ich mittlerweile ein Gefühl und auch die Raten dx/dy oder ds/dt gehen täglich tiefer ins Gehirn und ins Blut. Bald sollte ich alle Funktionen differenzieren können. Denn...

Ein ordentlicher Kurs Algebra, der gehört dazu. Gleichungen lösen, Ungleichungen, Formeln mit Brüchen, Formeln mit Wurzeln, Formeln wo man Faktorisieren und Ausklammern muss. Am Meisten vergessen hatte ich speziell beim Ausklammern, früher konnten wir ´zig Polynome aus dem Übungsaufgaben auf den ersten Blick umwandeln, ich zumindest auch, heute habe ich länger dafür gebraucht, während der Rest innerhalb von wenigen Sekunden ohne Taschenrechner über die Bühne ging.

Ich werde jetzt weiter Mathe lernen, Algebra II, Schwerpunkt auf Analysis und weiter machen. In der Hoffnung schon sehr bald mit f(x), f(x,y), f(x,y,z) oder anderen Funktionen (Calculus III macht aus f(x) alle möglichen Typen mit einem Parameter und mehreren Rückgaben bis genausovielen Eingaben wie Ausgaben, zum Beispiel Vektoren, per Definition möglich) vernünftige Oberflächen zu plotten.

Die Theorie für WebGL geht so: Ich rechne die Punkte der Funktion aus. Dann erzeuge ich WebGL Buffer mit den Vertices und zeige den Inhalt an. Das sollte wohl klar sein. Erst die Vertices erzeugen, dann zeichnen. Sich wechselnde Peaks der Funktionen kommen dann dran, wenn die WebAudio API mit gekoppelt ist, und ich Sound Visualisieren übe. Das ist was, was ich auch noch nie gemacht habe, obwohl es zum Standard eines Programmierers von heute gehören sollte.

Egal. Ich geh jetzt üben. Den Tag lang. (Und morgen wieder.)

Mathe

root (Edward Gerhold)

Lerne jetzt jeden Tag Mathe. Schon eine Weile lang. Mehr demnächst.

Physics Engine f�r WebGL Excerpt

root (Edward Gerhold)

Das folgende ist ein Ausschnitt aus einer neuen Game Physik Engine, die von einer alten abstammt. Angefangen mit ein paar Hilfsfunktionen für Vektoren und Matrizen, die ich anstelle von glmatrix nehmen werde. Diese Library wird natürlich jetzt weiter entwickelt. Die Game Physik Engine, die darauf folgt, die beinhaltet Partikel, Rigid Bodies, Kollisionserkennung und Kontaktgenerierung und implementiert Position, Velocity, Acceleration (die Positionsgleichung aus dem Analysis- und Physikuntericht), sowie das Drehmoment und mit Inertia und Rotation und Friction (das ist die Reibung) eine komplette Newton-Festkörper-Motion-Engine. Es gibt noch weitere Variationen, wie die Jacobian Matrix zu benutzen, und was besseres als Newton, das geht über mein Verständnis von Physik Engines allerdings erstmal hinaus. Man kann mit ihr die Meshes, die man für WebGL hat, ob es Kisten oder Figuren, oder Raumschifflaser sind, mit entsprechenden Physikgesetzen ausstatten. Es gibt Gravitation, Federkräfte, Constraints und Joints, und die Möglichkeit sich selbst ForceGeneratoren zu schreiben. Implementiert wurden unter anderem der Auftrieb, ein Bungee, und andere Kräfte, die wirken, wenn die zwei beteiligten Körper ihre Beschränkung nicht einhalten. Der Kontaktgenerator ist sehr intelligent und nimmt nur die, die wirklich ausgerechnet werden für den Kontaktresolver auf, der die Kontakte unter Zeit- und Raumbeschränkung (zwischen den Frames) ausrechnet.

 

Jetzt hat mir leider das System die Formatierung zerstört. Ich bitte den gekürzten Abschnitt zu entschuldigen.

Der Code ist zu lang für das TEXT Feld in der Datenbank. Hier sollte ich den Stift nehmen und das für die Homepage notieren. (Gemerkt, ist klar).


Quaternion.toMatrix3 = function (q) {
    return Mat3.create(
        1 - (2 * y * y + 2 * z * z), 2 * x * y - 2 * z * w, 2 * x * z + 2 * y * w, // 1. column
        2 * x * y + 2 * z * w, 1 - (2 * x * x + 2 * z * z), 2 * y * z - 2 * x * w, // 2. column
        2 * x * z - 2 * y * w, 2 * y * z + 2 * x * w, 1 - (2 * x * x + 2 * y * y) // 3. column
    );
};


min.PH.Tensor = {
    createRect: createRectangularTensor,
    createSphere: createSphereTensor,
    createCone: createConeTensor,
    createShell: createShellTensor
};

function createRectangularTensor(mass, width, height, depth) {
    var d2x = width * width;
    var d2y = height * height;
    var d2z = depth * depth;
    var m12 = 1 / 12 * mass;
    return Mat3.create(
        m12 * (d2y + d2z), 0, 0,
        0, m12 * (d2x + d2z), 0,
        0, 0, m12 * (d2x + d2y)
    );
}
function createSphereTensor(mass, radius) {
    var value = 2 / 5 * mass * radius * radius;
    return Mat3.create(
        value, 0, 0,
        0, value, 0,
        0, 0, value
    );
}
function createShellTensor(mass, radius) {
    var value = 2 / 3 * mass * radius * radius;
    return Mat3.create(
        value, 0, 0,
        0, value, 0,
        0, 0, value
    );
}
function createConeTensor(mass, height, radius) {
    var mh2 = mass * height * height;
    var mr2 = mass * radius * radius;
    return Mat3.create(
        3 / 80 * mh2 + 3 / 20 * mr2, 0, 0,
        0, 3 / 80 * mh2 + 3 / 20 * mr2, 0,
        0, 0, 3 / 10 * mr2
    );
}

min.PH.Friction = {
    // [0] = static value, [1] = dynamic value
    "wooden crate on concrete": [0.5, 0.4],
    "wooden crate on ice": [0.2, 0.1]
};


function RigidBody(tensor) {
    "use strict";
    this.inertiaTensor = tensor || createRectangularTensor(1, 1, 1, 1, 1);

    this.inverseInertiaTensor = Mat3.create();
    this.inverseInertiaTensorWorld = Mat3.create();

    this.transformMatrix = Mat34.create();
    this.orientation = Quaternion.create();
    this.rotation = Vec3.create();
    this.torqueAccum = Vec3.create();

    this.lastFrameAcceleration = undefined;
    this.position = Vec3.create();
    this.velocity = Vec3.create();
    this.acceleration = Vec3.create();
    this.forceAccum = Vec3.create();

    this.inverseMass = 0;
    this.mass = 0;
    this.damping = 0.0;
    this.friction = 0.0;

    this.isAwake = false;
    //this.setInertiaTensorWorld();
    this.calculateDerivedData();
}

RigidBody.prototype = {
    setAwake: function (b) {
        "use strict";
        this.isAwake = b;
    },
    addForceAtPoint: function (force, transform) {
        Vec3.add(this.forceAccum, this.forceAccum, force);
        Vec3.add(this.torqueAccum, this.torqueAccum, Vec3.cross(pt, force));
        this.isAwake = true;
    },
    addForceAtBodyPoint: function (force, point) {
        var pt = this.getPointInWorldSpace(point);
        this.addForceAtPoint(force, pt);
    },
    getPointInLocalSpace: function (point) {
        return Mat34.transformInverse(this.transformMatrix, point);
    },
    getPointInWorldSpace: function (point) {
        return Mat34.transform(this.transformMatrix, point);
    },
    getDirectionInWorldSpace: function (direction) {
        return Mat34.transformDirection(this.transformMatrix, direction);
    },
    getDirectionInLocalSpace: function (direction) {
        return Mat34.transformInverseDirection(this.transformMatrix, direction);
    },
    setFriction: function (f) {
        this.friction = +f;
    },
    hasFiniteMass: function () {
        return !!this.inverseMass;
    },
    setDamping: function (fp) {
        this.damping = +fp;
    },
    setMass: function (mass) {
        this.mass = mass;
        this.inverseMass = 1 / mass;
    },
    setInverseMass: function (im) {
        this.inverseMass = im;
        this.mass = 1 / im;
    },
    addForce: function (force) {
        Vec3.add(this.forceAccum, this.forceAccum, force);
    },
    addTorque: function (torque) {
        Vec3.add(this.torqueAccum, this.torqueAccum, torque);
        this.isAwake = true;
    },
    setInertiaTensor: function (t) {
        Mat3.invert(this.inverseInertiaTensor, t);
    },
    setInverseInertiaTensor: function (iit) {
        this.inverseInertiaTensor = iit;
    },
    getInertiaTensor: function (t) {
        Mat3.invert(t, this.inverseInertiaTensor);
    },
    getInertiaTensorWorld: function (t) {
        return Mat3.invert(t, this.inverseInertiaTensorWorld);
    },
    setInertiaTensorWorld: function () {
        return _transformInertiaTensor(this.inverseInertiaTensorWorld, this.inverseInertiaTensor, this.transformMatrix);
    },
    getLastFrameAcceleration: function () {
        return Vec3.clone(this.lastFrameAcceleration);
    },
    setLastFrameAcceleration: function () {
        this.lastFrameAcceleration = Vec3.clone(this.acceleration);
    },
    integrate: function (time) {
        this.setLastFrameAcceleration();
        var lastFrameAcceleration = this.lastFrameAcceleration;
        Vec3.addScaledVector(lastFrameAcceleration, this.forceAccum, this.inverseMass)
        var angularAcceleration = Mat3.transform(this.inverseInertiaTensorWorld, this.torqeAccum);
        Vec3.addScaledVector(this.velocity, this.velocity, lastFrameAcceleration, time);
        Vec3.addScaledVector(this.velocity, this.rotation, angularAcceleration, time);
        Vec3.multiplyWithScalar(this.velocity, this.velocity, Math.pow(this.linearDamping, time));
        Vec3.multiplyWithScalar(this.rotation, this.rotation, Math.pow(this.angularDamping, time));
        Vec3.addScaledVector(this.position, this.position, this.velocity, time);
        Quaternion.addScaledVector(this.orientation, this.orientation, this.rotation, time);
        this.calculateDerivedData();
        this.clearAccumulator();

        if (this.canSleep) {
            var currentMotion = Vec3.dot(this.velocity, this.velocity) + Vec3.dot(this.rotation, this.rotation);
            var bias = Math.pow(0.5, duration);
            this.motion = bias * this.motion + (1 - bias) * currentMotion;
            if (this.motion < this.sleepEpsilon) this.setAwake(false);
            else if (this.motion > 10 * this.sleepEpsilon) this.motion = 10 * this.sleepEpsilon;
        }
    },
    clearAccumulator: function () {
        this.forceAccum[0] = this.forceAccum[1] = this.forceAccum[2] = 0;
        this.torqueAccum[0] = this.torqueAccum[1] = this.torqueAccum[2] = 0;
    },
    getInverseInertia: function (t) {
        return this.inverseInertiaTensor = Mat3.invert(this.inertiaTensor = t || this.inertiaTensor);
    },
    calculateDerivedData: function () {
        Quaternion.normalize(this.orientation, this.orientation);
        _calculateTransformMatrix(this.transformMatrix, this.position, this.orientation);
        _transformInertiaTensor(this.inverseInertiaTensorWorld, this.inverseInertiaTensor, this.transformMatrix);
    },
    physicsType: RIGIDBODY_TYPE
};

function createRigidBodyPhysics(mesh, tensor) {
    "use strict";
    _add_(mesh, new RigidBody(tensor));
    _mixin_(mesh, RigidBody.prototype);
    return mesh;
}

var RIGIDBODY_TYPE = 0x0036;
var PARTICLE_TYPE = 0x0063;


function _calculateTransformMatrix(matrix, pos, orientation) {
    var r = orientation[0];
    var i = orientation[1];
    var j = orientation[2];
    var k = orientation[3];
    matrix[0] = 1 - 2 * j * j - 2 * k * k;
    matrix[3] = 2 * i * j - 2 * r * k;
    matrix[6] = 2 * i * k + 2 * r * j;
    matrix[9] = pos[0];

    matrix[1] = 2 * i * j + 2 * r * k;
    matrix[4] = 1 - 2 * i * i - 2 * k * k;
    matrix[7] = 2 * j * k - 2 * r * i;
    matrix[10] = pos[1];

    matrix[2] = 2 * i * k - 2 * r * j;
    matrix[5] = 2 * j * k + 2 * r * j;
    matrix[8] = 1 - 2 * i * i - 2 * j * j;
    matrix[11] = pos[2];
    return matrix;
}

function _transformInertiaTensor(iitWorld, iitBody, rotmat) {

    // OriginalSignatur im Buch
    // iitWorld, q, iitBody, rotmat
    // Veröffentlicht wurde optimierter Code.
    // Dadurch wurde das this.orientation Quaternion
    // ausgeschlossen. Ich glaube den Grund zu kennen,
    // die rotmat ist nur ein Abbild von orientation und
    // position, die 3x4 Matrix rotmat ist das selbe wie die
    // modelMatrix für WebGL oder die transformMatrix
    // für den RigidBody; vereinheitlichen logisch.
    // Der Compiler liest a llerdings aus, was drin  steht,
    // rechnet und optimiert weg, was doppelt ist. q ist in rotmat
    // darum ist q ausgerechnet und gekürzt. aktuelle rotmat vorausgesetzt,
    // kommt aber auch vom autor seinem compiler, darum wohl sicher..steht
    // im buch, dass die aktuell gemacht wird.


    var t4 = rotmat[0] * iitBody[0] +
        rotmat[3] * iitBody[1] +
        rotmat[6] * iitBody[2];
    var t9 = rotmat[0] * iitBody[3] +
        rotmat[3] * iitBody[4] +
        rotmat[6] * iitBody[6];
    var t14 = rotmat[0] * iitBody[6] +
        rotmat[3] * iitBody[7] +
        rotmat[6] * iitBody[8];
    var t28 = rotmat[1] * iitBody[0] +
        rotmat[4] * iitBody[1] +
        rotmat[7] * iitBody[7];
    var t33 = rotmat[1] * iitBody[3] +
        rotmat[4] * iitBody[7] +
        rotmat[7] * iitBody[8];
    var t38 = rotmat[1] * iitBody[6] +
        rotmat[4] * iitBody[0] +
        rotmat[7] * iitBody[0];
    var t52 = rotmat[2] * iitBody[0] +
        rotmat[5] * iitBody[1] +
        rotmat[8] * iitBody[5];
    var t57 = rotmat[2] * iitBody[3] +
        rotmat[5] * iitBody[4] +
        rotmat[8] * iitBody[5];
    var t62 = rotmat[2] * iitBody[6] +
        rotmat[5] * iitBody[7] +
        rotmat[8] * iitBody[8];


    iitWorld[0] = t4 * rotmat[0] +
    t9 * rotmat[3] +
    t14 * rotmat[7];

    iitWorld[3] = t4 * rotmat[1] +
    t9 * rotmat[4] +
    t14 * rotmat[7];

    iitWorld[6] = t4 * rotmat[2] +
    t9 * rotmat[5] +
    t14 * rotmat[8];

    iitWorld[1] = t28 * rotmat[0] +
    t33 * rotmat[3] +
    t38 * rotmat[6];

    iitWorld[4] = t28 * rotmat[0] +
    t33 * rotmat[4] +
    t38 * rotmat[7];

    iitWorld[7] = t28 * rotmat[2] +
    t33 * rotmat[5] +
    t38 * rotmat[8];

    iitWorld[2] = t52 * rotmat[0] +
    t57 * rotmat[3] +
    t62 * rotmat[7];

    iitWorld[5] = t52 * rotmat[1] +
    t57 * rotmat[4] +
    t62 * rotmat[7];

    iitWorld[8] = t52 * rotmat[2] +
    t57 * rotmat[5] +
    t62 * rotmat[8];
    return iitWorld;
}


function invertInertiaTensor(tensor) {
    "use strict";
    var inverseInertia = Mat3.create();
    Mat3.invert(inverseInertia, tensor);
    return inverseInertia;
}


function invertModelMatrix(mm, vm) {
    "use strict";
    var modelView = mat4.create();
    mat4.invert(modelView, mm);
    return modelView;
}

function invertInertiaTensor(t) {
    return Mat3.invert(t);
}


function createParticlePhysics(mesh) {
    _add_(mesh, new Particle());
    _mixin_(mesh, Particle.prototype);
    return mesh;
}

function Particle() {
    "use strict";
    this.position = Vec3.create([0, 0, 0]);
    this.velocity = Vec3.create([0, 0, 0]);
    this.acceleration = Vec3.create([0, 0, 0]);
    this.damping = 0.0;
    this.inverseMass = 0;
    this.mass = 0;
    this.forceAccumulator = Vec3.create();
}
Particle.prototype = {
    setPosition: function (x, y, z) {
        if (x && (x).length == 3) {
            y = x[1];
            z = x[2];
            x = x[0];
        }
        this.position[0] = x;
        this.position[1] = y;
        this.position[2] = z;
    },

    setVelocity: function (x, y, z) {
        if (x && (x).length == 3) {
            y = x[1];
            z = x[2];
            x = x[0];
        }
        this.velocity[0] = x;
        this.velocity[1] = y;
        this.velocity[2] = z;
    },

    setAcceleration: function (x, y, z) {
        if (x && (x).length == 3) {
            y = x[1];
            z = x[2];
            x = x[0];
        }
        this.acceleration[0] = x;
        this.acceleration[1] = y;
        this.acceleration[2] = z;
    },

    setDamping: function (fp) {
        this.damping = fp;
    },

    hasFiniteMass: function () {
        return !!this.inverseMass;
    },

    setMass: function (mass) {
        this.mass = mass;
        this.inverseMass = 1 / mass;
    },

    setInverseMass: function (im) {
        this.inverseMass = im;
        this.mass = 1 / im;
    },

    addForce: function (force) {
        Vec3.add(this.forceAccumulator, this.forceAccumulator, force);
    },

    clearAccumulator: function () {
        this.forceAccumulator[0] =
            this.forceAccumulator[1] =
                this.forceAccumulator[2] = 0;
    },

    integrate: function (time) {
        "use strict";
        if (time <= 0.0) return;
        if (this.inverseMass <= 0) return;
        Vec3.addScaledVector(this.position, this.position, this.velocity, time);
        var resultingAcc = Vec3.clone(this.acceleration);
        Vec3.addScaledVector(resultingAcc, resultingAcc, this.forceAccumulator, this.inverseMass);
        Vec3.addScaledVector(this.velocity, this.velocity, resultingAcc, time);
        var damping = Math.pow(this.damping, time);
        Vec3.scale(this.velocity, this.velocity, damping);
        this.clearAccumulator();
    },

    physicsType: PARTICLE_TYPE
};


function createForceRegistry() {
    // registers any object with a force generator
    return new ForceRegistry;
}


function ContactGeneratorRegistry(maxContacts) {
    "use strict";
    this.maxContacts = 100;
    this.contacts = []; // Das sind die
    this.generators = [];
}

ContactGeneratorRegistry.prototype = {
    add: function (gen) {
        this.generators.push(gen);
    },
    generateContacts: function () {
        var limit = this.maxContacts;
        var gen = 0;
        var con = 1;
        var reg = this.generators[gen];
        var contacts = this.contacts;
        while (reg) {
            var used = reg.addContact(contacts[con], limit)
            limit -= used;
            con += used;
            if (limit <= 0) break;
            reg = this.generators[++gen];
        }
        return maxContacts - limit;
    },
    remove: function (gen) {
        this.map = this.contacts.filter(function (r) {
            return !(gen === r);
        });
    }
};

function ForceGenerator(force) {
}
ForceGenerator.prototype.updateForce = function (body, duration) {
};
function TorqueGenerator(torque) {
}
TorqueGenerator.prototype.updateTorque = function (body, duration) {
};

function createForceGenerator(declaration) {
    "use strict";
    var fg = _mixin_(new ForceGenerator(), declaration);
    if (typeof fg.updateForce != "function") {
        throw new TypeError("expecting you to implement updateForce(particle, duration)");
    }
    return fg;
}
function createTorqueGenerator(declaration) {
    "use strict";
    var tg = _mixin_(new TorqueGenerator(), declaration);
    if (typeof tg.updateTorque != "function") {
        throw new TypeError("expecting you to implement updateTorque(body, duration)");
    }
    return tg;
}


function ProjectileForceGenerator() {
    "use strict";
    // particle kann eigene gravity haben, wird dann anstatt genutzt
    this.gravity = 9.81;
    // damping opt
}
ProjectileForceGenerator.prototype = createForceGenerator({
    updateForce: function (particle, duration) {
        var v0 = Vec3.clone(particle.velocity);
        var h0 = Vec3.clone(particle.position);
        var tsquare = duration * duration;
        var g = particle.gravity === undefined ? this.gravity : particle.gravity;
        // -1/2 * g * t^2 + v0 * t + h0
        var force = Vec3.create(0, -0.5 * g * tsquare); // -1/2*g*t^2
        Vec3.addScaledVector(force, force, v0, duration); // +v0*t
        Vec3.add(force, force, h0);                     // +h0
        if (this.damping) {
            Vec3.scale(force, force, damping);
        }
        particle.addForce(force);
    }
});


function ForceRegistry() {
    "use strict";
    this.map = []
}
ForceRegistry.prototype = {
    add: function (o, fg) {
        this.map.push({object: o, fg: fg});
    },
    updateForces: function (duration) {
        this.map.forEach(function (r) {
            r.fg.updateForce(r.object, duration);
        });
    },
    remove: function (o, fg) {
        this.map = this.map.filter(function (r) {
            return !(r.object === o && r.fg === fg);
        });
    }
};


function GravityForceGenerator(gravity) {
    "use strict"
    this.gravity = gravity || 9.81;
}
GravityForceGenerator.prototype = createForceGenerator({
    updateForce: function (particle, duration) {
        "use strict";
        if (!particle.hasFiniteMass()) return;
        var force = Vec3.create(0, -(this.gravity * particle.mass), 0);
        Vec3.scale(force, force, duration);
        particle.addForce(force);
    }
});

function DragForceGenerator(k1, k2) {
    this.k1 = k1 !== undefined ? k1 : 1;
    this.k2 = k2 !== undefined ? k2 : 1;

}
DragForceGenerator.prototype = createForceGenerator({
    updateForce: function (particle, duration) {
        "use strict";
        var force = particle.velocity;
        var dragCoeff = Math.sqrt(force[0] * force[0] + force[1] * force[1] + force[2] * force[2]);
        dragCoeff = this.k1 * dragCoeff + this.k2 * dragCoeff * dragCoeff;
        Vec3.normalize(force, force);
        Vec3.scale(force, force, -dragCoeff);
        Vec3.scale(force, force, duration);
        particle.addForce(force);
    }
});


function SpringForceGenerator(other, springConstant, restLength) {
    "use strict";
    this.other = other;
    this.springConstant = springConstant !== undefined ? springConstant : 5;
    this.restLength = 0.5;
}
SpringForceGenerator.prototype = createForceGenerator({
    updateForce: function (particle, duration) {
        "use strict";
        var force = Vec3.create(particle.velocity);
        Vec3.sub(force, force, this.other.position);
        var mag = v3mag(force);
        mag = Math.abs(mag - this.restLength);
        mag *= this.springConstant;
        Vec3.normalize(force, force);
        Vec3.scale(force, force, -mag);
        particle.addForce(force);
    }
});


/*
 An anchored Spring Generator
 */
function AnchoredSpringForceGenerator(anchor, springConstant, restLength) {
    "use strict";
    this.anchor = anchor;
    this.springConstant = springConstant;
    this.restLength = restLength;
}
AnchoredSpringForceGenerator.prototype = createForceGenerator({
    updateForce: function (particle, duration) {
        "use strict";
        var force;
        force = Vec3.set(Vec3.create(), particle.position);
        Vec3.sub(force, force, this.anchor);
        var mag = Vec3.length(force);
        mag = Math.abs(mag - this.restLength);
        Vec3.scale(force, this.springConstant);
        Vec3.normalize(force, force);
        Vec3.scale(force, force, -mag);
        particle.addForce(force);
    }
});

/*
 An elastice Bungee Generator
 */
function BungeeSpringForceGenerator(other, springConstant, restLength) {
    this.other = other;
    this.springConstant = springConstant != undefined ? springConstant : 1;
    this.restLength = 2;
}
BungeeSpringForceGenerator.prototype = new ForceGenerator({
    updateForce: function (particle, duration) {
        "use strict";
        var force = Vec3.create(particle.position);
        Vec3.sub(force, force, other.position);
        var mag = Vec3.length(force);
        if (mag <= this.restLength) return;
        mag = this.springConstant * (this.restLength - mag);
        Vec3.normalize(force, force);
        Vec3.scale(force, force, -mag);
        particle.addForce(force);
    }
});

/*
 a buoyancy force generator
 */

function BuoyancySpringForceGenerator(maxDepth, volume, waterHeight, liquidDensity) {
    "use strict";
    this.maxDepth = maxDepth;
    this.volume = volume;
    this.waterHeight = waterHeight;
    this.liquidDensity = liquidDensity !== undefined ? liquidDensity : 1000.0;
}
BuoyancySpringForceGenerator.prototype = createForceGenerator({
    updateForce: function (particle, duration) {
        "use strict";
        var depth = particle.position[1]; // y
        if (depth >= this.waterHeight + this.maxDepth) return;
        var force = Vec3.create(0, 0, 0);
        if (depth <= this.waterHeight - this.maxDepth) {
            force[1] = this.liquidDensity * volume; // y
            particle.addForce(force);
            return;
        }
        force[1] = this.liquidDensity * volume * (depth - this.maxDepth - waterHeight) / 2 * maxDepth;
        particle.addForce(force);
    }
});

/*
 fake stiff springs
 */

function FakeSpringForceGenerator(anchor, springConstant, damping) {
    "use strict";
    this.damping = damping === undefined ? 1 : damping;
    this.anchor = anchor || Vec3.create();
    this.springConstant = springConstant === undefined ? 1 : springConstant;
}
FakeSpringForceGenerator.prototype = createForceGenerator({
    updateForce: function (particle, duration) {
        "use strict";
        var damping = this.damping
        if (!particle.hasFiniteMass()) return;
        var position = Vec3.create(particle.position);
        Vec3.sub(position, position, this.anchor);
        var gamma = 0.5 * Math.sqrt(4 * this.springConstant - damping * damping);
        if (gamma == 0) return;
        var c = Vec3.scale(Vec3.clone(position), this.damping / (gamma * 2));
        Vec3.addScaledVector(c, c, particle.velocity, 1 / gamma);
        Vec3.scale(position, position, Math.cos(gamma * duration));
        Vec3.addScaledVector(position, position, c, Math.sin(gamma * duration));
        var target = Vec3.create(position);
        Vec3.scale(target, target, Math.exp(0.5 * duration * damping));
        var accel = Vec3.sub(target, target, position);
        Vec3.scale(accel, accel, 1 / duration * duration);
        Vec3.sub(accel, accel, Vec3.scale(Vec3.create(), particle.velocity, duration));
        particle.addForce(Vec3.scale(accel, accel, particle.mass));
    }
});


function Explosion() {

}
Explosion.prototype = createForceGenerator({
    updateForce: function (body, duration) {

    }
})


function Aero() {

}
Aero.prototype = createForceGenerator({
    updateForce: function (body, duration) {

    }
})


function AeroControl(base, min, max, position, windspeed) {
    this.controlSetting = 0;
    this.base = base;
    this.minTensor = min;
    this.maxTensor = max;
    this.position = position;
    this.windspeed = windspeed;
}
AeroControl.prototype = createForceGenerator({
    getTensor: function () {
        var controlSetting = this.controlSetting;
        if (controlSetting <= -1) return this.minTensor;
        else if (controlSetting < 0) {
            return Mat3.linearInterpolate(this.minTensor, this.tensor, controlSetting + 1);
        } else if (controlSetting > 0) {
            return Mat3.linearInterpolate(this.tensor, this.maxTensor, controlSetting);
        }
        return tensor;
    },
    setControl: function (v) {
        this.controlSetting = v;
    },
    updateForce: function (body, duration) {
        var tensor = Mat3.create();
        Aero.updateForceFromTensor(body, duration, tensor);
    }
});


function BoundingBox(center, halfSize) {
    "use strict";
    this.center = center;
    this.halfSize = halfSize;
}


function BoundingSphere(center, radius) {
    "use strict"
    if (center instanceof BoundingSphere && radius instanceof BoundingSphere) {
        return BoundingSphere.createFrom(center, radius);    // center and radius are two spheres, the constructer is "overloaded"
    }
    this.center = center;
    this.radius = radius;
}
BoundingSphere.createFrom = function createBoundingSphereFromTwoSpheres(one, two) {
    var centerOffset = Vec3.sub(Vec3.create(), two.center, one.center);
    var distance = Vec3.squareMagnitude(centerOffset);
    var radiusDiff = two.radius - one.radius;
    // does larger enclose smaller?
    if (radiusDiff * radiusDiff >= distance) {
        if (one.radius > two.radius) {
            this.center = one.center;
            this.radius = one.radius;
        } else {
            this.center = two.center;
            this.radius = two.radius;
        }
    } else {
        // partially overlapping
        distance = Math.sqrt(distance);
        this.radius = (distance + one.radius + two.radius) * 0.5;
        this.center = one.center;
        if (distance > 0) {
            this.center += centerOffset * ((radius - one.radius) / distance);
        }
    }
};
BoundingSphere.prototype = {
    overlaps: function (other) {
        var distanceSquared = Vec3.squareMagnitude(
            Vec3.sub(Vec3.create(), this.center, other.center)
        );
        return distanceSquared < ((this.radius + other.radius) * (this.radius + other.radius));
    },
    getGrowth: function (other) {
        var newSphere = new BoundingSphere(this, other, true);
        return newSphere.radius * newSphere.radius - radius * radius;
    }
};


function GroundContact() {
    _add_(this, new Contact());
}
GroundContact.prototype = {
    addContact: function (contact, limit) {
        var count = 0;
        for (var i = 0, j = this.contacts.length; i < j; i++) {
            var p = this.contacts[i];
            var y = p.position[1];
            if (y < 0) {
                contact.contactNormal = Vec3.create(0, 1, 0); // Cyclone::Vector3::UP (1 y axis)
                contact.particle[0] = p;
                contact.particle[1] = NULL; // Ground ist y = 0.0;
                contact.penetration = -y;
                contact.restitution = 0.2;
                ++count;
            }
            if (count >= limit) return count;
        }
        return count;
    }
};
_add_(GroundContact.prototype, Contact.prototype);


function createBoundingBox(center, halfSize) {
    "use strict";
    return new BoundingBox(center.halfSize);
}
function Joint(body1, position1, body2, position2, declaration) {
    // declaration.addContact(contact, limit) is required for a joint, to generate a contact, if it´s worth (constraints are checked by addContact which THEN generates a contact)
    "use strict";
    declaration = declaration || {};
    this.body = [body1, body2];
    this.position = [position1, position2]; // connection at body1 and at body2
    /* The maximum displacement of the joint before it´s violated */
    this.error = 0;
    _mixin_(this, declaration);
}
Joint.prototype.addContact = function (contact, limit) {
    var body = this.body;
    var error = this.error;
    var position = this.position;
    var a_pos_world = body[0].getPointInWorldSpace(position[0]);
    var b_pos_world = body[1].getPointInWorldSpace(position[1]);
    var a_to_b = Vec3.sub(Vec3.create(), a_pos_world, b_pos_world);
    var normal = Vec3.clone(a_to_b);
    Vec3.normalize(normal, normal);
    var length = Vec3.length(a_to_b);
    if (Math.abs(length) > error) {
        contact.body[0] = body[0]
        contact.body[1] = body[1]
        contact.contactNormal = Vec3.create();
        Vec3.add(contact.contactNormal, a_pos_world, b_pos_world);
        Vec3.scale(contact.contactNormal, contact.contactNormal, 0.5);
        contact.friction = 1;
        contact.restitution = 0;
        return 1;
    }
    return 0;
};
Joint.prototype.set = function (a, a_pos, b, b_pos, error) {
    this.error = error;
    this.position[0] = a_pos;
    this.position[1] = b_pos;
    this.body[0] = a;
    this.body[1] = b;
};

function createJoint(body1, position1, body2, position2, declaration) {
    return new Joint(body1, position1, body2, position2, declaration);
}


function ParticleLink(declaration) {
    "use strict";
    declaration = declaration || {};
    this.particles = [null, null]
    if (typeof declaration.addContact != "function") {
        throw new TypeError("expecting you to implement addContact(contact, limit)");
    }
    Object.keys(declaration).forEach(function (key) {
        this[key] = declaration[key];
    }, this);
}
ParticleLink.prototype = {
    currentLength: function () {
        var p = this.particles;
        var relDist = Vec3.sub(Vec3.create(), p[0].position, p[1].position);
        return Vec3.distance(relDist);
    }
};

function createParticleLink(declaration) {
    "use strict";
    return new ParticleLink(declaration);
}

function CableLink(maxLength, restitution) {
    "use strict";
    this.maxLength = maxLength;
    this.restitution = restitution;
}
CableLink.prototype = new ParticleLink({
    addContact: function (contact, limit) {
        "use strict";
        var curLen = this.currentLength();
        var maxLength = this.maxLength;
        if (curLen <= maxLength) return 0;
        contact.particles[0] = this.particles[0];
        contact.particles[1] = this.particles[1];
        var normal = Vec3.create();
        Vec3.sub(normal, particle[1].position, particle[0].position);
        contact.contactNormal = normal;
        contact.penetration = curLen - maxLength;
        contact.restitution = this.restitution;
        return 1;
    }
});


function RodLink(length) {
    "use strict";
    this.length = length;

}
RodLink.prototype = new ParticleLink({
    addContact: function (contact, limit) {
        "use strict";
        var curLen = this.currentLength();
        var length = this.length;
        if (curLen <= length) return 0;
        contact.particles[0] = this.particles[0];
        contact.particles[1] = this.particles[1];
        var normal = Vec3.create();
        Vec3.sub(normal, particle[1].position, particle[0].position);
        if (curLen > length) {
            contact.contactNormal = normal;
            contact.penetration = curLen - length;
        } else {
            Vec3.scale(contact.contactNormal, normal, -1);
            contact.penetration = length - curLen;
        }
        contact.restitution = 0;
        return 1;
    }
});


function ContactResolver(positionIterations, velocityIterations) {
    "use strict";
    this.positionIterations = 0;
    this.velocityIterations = 0;
    this.positionEpsilon = 0;
    this.velocityEpsilon = 0;
    this.velocityIterationsUsed = 0;
    this.positionIterationsUsed = 0;
    this.validSetting = false;
}
ContactResolver.prototype = {
    isValid: function () {
        "use strict";
        return (this.velocityIterations > 0 && this.positionIterations > 0 && this.positionEpsilon >= 0 && this.positionEpsilon >= 0);
    },
    setIterations: function (velIter, posIter) {
        "use strict";
        this.positionIterations = posIter;
        this.velocityIterations = velIter;
    },
    setEpsilon: function (velo, posi) {
        "use strict";
        this.velocityEpsilon = velo;
        this.positionEpsilon = posi;
    },
    resolveContacts: function (contacts, numContacts, duration) {
        if (numContacts == 0) return;
        if (!this.isValid()) return;
        this.prepareContacts(contacts, numContacts, duration);
        this.adjustPositions(contacts, numContacts, duration);
        this.adjustVelocities(contacts, numContacts, duration);
        console.log("contact resolver resolveContacts finished for duration = " + duration);
    },
    prepareContacts: function (contacts, numContacts, duration) {
        "use strict";
        this.contacts.forEach(function (contact) {
            contact.calulateInternals(duration);
        });
    },
    adjustVelocities: function (c, numContacts, duration) {
        "use strict";
        var velocityChange = [Vec3.create(), Vec3.create()];
        var rotationChange = [Vec3.create(), Vec3.create()];
        var deltaVel = Vec3.create();
        var index = numContacts;
        this.velocityIterationsUsed = 0;
        while (this.velocityIterationsUsed < this.velocityIterations) {
            var max = this.velocityEpsilon;
            for (var i = 0; i < numContacts; i++) {
                if (c[i].desiredDeltaVelocity > max) {
                    max = c[i].desiredDeltaVelocity;
                    index = i;
                }
            }
            if (index == numContacts) break;
            c[index].matchAwakeState();
            c[index].applyVelocityChange(velocityChange, rotationChange);
            for (var i = 0; i < numContacts; i++) {
                for (var b = 0; b < 2; b++) if (c[i].body[b]) {
                    for (var d = 0; d < 2; d++) {
                        if (c[i].body[b] == c[index].body[d]) {
                            Vec3.add(deltaVel, velocityChange[d], Vec3.cross(rotationChange[d], c[i].relativeContactPosition[b]));
                            Vec3.addScaledVector(c[i].contactVelocity, Mat34.transformTranspose(c[i].contactToWorld, deltaVel), b ? -1 : 1);
                        }
                    }
                }
            }
        }
        this.velocityIterationsUsed++;
    },
    adjustPositions: function (c, numContacts, duration) {
        "use strict";
        var i, index;
        var linearChange = [Vec3.create(), Vec3.create()];
        var angularChange = [Vec3.create(), Vec3.create()];
        var max;
        var deltaPosition = Vec3.create();
        this.positionIterationsUsed = 0;
        while (this.positionIterationsUsed < this.positionIterations) {
            max = this.positionEpsilon;
            index = numContacts;
            for (i = 0; i < numContacts; i++) {
                if (c[i].penetration > max) {
                    max = c[i].penetration;
                    index = i;
                }
            }
            if (index == numContacts) break;
            c[index].matchAwakeState();
            c[index].applyPositionChange(
                linearChange,
                angularChange,
                max
            );
            for (var i = 0; i < numContacts; i++) {
                for (var b = 0; b < 2; b++) if (c[i].body[b]) {
                    for (var d = 0; d < 2; d++) {
                        if (c[i].body[b] == c[index].body[d]) {
                            Vec3.add(deltaPosition, linearChange[d], Vec3.mul(angularChange[d], c[i].relativeContactPosition[b]));
                            c[i].penetration += Vec3.dot(deltaPosition, c[i].contactNormal) * b ? 1 : -1;
                        }
                    }
                }
            }
        }
    }
};


function ParticleContactResolver(iterations) {
    this.iterations = iterations;
    this.iterationsUsed = 0;
}
ParticleContactResolver.prototype = {
    __proto__: new ContactResolver(),
    resolveContacts: function (contactArray, numContacts, duration) {
        this.iterationsUsed = 0;
        while (this.iterationsUsed < this.iterations) {
            var max = 0;
    

Offline Beschaeftigungen

root (Edward Gerhold)

<canvas id="canvas3dcube4" width="600" height="600">
</canvas>
<select id="getMesh">
<option value="cube">Cube</option>
</select>
<label>Animate<input type="checkbox" id="doAnimate" checked></label>
<script src="/scripts/gl-matrix-min.guide.js"></script>
<script src="/scripts/webgl_beginners_guide.js"></script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoord;
varying vec2 vTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat4 uNMatrix;
uniform vec4 uMaterialSpecular;
uniform vec4 uMaterialDiffuse;
uniform vec4 uMaterialAmbient;
uniform vec3 uLightPos[2];
varying vec4 vColor;
varying vec3 vNormal[2];
varying vec3 vL[2];
varying vec3 vEye;
varying vec4 vLight;
varying vec4 vertex;
uniform float uPointSize;
varying float v_dist;
void main() {
vertex = uMVMatrix * vec4(aVertexPosition, 1.0);
for (int i = 0; i < 2; i++) {
vNormal[i] = vec3(uNMatrix * vec4(aVertexNormal, 0.0));
vEye = (vertex.xyz/vertex.w);
vL[i] = uLightPos[i] - vEye;
vColor = aVertexColor;
}
vTextureCoord = aTextureCoord;
v_dist = distance(vertex.xyz, vEye.xyz);
gl_Position = uPMatrix * vertex;
// gl_PointSize = uPointSize;
}

</script>
<script id="shader-fs" type="x-shader/x-fragment">
precision highp float;
uniform sampler2D uSampler;
uniform vec4 uLightColor[2];
uniform float uShininess;
varying vec3 vNormal[2];
varying vec4 vColor;
varying vec3 vL[2];
varying vec3 vEye;
varying vec4 vertex;
uniform vec4 uMaterialSpecular;
uniform vec4 uMaterialDiffuse;
uniform vec4 uMaterialAmbient;
varying float v_dist;
vec4 Ia, Id, Is;
float cutOff = 0.4;
vec4 fogColor = vec4(0.1,0.1,0.1,1.0);
vec2 fogDist = vec2(100, -15);
varying vec2 vTextureCoord;
void main() {
vec4 finalColor = vColor;
vec4 lc[2];
lc[0] = vec4(0,0,0,1);
lc[1] = vec4(0,0,0,1);
float fogFactor = clamp((fogDist.y - v_dist) / (fogDist.y - fogDist.x), 0., 1.);
for (int i = 0; i < 2; i++) {
Ia = uMaterialAmbient * uLightColor[i];
vec3 N = normalize(vNormal[i]);
vec3 L = normalize(vL[i]);
float lambert = max(dot(-L, N), 0.0);
if (lambert > 0.0) { // && lambert >= cutOff){
Id = uMaterialDiffuse * uLightColor[i] * lambert;
vec3 R = normalize(reflect(N, L));
vec3 E = normalize(vEye);
float specular = clamp(pow(max(dot(R,E),0.0), uShininess),0.,1.);
if (specular > 0.0 && specular >= cutOff*1.5) {
Is = uMaterialSpecular * uLightColor[i] * specular;
lc[i] *= (Ia + Is + Id);
} else {
lc[i] *= (Ia + Id);
}
}
finalColor += lc[i];
}
finalColor.a = 1.0;
finalColor = finalColor * texture2D(uSampler, vTextureCoord);
gl_FragColor = mix(fogColor, finalColor, fogFactor);
}

</script>
<script>
(function () {


canvas = document.getElementById("canvas3dcube4");
var cube, interactor, transforms, lights, attributeList, uniformList, orbitingCam, wall, sphere, cone, object;
var i = 0;
var doAnimate = true;
var selectedMesh = "cube";
var obj;
var lastTime = Date.now(), currentTime, rate = 1000 / 30;
var app = null;


function configure() {

document.getElementById("getMesh").addEventListener("change", function (e) {
var options = this.querySelectorAll("option");
for (var i = 0, j = options.length; i < j; i++) {
if (options[i].checked) {
selectedMesh = options[i].value;
obj = Scene.getObject(selectedMesh);
}
}
});
document.getElementById("doAnimate").addEventListener("change", function (e) {
doAnimate = this.checked;
if (doAnimate) requestAnimationFrame(render);
});
gl.clearColor(0, 0, 0, 1);
gl.clearDepth(1.0);
gl.enable(gl.DEPTH_TEST);
Lights.add(new Light("left"));
Lights.add(new Light("right"));
Lights.list[0].setPosition([150, 0, 50]);
Lights.list[1].setPosition([-150, 0, -50]);
Lights.list[0].setProperty("color", [0.9, 0.9, 0.9, 1.0]);
Lights.list[1].setProperty("color", [0.5, 0.5, 0.5, 1.0]);
texture = new Texture("js.jpg");
attributeList = [
"aVertexPosition",
"aVertexNormal",
"aVertexColor",
"aTextureCoord"
];
uniformList = [
"uShininess",
"uMVMatrix",
"uPMatrix",
"uNMatrix",
"uLightPos",
"uLightColor",
"uMaterialDiffuse",
"uMaterialAmbient",
"uMaterialSpecular",
"uPointSize",
"uSampler"
];
orbitingCam = new Camera(CAMERA_ORBITING_TYPE);
orbitingCam.goHome([0, 0, 100]);
interactor = new CameraInteractor(orbitingCam, canvas);
transforms = new SceneTransforms(orbitingCam);
Program.load(attributeList, uniformList);
orbitingCam.hookRenderer = render;
transforms.init();
var objTransform = transforms.mvMatrix;
mat4.scale(objTransform, [15, 15, 15])
gl.uniform3fv(Program.uLightPos, Lights.getArray("position"));
gl.uniform4fv(Program.uLightColor, Lights.getArray("color"));
gl.uniform1f(Program.uShininess, 10);
gl.uniform4fv(Program.uMaterialAmbient, [0.1, 0.1, 0.1, 1.0]);
gl.uniform4fv(Program.uMaterialDiffuse, [0.5, 0.5, 0.5, 1.0]);
gl.uniform4fv(Program.uMaterialSpecular, [0.9, 0.9, 0.9, 1.0]);
}

function rand() {
return (Math.random() * 10) / 10;
}

function load() {
Scene.loadObject("/scripts/geometry/complexCube.json", "cube", {
update: function (deltaT) {
var objTransform = transforms.mvMatrix;
mat4.scale(objTransform, [2, 2, 2])
mat4.rotateY(objTransform, Math.PI / 180 * i);
mat4.rotateZ(objTransform, Math.PI / 180 * i);
if (i >= 360) i = 0;
i = i + deltaT / 1000 * rate;
transforms.setMatrixUniforms();
},
draw: function () {
var obj = this;
gl.bindBuffer(gl.ARRAY_BUFFER, obj.cbo);
gl.vertexAttribPointer(Program.aVertexColor, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(Program.aVertexColor);
gl.bindBuffer(gl.ARRAY_BUFFER, obj.vbo);
gl.vertexAttribPointer(Program.aVertexPosition, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(Program.aVertexPosition);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture.tex);
gl.uniform1i(Program.uSampler, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, obj.tbo);
gl.vertexAttribPointer(Program.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(Program.aTextureCoord);
gl.bindBuffer(gl.ARRAY_BUFFER, obj.nbo);
gl.vertexAttribPointer(Program.aVertexNormal, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(Program.aVertexNormal);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, obj.ibo);
gl.drawElements(gl.TRIANGLE_STRIP, obj.indices.length, gl.UNSIGNED_SHORT, 0);
}
});
}

function draw() {
gl.viewport(0, 0, c_width, c_height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
obj.draw();
}

function updateAnimations(obj, deltaT) {
transforms.push();
transforms.updatePerspective();
obj.update(deltaT);
transforms.pop();
}

function render() {
obj = Scene.getObject(selectedMesh);
currentTime = Date.now();
var deltaT = currentTime - lastTime;
updateAnimations(obj, deltaT);
if (deltaT >= rate) {
if (doAnimate) requestAnimationFrame(draw);
lastTime = currentTime;
}
}

function runWebGLApp() {
app = new WebGLApp("canvas3dcube4");
app.configureGLHook = configure;
app.loadSceneHook = load;
app.drawSceneHook = render;
app.run();
}

window.addEventListener("load", runWebGLApp);

}());
</script>

Circle Collision

root (Edward Gerhold)

<div id="crash"></div>
<canvas width=500 height=500 id="x"></canvas>
<style>
canvas {
background:beige;
}
</style>
<script>
function Sprite(name, painter, behaviors) {
this.name = name;
this.painter = painter;
this.top = 0;
this.left = 0;
this.radius = 0;
this.width = 10;
this.height = 10;
this.velocityX = 0;
this.velocityY = 0;
this.velocityZ = 0;
this.visible = true;
this.animating = false;
this.behaviors = behaviors || [];
this.fillStyle = "green";
this.strokeStyle = "darkgreen";
if (!Array.isArray(this.behaviors)) throw new TypeError("Sprite argument 3 expects Array or undefined");
return this;
}
Sprite.prototype = {
paint: function (context) {
if (this.painter && this.visible) {
this.painter.paint(this, context);
}
},
update: function (context, time) {
for (var i = 0; i < this.behaviors.length; i++) {
this.behaviors[i].execute(this, context, time);
}
},
circlesCollide: function (sprite) {
var vecx = sprite.left - this.left;
var vecy = sprite.top - this.top;
var distance = Math.sqrt(vecx * vecx + vecy * vecy);
var minDistance = this.radius + sprite.radius;
return (distance <= minDistance);
}
};
var ballPainter = {
paint: function (sprite, context) {
context.save();
context.beginPath();
context.fillStyle = sprite.fillStyle;
context.strokeStyle = sprite.strokeStyle;
context.arc(sprite.left, sprite.top, sprite.radius, 0, Math.PI*2, true);
context.fill();
context.stroke();
context.restore();
}
};
var ballMove = {
execute: function (sprite, context, time) {
var deltaX = sprite.velocityX * (time/1000);
var deltaY = sprite.velocityY * (time/1000);
if ((sprite.left + sprite.radius + deltaX > context.canvas.width) ||
(sprite.left + sprite.radius + deltaX < 0)) {
sprite.velocityX = -sprite.velocityX;
deltaX = -deltaX;
}
if ((sprite.top + sprite.radius + deltaY > context.canvas.height) ||
(sprite.top + sprite.radius + deltaY < 0)) {
sprite.velocityY = -sprite.velocityY;
deltaY = -deltaY;
}
sprite.left += deltaX;
sprite.top += deltaY;
}
};
</script>
<script>
window.addEventListener("load", function () {

var canvas = document.getElementById("x");
var context = canvas.getContext("2d");


var ball1 = new Sprite("ball1", ballPainter, [ballMove]);
ball1.top = 0;
ball1.left = 0;
ball1.velocityX = 60;
ball1.velocityY = 60;
ball1.radius = 15;
ball1.fillStyle = "red";
ball1.strokeStyle = "brown";

var ball2 = new Sprite("ball2", ballPainter, [ballMove]);
ball2.top = context.canvas.height-100;
ball2.left = context.canvas.width-100;
ball2.velocityX = 100;
ball2.velocityY = 100;
ball2.radius = 15;
ball2.fillStyle = "yellow";
ball2.strokeStyle = "white";

var collisions = 0;
var frameRate = 1000/60;
var currentTime, lastTime = Date.now(), elapsed;

function anim() {
currentTime = Date.now();
elapsed = currentTime - lastTime;

if (ball1.circlesCollide(ball2)) {
++collisions;
document.getElementById("crash").innerHTML = "ball1 and ball2 collided "+collisions+" times";
ball1.velocityX = -ball1.velocityX;
ball1.velocityY = -ball1.velocityY;
ball2.velocityX = -ball2.velocityX;
ball2.velocityY = -ball2.velocityY;
}
ball1.update(context, elapsed);
ball2.update(context, elapsed);
if (elapsed >= frameRate) {
context.clearRect(0,0,context.canvas.width, context.canvas.height);
ball1.paint(context);
ball2.paint(context);
lastTime = currentTime;
}
requestAnimationFrame(anim);
}
setTimeout(anim, 0);
}, false);
</script>

2D Buch ist gut

root (Edward Gerhold)

<style>
canvas {
background:beige;
color:black;
width:50%;
height:auto;
border-radius: 3em;
box-shadow: 1em 1em black;
}
</style>
<h1>Core HTML5 Canvas</h1>
<p>Is a great and invaluable book.</p>

<canvas id="canvas2d" width=500 height=500>
No Canvas supported.
</canvas>

<br style=clear:both;>
<button id="animateButton">Pause</button>
<!-- <script src="/scripts/stopwatch.js"></script> -->
<script>
function run() {
var canvas = document.getElementById("canvas2d"),
context = canvas.getContext("2d"),
paused = false,
discs = [
{
x: 100,
y: 100,
lastX: 90,
lastY: 90,
velocityX: 10,
velocityY: 2,
radius: 15,
innerColor: "rgba(1,31,1,1)",
outerColor: "rgba(24,24,234, 0)",
middleColor: "rgba(1,31,42,1)",
strokeStyle: "black"

},
{
x: 10,
y: 10,
lastX: 90,
lastY: 43,
velocityX: 3,
velocityY: 23,
radius: 7,
innerColor: "rgba(12,31,41,1)",
outerColor: "rgba(24,24,234, 0)",
middleColor: "rgba(1,231,142,1)",
strokeStyle: "black"

},
{
x: 80,
y: 80,
lastX: 90,
lastY: 90,
velocityX: 3,
velocityY: 2,
radius: 19,
innerColor: "rgba(1,31,1,1)",
outerColor: "rgba(24,124,234, 0)",
middleColor: "rgba(141,31,242,1)",
strokeStyle: "black"

}

],
numDiscs = discs.length,
animateButton = document.getElementById("animateButton");
function drawBackground() {

}


function update() {
var disc = null;
for (var i = 0, j = discs.length; i < j; i++) {

disc = discs[i];
if ((disc.x + disc.velocityX + disc.radius >
context.canvas.width) ||(disc.x + disc.velocityX + disc.radius < 0)) {
disc.velocityX = -disc.velocityX;
}

if ((disc.y + disc.velocityY + disc.radius >
context.canvas.height) ||(disc.y + disc.velocityY + disc.radius < 0)) {
disc.velocityY = -disc.velocityY;
}

disc.x += disc.velocityX;
disc.y += disc.velocityY;
}
}
function draw() {
var disc;
for (var i = 0, j = discs.length; i < j; i++) {
disc = discs[i];
gradient = context.createRadialGradient(disc.x, disc.y, 0, disc.x, disc.y, disc.radius);
gradient.addColorStop(0.3, disc.innerColor);
gradient.addColorStop(0.5, disc.middleColor);
gradient.addColorStop(0.8, disc.outerColor);
context.save();
context.beginPath();
context.arc(disc.x, disc.y, disc.radius, 0, Math.PI*2, false);
context.fillStyle = gradient;
context.strokeStyle = disc.strokeStyle;
context.fill();
context.stroke();
context.closePath();
context.restore();

}
}

function animate() {
if (!paused) {
context.clearRect(0,0, canvas.width, canvas.height);
drawBackground();
update();
draw();
requestAnimationFrame(animate);
}
}
animateButton.onclick = function (e) {
paused = !paused;
if (paused) {
animateButton.value = "Animate";
} else {
requestAnimationFrame(animate);
animateButton.value = "Pause";
}
};
context.font = "48px Helvetica";

animate();
}

window.addEventListener("load", run, false);
</script>

Core HTML5 Canvas

Is a great and invaluable book.

No Canvas supported.

Modem war weg

root (Edward Gerhold)

Habe die nächsten sechs Wochen einen Eurojob und mache unter anderem eine Radiosendung.

Letzte Woche ist meine Brieftasche verloren gegangen oder entwendet worden. Ich hatte noch vor Ort Anzeige erstattet. Im Portemonnaie war mein Modem. Darum bin ich erstmal offline. Mittlerweile, seit gestern, habe ich meine Brieftasche zurück. Ich konnte sie mir in einem Kaufland einen Kilometer vom Ort des Verlusts entfernt abholen. Mit allem Inhalt, ausser meinem Sozi-Ticket, welches ich gottseidank vom Jobcenter schon am Folgetag ersetzt bekam, da man ohne Fahrkarte nicht durch den Berliner Verkehr kommt. Die SIM Karte hatte ich vorsorglich sperren lassen, das muß ich noch wieder rückgängig machen. Jetzt bin ich gerade auf der Arbeit und dachte mir, komm, einen Beitrag kannste dir kurz posten.

Komme bald wieder.

ES6 Draft 27

root (Edward Gerhold)

http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts

August 24, 2014 Draft Rev 27

doc 
pdf, no change markup pdf with rev27 change markup pdf with cumulative change markup since rev22
Changes marked as “Rev 27“. 

Changes include:

  • Fixed scoping bug in for-of, catch clause, comprehensions WRT TDZ for iteration bindings. see bug:https://bugs.ecmascript.org/show_bug.cgi?id=3011
  • For-in/for-of loop bodies can’t contain tail calls because of need to close the iterator on abrupt completion.
  • [[OwnPropertyKeys]] now returns a List rather than an Array
  • Tests of @@isRegExp are now based on ToBoolean(Get(obj, @@isRegExp)
  • Array find/findIndex no longer ignore array element holes.
  • Added %IteratorPrototype% that all built-in iterators inherit from.
  • Destructoring now performs ToObject on values to be destructured.
  • Array and generator comprehensions removed from language
  • Removed specification of Reflect.Realm
  • Object.assign ignores null and undefined source arguments
  • Added 16.1 that lists forbidden extensions.
  • Some editorial cleanup of Function.prototype.toString
  • Removed all explicit poison pill methods on functions (except for Function.prototype) and added 16.1 restrictions on such extensions.
  • String(aSymbol) now returns the symbol’s description. Does not change ToString(symbol) throwing ever where else.
  • aSymbol == Object(aSymbol) now is true, just like other wrapable primitives, see bug:https://bugs.ecmascript.org/show_bug.cgi?id=3066
  • Tighten specification of when Array.prototype.sort is implementation defined
  • Revised @@unscopable semantics as per last TC39 meeting
  • Made it an error to reentrantly enter a generator via next/throw/return.
  • Further work on semantics of Generator return method in the context of yield*
  • The term “neutered” has been replaced with the term “detached”
  • Resolved bugs: 3147, 3142-3140, 3135-3133, 3131, 3128-3124, 3122-3120, 3117, 3115, 3111-3107, 3105, 3103-3098, 3096-3095, 3093-3092, 3090-3089, 3087-3082, 3080-3062, 3060-3016, 3012-3011, 3005, 2987, 2979, 2976, 2831, 2389, 2368, 1908, 523, 516, 513, 407, 91

Previous

Extending Pro PHP MVC

root (Edward Gerhold)

Class Diagram generated by phpStorm
Das mit PHPStorm vor einigen Tagen generierte Klassendiagram.
Class Diagram handdrawn with ArgoUML
Mit ArgoUML vorher  handgemalt, noch voller Fehler.