| |
|
|
- Seite 1 - |
|
HofK | Auf einen heißen Tipp von IF hin, habe ich mir mal three.js [...] angeschaut. Da [...] (ganz unten) die ersten Resultate. |
|
|
| |
|
|
| |
|
- Seite 41 - |
|
|
HofK | |
|
| |
|
|
|
HofK | Im Anfängerbeispiel gibt es jetzt im Schritt 2 Bienen. Eine Biene ist ein Klone der anderen. Im Schritt 4 jetzt ein Video als Textur. Das Video läuft nur in diesem Schritt, ansonsten sitzt der Vogel nur reglos da. Bei Firefox gibt es zuweilen Startschwierigkeiten, F5 hilft.
Im Schritt 13 bekommen die Bienen ihre Wabe. Sie ist mit InstancedMesh realisiert. Nur in diesem Schritt schließen und öffnen sich die Waben.
|
|
|
| |
|
|
|
HofK | Bei der CPU-Simulation funktioniert nun das Laden von Assembler-Dateien.
Unter [...] kann man zum Test einige Assemblerdateien finden und herunterladen. Die Programme laufen aber keineswegs fehlerfrei, da noch nicht alle Befehle überprüft und entsprechend korrigiert wurden. Das ist noch viel Detailarbeit und kostet Zeit.
Je mehr ich in sehr spezifische Dinge komme wird deutlich, dass Reengineering anspruchsvoller ist als eine Sache aus dem Stand zu programmieren.
Dabei habe ich ein Programm als Grundlage, dass ich vor Jahren selbst erstellt habe.
Das Problem ist, dass man sich gleichzeitig mit zwei sehr unterschiedlichen Umgebungen und Sprachen auseinandersetzen muss und man zusätzlich immer an der Vorlage klebt. Das wird zum Problem, wenn eine Sache sich in der anderen Umgebung überhaupt nicht in dieser Art und Weise umsetzen lässt.
Mein Divisionsproblem!
Da verwundert es nicht, wenn man hört, dass einige Kernprogramme im Bankenwesen immer noch in COBOL laufen. Dafür gibt es kaum noch aktive Programmierer aus der alten Zeit, man hat bereits nachgeschult. |
|
|
| |
|
|
|
HofK | Zwischendurch mal wieder etwas anderes.
Die Verformung von grundlegenden Geometrien wie Rechteck und Cylinder ermöglicht interessante Formen.
Auf eine Frage hin [...] hat prisoner849 alias Paul West wieder einmal einen cleveren Lösungweg angeboten. Ist in der Sammlung [...]
Eine wesentlich einfachere Variante zur Veränderung der Positionen habe ich als Antwort auf eine andere Anfrage erstellt. Ein flach gedrückter Torus. [...]
[...]
Der Fisch von prisoner849 brachte mich auf die Idee der Verallgemeinerung.
Basis ist hier ein Zylinder. Als ich die Kappen hinzufügen wollte, bin ich auf ein Problem gestoßen. Die Mittelpunkte der Kreise sind mehrfach definiert. Auf eine Anfrage [...] gab es bisher keine Resonanz. Also habe ich statt des Zylinders wieder eine benutzerdefinierte Geometrie erzeugt. Diesmal aber als eigenständige BasicGeometry - abgeleitet von CylinderGeometry und stark reduziert.
function BasicGeometry( radialSegments, heightSegments, withTop, withBottom ) {
let indices = [];
let uvs = [];
let index = 0;
let indexArray = [];
let groupStart = 0;
let groupCount = 0;
for ( let y = 0; y <= heightSegments; y ++ ) {
let indexRow = [];
let v = y / heightSegments;
for ( let x = 0; x <= radialSegments; x ++ ) {
uvs.push( x / radialSegments, 1 - v );
indexRow.push( index ++ );
}
indexArray.push( indexRow );
}
let a, b, c, d;
for ( let i = 0; i < radialSegments; i ++ ) {
for ( let j = 0; j < heightSegments; j ++ ) {
a = indexArray[ j ][ i ];
b = indexArray[ j + 1 ] [ i ];
c = indexArray[ j + 1 ][ i + 1 ];
d = indexArray[ j ] [ i + 1 ];
indices.push( a, b, d );
indices.push( b, c, d );
groupCount += 6;
}
}
g.addGroup( groupStart, groupCount, 0 );
groupStart += groupCount;
let verticesCount = ( radialSegments + 1 ) * ( heightSegments + 1 )
if ( wTop ) generateCap( true );
if ( wBtm ) generateCap( false );
g.setIndex( new THREE.BufferAttribute( new Uint32Array( indices ), 1 ) );
g.setAttribute('position', new THREE.BufferAttribute( new Float32Array( verticesCount * 3 ), 3 ) );
g.setAttribute('uv', new THREE.BufferAttribute( new Float32Array( uvs ), 2 ) );
function generateCap( top ) {
let groupCount = 0;
uvs.push( 0.5, 0.5 );
const centerIndex = index;
for ( let x = 0; x <= radialSegments; x ++ ) {
uvs.push( 0, 0 );
index ++;
}
index ++;
for ( let x = 1; x <= radialSegments; x ++ ) {
const c = centerIndex;
const i = centerIndex + x;
if ( top ) {
indices.push( i, i + 1, c );// face top
} else {
indices.push( i + 1, i, c );// face bottom
}
groupCount += 3;
}
g.addGroup( groupStart, groupCount, top ? 1 : 2 );
groupStart += groupCount;
verticesCount += radialSegments + 2;// with center
}
}
Die Sache ist noch in Arbeit, aber es ergibt sehr vielfältige Formen.
So einfach definiert man die Form:
// no flat smooth
// ext string - with top: x, f, s | with bottom: x, f, s | connected: x, c
const design = [
// max vert, ext, angle, 0 first, ... , max radial
[ 40,"ffc",314, 0, 20, 36, 45 ],
// center x, y, z, distance to center orthogonal-radial
[ 0.0, 0.4, 0.0, 1.0, 1.0, 0.8, 0.8 ],// top, max vert.
[ 0.1, 0.0, 0.1, 1.2, 0.6, 0.6, 0.7 ],// some centers x,y,z
[ 0.0, -2.0, 0.0, 0.3, 0.4, 0.3, 0.5 ],
[ 0.0, -3.0, 0.4, 0.6, 0.8, 0.7, 0.7 ],// bottom
];
const geo = Curved2Geometry( design );
Hier müssen noch die uv Werte der Kappen berechnet werden. |
|
|
| |
|
|
|
HofK | Wenn man erst einmal den richtigen Ansatz gefunden hat, ist die Rechnug selbst kein Problem.
Dabei enthält das Array pts für jede vertikale Schicht ([ 0 ] die obere) ein Array mit den auf die jeweilige im 3D Raum liegende Ebene bezogenen Koordinaten. Diese wurden zur Bestimmung aller Positionen vorher bereits berechnet. uMax bzw. vMax sind dabei die maximal aufgetretenen Werte in der oberen Schicht.
Für den Boden läuft es analog.
|
|
|
| |
|
|
|
HofK | Wieder zurück zur CPU Simulation brachten einige Versuche mit der Addition in der ALU merkwürdige Ergebnisse. Das letzte Bit blieb teils leer und damit waren die Resultate natürlich falsch.
Nach vielen console.log( ) Ausgaben stellte ich fest, dass immer bei Bit 0 etwas schief lief. Die runde Null hat so öfters ihre "Ecken und Kanten".
Dann bekam ich heraus, dass ein Ergebnis-String der 9 Bit ALU eine Länge von 18 hatte. Auch bei Bit 0!
Also alle in diesem Zusammenhang benutzten Befehle und Funktionen unter die Lupe genommen. Dabei stieß ich auf right( s, n ).
Um den Quellcode vergleichbar zu halten und auch um die Übernahme von XProfan nach JavaScript überschaubar zu gestalten, habe ich wie weiter oben beschrieben, einige Funktionen von XProfan in JS nachgebildet.
So auch
Das mit -n findet man dort: [...]
Im Test war es auch ok.
Was ich nicht bedacht und geprüft hatte, war die doch sehr spezielle Zahl 0, obwohl man das immer machen sollte.
Ich kann mich gut erinnern, das der Einstieg in die höherer Mathematik mit dem Beweis begann, dass es nur eine Null gibt. Erscheint dem "normalen" Menschen selbstverständlich und nicht der Rede wert. Gab seinerzeit auch erst großes Erstaunen was das soll. Hinterher war es klar - wie meist immer bei solchen Dingen.
In der entsprechenden XProfan Schleife
R9$ = space$(8-bit%) + r$ + right$(R9$, bit%)' ... als das Resultat-Bit
wird anfangs bit% Null.
Bei XProfan right$ kommt ein Leerstring wie gewünscht.
Bei der JS right Funktion bedeutet aber -0 auch 0 und s.substr( 0 ) liefert den ganzen String. Der selbst ist zuerst mit Leerzeichen gefüllt. Dadurch versteckt er sich gut, nur die Länge 18 hat ihn verraten.
Man muss die 0 "behandeln".
Ich bin mir sicher, das war nicht der letzte Stolperstein (oder doch -felsen?) bei der Portierung.
|
|
|
| |
|
|
|
p.specht
| Immerhin könntest du den Stolperstein nun in 3D modelieren |
|
|
| XProfan 11Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'... | 01.04.2021 ▲ |
|
|
|
|
HofK | Der nächste Stolperstein war die zeitlich unbegrenzte Unterbrechung des Programmlaufs über den Startknopf. Nach einigen Fehlversuchen und ein wenig Umgruppierung im Code konnte ich das aber durch einer einfache Zeitangabe verwirklichen. Der Takt wird unendlich ausgedehnt.
Eine weitere Etappe ist damit geschafft. Das erste Testprogramm ist voll funktionstüchtig. Es ist mehrfach startbar.
Man kann Zahlen eingeben, zwischendurch pausieren und den Takt mit dem Schieberegler verändern. Die Summe erscheint im I/O-Protocol.
Dort ausprobieren: [...]
Die Assemblerdatei lokal speichern. Dort zu finden. [...]
Und hier:
|
|
|
| |
|
|
|
HofK | Der Fisch entwickelt sich.
Problem ist es, eine passende Textur zu basteln. Dazu muss man ein Foto entsprechend verzerren.
Eine Anfrage auf discourse [...] hatte keine Resonanz, aber zufällig war in einem anderen Beitrag [...] ein Link, der das Problem löst. [...]
Zwar nicht perfekt, da etwas mühsam und nicht 100% exakt hinzubekommen, aber für meine Zwecke ausreichend.
Fischmaul und Flossen fehlen noch.
Da zappelt der Fisch (kurzes Video):
Herunterladen |
|
|
| |
|
|
|
HofK | Die zweifach kurvige Geometrie ist fertiggestellt.
Curved2Geometry
Man definiert mit einige 3D Punkten die Mittelkurve und für einige Winkel die orthogonal radialen Abstände der Hülle von diesen Punkten.
Mit der Angabe der maximalen Werte bestimmt man die vertikale und radiale Feinheit der Darstellung.
Mit einem Definitionsstring aus drei Zeichen legt man fest, ob Kappen generiert werden sollen und ob diese "flat" oder "smooth" sein sollen. Das dritte Zeichen ermöglicht das radiale verbinden ohne Naht oder eine symmetrische Geometrie. Für die symmetrische Geometrie muss der letzte Winkel 180° sein.
3 Zeichen 'string' = 'withTop withBottom conncted/symmetric'
withTop/Bottom: x, f, s = no, flat, smooth conncted/symmetric: x, c, s = no, connected, symmetric
Mit der Angabe von Abweichungen zu den definierten Punkten der Mittelkurve lässt optional eine sehr organische Bewegung der Geometrie erzeugen.
Die Parameter und Werte werden in einer Designmatrix zusammengefasst. Das erste Zeile dieser Matrix ist ein Array der Parameter, die weiteren Zeilen enthalten in jeweils einem Array die Werte.
Auf diese Weise kann man die Werte in Spalten genau unter den Parametern platzieren.
const design = [
// first0, .. angles .. , max angle
[ maxVert.,'string', maxRadial, 0, phi1, phi2, ... phimax ] ,
// center x,y,z distance to center orthogonal-radial
[ x, y, z, r0, r1, r2, ... r ],// top
...
[ ]// bottom
];
Ein Beispiel:
Da bei beliebig definierten Mittelpunkten und Winkeln und ebenso beliebigen maximalen Werten der Feinheit keine exakte Übereinstimmung möglich ist, werden die jeweils nächstgelegenen Werte ermittelt und für die Berechnung benutzt.
Die optionalen Werte der Abweichungen sind in entsprechender Struktur zu den Mittelpunkten zu notieren. Aus diesen Werten werden auf einer Kurve weitere Punkte erzeugt. Deren Anzahl ist in einem gesonderten Parameter anzugeben.
Die Bewegung wird mit Hilfe der Methode geometry.morph( geometry.cPts ) erzeugt.
g.cPts = []; // array of array of morphed g.cPoints
wobei
g.cPoints = new THREE.CatmullRomCurve3( g.dsgnCenters, false ).getSpacedPoints( g.vertical );
Dort ansehen: [...] => [...]
Quelltext auch auf Github [...] und discourse [...] |
|
|
| |
|
|
|
HofK | Eine entscheidende Etappe der CPU-Simulation ist erfolgreich absolviert.
Das rekursive Quicksort funktioniert.
Es benutzt zwar nicht alle Befehle, aber ist doch schon recht komplex. Die problematischen Befehle MUL und DIV werden nicht benötigt.
Die Auswahl einer Eingabedatei ist möglich, funktioniert aber bedingt durch die Vorgaben der Browser etwas anders als unter Windows/Desktop. Dort wird der Dateiname aus dem Edit benutzt, im Browser muss man per select eine lokale Datei selbst auswählen.
Speichern in eine lokale Datei ist im Browser nicht möglich. In anderen Programmen habe ich das Problem derart gelöst, das die Werte über ein textarea in die Zwischenablage kopiert werden. Siehe z.B. [...]
Also den Code entsprechend übernommen, getestet - die Zwischenablage ist leer!
In der Konsole/Warnungen findet man
Ist wohl wieder mal ein Sicherheitsfeature. Nur dumm, dass all diese Dinge den normalen Nutzer ausbremsen, aber die Ganoven nicht davon abhalten über die immer wieder neu entdeckten Schlupflöcher ihr Unwesen zu treiben.
Also werde ich analog zum Input ein copy unter das Feld setzen. Der Nutzer muss dann eben nochmal klicken, wenn er das Ergebnis nicht nur im RAM haben möchte.
Ausprobieren: [...]
Dateien unter [...]
Vor Run input.hcx selektieren!
Quicksort rekursiv.txt
|
|
|
| |
|
|
|
HofK | Mittlerweile klappt nun kopieren in die Zwischenablage.
Mit der Farbänderung der Buttonschriftfarbe von "to Clipboard" wird signalisiert, dass die Speicherung STO erfolgt ist und der Button betätigt werden kann. Damit ist ein Browser zufrieden - Firefox!!!
Bei Chrome keine Fehlermeldung, aber es passiert nichts.
Irgendwie verliert man da die Lust für Browser etwas zu programmieren. Weil Chaos herrscht soll man für jeden Browser eine Extrawurst braten.
Dazu habe ich keine Lust und werde mich fortan auf Firefox beschränken und das vermerken. Aber auch da kann es passieren, das nach einiger Zeit nichts mehr funktioniert. Wie beim Video, wo alte Beispiele nicht mehr laufen, weil seit einiger Zeit auch hier ein Nutzerbutton Pflicht ist. War der in alten Beispielen (z.B. in meiner Sammlung von Discourse ) nicht da, funktioniert das heruntergeladene Beispiel nicht mehr.
Das Chaos ist sogar "sauber" dokumentiert: [...]
Zitat: "The clipboard and other APIs involved here are evolving rapidly, so there are variations among browsers in how they work."
Die "neue" Clipboard API mag ich gar nicht erst testen,
Wer also probieren möchte - bitte Firefox benutzen. [...]
Damit der Test schnell geht den Schieber "clock speed" ganz nach rechts schieben und eine kleine input - Datei wählen, z.B. inputA.hcx von [...] |
|
|
| |
|
|