PHP, HTML & JavaScript- Forum | | | | - 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 9 - |
| | HofK | Soeben habe ich die alpha Version mit Skalierung auf [...] gebracht. Auf [...] ist ein Video erneuert.
Für die Halbkugeln ist die Skalierung zwischen Start- und Endfunktion möglich.
Für die Kugel klappt die Skalierung aber nur zwischen den Standardwerten 0 und 1.
Einige Versuche mit Start- und Endfunktion führten zu immer unterschiedlichen Fehlpositionierungen. Dabei reagieren konvexe und konkave Funktionen unterschiedlich. Wenn die Abende jetzt wieder länger werden, muss ich da mal tiefer in die mathematische Theorie eintauchen. Eventuell gibt es eine simple Lösung - muss man nur finden.
Im Quelltext sind Teile der Versuche noch sichtbar, weil ich da eventuell wieder ansetze.
Momentan verfügbare Funktionen:
// u azimuth (start: x axis, counterclockwise) // for hemispheres: v polar (start: pole 0, end: equator 1), t time
stretchSouth,//function ( u, v, t )// stretch / compress south hemisphere in -y direction stretchNorth, //function ( u, v, t )// stretch / compress north hemisphere in +y direction endPole,//function ( u, t )// end angle ( to equator, per phi) startPole, //function ( u, t )// start angle ( from south- or north pole, per phi) scalePoleH,//function ( v, t )// scaling hemispheres from pole to equator ( is overwritten by scalePole )
// for sphere: v polar (start: south pole 0, end: north pole 1), t time
rAzimuthPole, //function ( u, v, t )// radius depending on location, equatorGap,//function ( u, t )// gap in relation to the radius squeeze,// function ( u, t )// 0 sphere to 1 flat circle moveX,//function ( u, v, t )// factor for radius, move in x direction moveY,//function ( u, v, t )// factor for radius, move in y direction moveZ,//function ( v, u, t )// factor for radius, move in z direction
endAzimuth,//function ( v, t )// end azimuth angle phi (per theta) startAzimuth,//function ( v, t )// starting azimuth angle phi (per theta) scaleAzimuth,//function ( u, t )// scaling between start and end of azimuth angle ( phi 0 .. 2*PI)
scalePole, //function ( v, t )// scaling between start and end of polar angle (theta -PI/2 .. PI/2 )
materialSouth,//function ( u, v, t )// material South materialNorth,//function ( u, v, t )// material North materialPlane,//function ( u, t )// material of extra south top or north bottom materialWedge,//function ( v, t )// material wedge side |
| | | | |
| | HofK | Bei der Positionierung der singulären Pole und Mittelpunkte von Boden und Deckel gab es noch Fehler im Zusammenhang mit der Anwendung der Funktionen.
Das Problem steckt in den Kugelkoordinaten. Die Pole haben zwar eindeutig einen Polwinkel theta ( -Pi/2, +Pi/2), aber da sie normal mittig liegen keinen bestimmten Azimut phi.
Bei der Berechnung mit Funktionen die u (und damit phi) als Argument haben, gibt es dann Probleme - unsinnige Ergebnisse.
Deshalb berechne ich einen sehr kleinen Kreis um die Mittelpunkte (x und z) und nehme den Mittelwert. Dazu muss, auch wenn nur einige Kugelkeile gewünscht werden, dort leider der vollständige Kreis geschlossen werden. Das erhöht die Auswahlabfragen, ist aber nicht zu vermeiden.
So gibt es nun aber auch in solchen Fällen sinnvolle Ergebnisse. Auf [...] ist die Version aktuell.
Die Berechnung geschieht im Zusammenspiel der Funktionen function setPoleVertex( south_north ) function setVertex( south_north ) function setPlaneCenterVertex( south_north )
|
| | | | |
| | HofK | Zwischendurch mal etwas Abwechslung.
Auf die Frage eines etwas hilflosen Anfängers hin [...] habe ich mein etwas älteres Beispiel zu raycast überarbeitet. Die deutschsprachigen Variablen Englisch ausgedrückt und die Kommentare wo sinnvoll übersetzt. Dazu noch eine Erweiterung zum besseren Verständnis des etwas schwierigen three.js Sachverhalts: Der Strahl kann dargestellt werden. [...]
Die alte Version bleibt erhalten. [...]
-----
Weiterhin ist THREEf auf Revision 87 umgestellt, [...] und enthält nun auch den vertexFaceNumbersHelper
Die Änderung zu r87 betrifft flatShading:
flatShading =document.getElementById( "flatShading" ).checked;
//shading =flatshading ? THREE.FlatShading : THREE.SmoothShadig; // old //.flatShading: true or false; // three.js r87
Also sehr einfach als Eigenschaft nur true oder false.
Beim Test habe ich eben festgestellt, dass die Sandbox nun auch auf Opera 48.0.2685.50 (PGO) und Chrome 61.0.3163.100 läuft! Hatte ich nicht mehr erwartet. Kann ich den Hinweis auf Firefox wohl löschen.
Auf GitHub muss THREEf noch erneuert werden. |
| | | | |
| | HofK | HofK (18.10.2017)
... Wenn die Abende jetzt wieder länger werden, muss ich da mal tiefer in die mathematische Theorie eintauchen. Eventuell gibt es eine simple Lösung - muss man nur finden. ...
Es bedurfte keiner tieferen mathematischen Forschungen. Die Lösung ist ganz einfach und fast so wie ich es schon hatte. Wenn man aber einen kleinen Fehler nicht bemerkt und in alle Varianten wieder mit einbaut, sieht es dunkel aus. Irgendwann kam die Erleuchtung, ich kann ziemlich hartnäckig sein. Die Anzahl der Fehlversuche ist nicht veröffentlichungsfähig - hab auch nicht mitgezählt.
Und so einfach geht es:
In der Funktion create():
if ( g.scaleH ) {
// ...HSE Hemisphere Start- End
g.scalePoleHSE = function( u, v, t ) { return 1 - ( g.startPole( u, t ) + ( g.endPole( u, t ) - g.startPole(u, t ) ) * g.scalePoleH( v, t ) ) }
} else {
// uses the decomposed scale function (South and North)
g.scalePoleS = function( u, v, t ) { return 2 * ( g.startPole( u, t ) + ( g.endPole( u, t ) - g.startPole( u, t ) ) * g.scalePole( v / 2, t ) ) }
g.scalePoleN = function( u, v, t ) { return 2 * ( 1 - g.endPole( u, t ) + ( g.endPole( u, t ) - g.startPole( u, t ) ) * ( 1 - g.scalePole( 1 - v / 2, t ) ) ) }
}
und dann in morphVertices( time ) die Berechnung des passenden Polwinkels theta .
In der Sandbox [...] jetzt verfügbar, und dort [...] momentan aktuelles Video 4.
|
| | | | |
| | HofK | Da mit indexed BufferGeometry nun wesentliche Sachen in THREEp funktionieren, bin ich dabei die sogenannte Dreieckssuppe, non indexed Buffer Geometry anzugehen.
Manch einer stürzt sich als Hobby auf riesige Puzzle, ich erzeuge mir ein systematisches Durcheinander und zwänge es dann per JavaScript in die benötigte Ordnung.
Mein Vorteil jetzt bei der zweiten Geometrie-Variante ist, dass ich anhand der ersten Variante sehr schnell die Korrektheit prüfen kann. So ist noch keine Grafik zu sehen, da nur create() existiert und die Positionen noch nicht berechnet sind, aber anhand einer Kontrollausgabe sieht man, dass es stimmt.
Berechnet werden die zu einem nur virtuell existierendem vertex gehörenden faces und die jeweilige Ecke a,b oder c des Dreiecks.
Natürlich gibt es wieder Indexrechnungen ( fIdx - face index) wo man sich muss.
if ( j === 0 ) {
if( i > bottomS ) { fIdx = uWed * ( i - 1 ) * ( i - 1 ) + w * ( 2 * ( i - 1 ) + 1 ) - uWed * bottomS * bottomS; ... if( i < topS ) { fIdx = uWed * i * i + w * ( 2 * i + 1 ) - uWed * bottomS * bottomS;
----
if ( j > 0 ) {
if( i > bottomS ) { fIdx = uWed * ( i - 1 ) * ( i - 1 ) + w * ( 2 * ( i - 1 ) + 1 ) + 2 * ( j - 1 ) - uWed * bottomS * bottomS; ... if( i < topS ) { fIdx = uWed * i * i + w * ( 2 * i + 1 ) + 2 * j - 1 - uWed * bottomS * bottomS;
----
if ( w === uWed - 1) {
if( i > bottomS ) { fIdx = uWed * ( i - 1 ) * ( i - 1 ) + w * ( 2 * ( i - 1 ) + 1 ) + 2 * ( i - 1 ) - uWed * bottomS * bottomS; ... if( i < topS ) { fIdx = uWed * i * i + w * ( 2 * i + 1 ) + 2 * i - 1 - uWed * bottomS * bottomS;
Mit
fPos = fIdx * 9;
vFace.push( fPos ); vPos.push( fPos + b );
fIdx ++;
werden die ermittelten Werte gespeichert. Hier im Beispiel die Ecke b (Konstante 3, drei Koordinatenwerte je Punkt) für die Position. Das hängt von der jeweiligen Anfangsecke und dem Drehsinn (Süd/ Nord unterschiedlich) ab und entspricht der Anordnung bei indexedBufferGeometry.
Dazu gibt es wieder ein "Konstruktionsblatt".
|
| | | | |
| | HofK | Zwischendurch mal etwas Abwechselung bei der Indexfummelei.
In einfachem Englisch gestellte Fragen verstehe ich, und so konnte ich dort [...]
eventuell etwas weiterhelfen.
Dazu habe ich nur ein vorhandenes Beispiel leicht verändert und Englisch gemacht.
Es kann unter [...] etwas weiter unten (bei Knoten) ausprobiert werden.
<!doctype html>
<html lang="de">
<head>
<title> picture ball </title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
<script src="../js/three.min.87.js"></script>
<script src="../js/OrbitControls.js"></script>
<script src="../js/THREEx.WindowResize.js"></script>
<div id="threejs" style="position: absolute; left:0px; top:0px"></div>
</body>
<script>
var boards = [];
var texture = [];
var matTexture = [];
init();
animate();
//...........................
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 45, window.innerWidth/ window.innerHeight,1, 300000 );
scene.add( camera );
camera.position.set( 0, 1500, 5000 );
renderer = new THREE.WebGLRenderer( { antialias:true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xeeeeee );
container = document.getElementById('threejs' );
container.appendChild( renderer.domElement );
THREEx.WindowResize( renderer, camera );
controls = new THREE.OrbitControls( camera, renderer.domElement );
texture[0] = new THREE.TextureLoader().load( "waterlily.png" );
texture[1] = new THREE.TextureLoader().load( "dahlia.jpg" );
texture[2] = new THREE.TextureLoader().load( "petunia.jpg" );
texture[3] = new THREE.TextureLoader().load( "frog.jpg" );
for (var z = 0; z < 4; z++) {
matTexture[z] = new THREE.MeshBasicMaterial( { color:0xffdd99, map: texture[z], transparent:true, opacity:0.8, wireframe:false} );
}
// ball
materialSph = new THREE.MeshBasicMaterial( { color: 0x0099dd, transparent: true, opacity: 0.8, wireframe:false } );
sphGeo = new THREE.SphereGeometry(1200, 8, 8);
sphere = new THREE.Mesh( sphGeo, materialSph );
scene.add( sphere );
// board for some things
materialBoard = new THREE.MeshBasicMaterial({color:0xdddddd, transparent:true, opacity:0.4, wireframe: true });
boardGeo = new THREE.PlaneGeometry(500,500);
picGeo = new THREE.PlaneGeometry( 200, 200 );
for (var i = 0; i < sphGeo.vertices.length; i++) {
board = new THREE.Mesh( boardGeo, materialBoard );// board for pictures etc.
pic = new THREE.Mesh( picGeo, matTexture[ i % 4 ] );
board.add( pic ) ;// add picture to the board
pic.position.x = -70;// position on the board
pic.position.y = 120;
boards.push( board );
scene.add( boards[ i ] );
boards[ i ].position.set( 1.3 * sphGeo.vertices[ i ].x , 1.3 * sphGeo.vertices[ i ].y, 1.3 * sphGeo.vertices[ i ].z );
}
}
function animate() {
requestAnimationFrame( animate );
for( var n = 0; n < boards.length; n ++ ) {
boards[ n ].lookAt( camera.position );
// or see https://discourse.threejs.org/t/add-marker-to-rotating-globe-object-help/1116/6
// boards[ n ].quaternion.copy( camera.quaternion );
}
renderer.render( scene, camera );
controls.update();
}
</script>
</html>
|
| | | | |
| | HofK | Kleiner Nachschlag zur discourse.threejs.org Hilfe (s.o.) [...]
<!doctype html>
<html lang="de">
<head>
<title> picture coil </title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
<script src="../js/three.min.87.js"></script>
<script src="../js/OrbitControls.js"></script>
<script src="../js/THREEx.WindowResize.js"></script>
<!-- https://github.com/hofk/THREEf.js/blob/master/THREEf_87/THREEf.js -->
<script src="../js/THREEf.js"></script>
<div id="threejs" style="position: absolute; left:0px; top:0px"></div>
</body>
<script>
var boards = [];
var texture = [];
var matTexture = [];
init();
animate();
//...........................
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth/ window.innerHeight,1, 100000 );
scene.add( camera );
camera.position.set( -200, 500, 12000 );
renderer = new THREE.WebGLRenderer( { antialias:true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xeeeeee );
container = document.getElementById('threejs' );
container.appendChild( renderer.domElement );
THREEx.WindowResize( renderer, camera );
controls = new THREE.OrbitControls( camera, renderer.domElement );
texture[0] = new THREE.TextureLoader().load( "waterlily.png" );
texture[1] = new THREE.TextureLoader().load( "dahlia.jpg" );
texture[2] = new THREE.TextureLoader().load( "petunia.jpg" );
texture[3] = new THREE.TextureLoader().load( "frog.jpg" );
for (var z = 0; z < 4; z++) {
matTexture[z] = new THREE.MeshBasicMaterial( { map: texture[z], transparent:true, opacity:0.8, wireframe:false} );
}
// coil generated with addon THREEf.js
var geometry = new THREE.Geometry();
geometry.createMorphGeometry = THREEf.createMorphGeometry;// insert the methode from THREEf.js
// apply the methode with some parameters
geometry.createMorphGeometry({
radius: 200,
height: 600,
radiusSegments: 18,
heightSegments: 80,
withBottom: true,
withTop: true,
centerX: function ( v, t ) { return 2 * Math.sin( 6 * Math.PI * v ) },
centerY: function ( v, t ) { return v * ( v + 10 ) },
centerZ: function ( v, t ) { return 2 * Math.cos( 6 * Math.PI * v ) }
});
var material = new THREE.MeshBasicMaterial( { color: 0x0099dd, transparent: true, opacity: 0.8, wireframe:false } );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
// board for some things
materialBoard = new THREE.MeshBasicMaterial({color:0xdd00dd, transparent:true, opacity:0.5, wireframe: false });
boardGeo = new THREE.PlaneGeometry(500,500);
picGeo = new THREE.PlaneGeometry( 160, 160 );
idx = 0;
for (var i = 0; i < geometry.vertices.length; i++) {
if ( i % 32 === 0) {
board = new THREE.Mesh( boardGeo, materialBoard );// board for pictures etc.
pic1 = new THREE.Mesh( picGeo, matTexture[ idx % 4 ] );
pic2 = new THREE.Mesh( picGeo, matTexture[ ( idx % 4 ) % 2 ] );
board.add( pic1 );// add picture to the board
board.add( pic2 );
pic1.position.x = -70;// position on the board
pic1.position.y = 120;
pic1.position.z = 20;
pic2.position.x = 80;
pic2.position.y = -120;
pic2.position.z = 20;
boards.push( board );
scene.add( boards[ idx ] );
boards[ idx ].position.set( 1.4 * geometry.vertices[ i ].x , geometry.vertices[ i ].y + 300, 1.4 * geometry.vertices[ i ].z );
idx ++;
}
}
}
function animate() {
requestAnimationFrame( animate );
for( var n = 0; n < boards.length; n ++ ) {
boards[ n ].quaternion.copy( camera.quaternion );
}
renderer.render( scene, camera );
controls.update();
}
</script>
</html>
-----------------------------------------------------------------------------------------
Bei meiner Indexrechnerei hat mich eine falsch gesetzte Klammer aufgehalten. Ständig darüber hinweg gelesen und lange nicht entdeckt. Das Ergebnis war nur in bestimmten Konstellationen falsch.
offensichtlich nicht korrekt
nun klappt es aber |
| | | | |
| | p.specht
| | | | XProfan 11Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'... | 08.11.2017 ▲ |
| |
| | HofK | Habe soeben den "Buddelkasten" auf den neuesten Stand gebracht. [...] In ihm kann man jetzt auch Gebilde aus der three.js "Dreieckssuppe" non indexed BufferGeometry erzeugen.
Auf dem Weg dahin war das uv Mapping einmal "eigen". Da kommt die Frage auf "Bug oder Feature?"
Manche Fehler sind einfach so "schön", dass man etwas daraus machen kann.
Noch fehlt bei non indexed die Berechnung der Normalen, bei indexed wird da momentan die three.js interne Funktion benutzt. Sie führt aber zu unschönen Nähten und muss auch noch ersetzt werden. Das gibt wieder eine ausgiebige Rechnerei wie bei THREEf. |
| | | | |
| | Georg Teles | In Sachen Grafik bin ich eine Niete aber verfolge den Thread schon länger und die Beispiele lassen echt viel Spielerei übrig, da kann ich auch nur staunen genial ! |
| | | | |
| | HofK | Georg Teles (11.11.2017)
In Sachen Grafik bin ich eine Niete ...
Meine Fähigkeiten bei Grafik sind auch eher bescheiden, hier wird nur etwas dreidimensionales Denken, etwas Mathematik in Form von 3D Geometrie und ein wenig dreidimensionales Rechnen (Vektorrechnung) benötigt. Und dann die Datenfelder mit den schönen Indexrechnereien.
Entscheidend ist die zugrunde liegende Bibliothek three.js, die die 3D Web-Grafik webGL erst handhabbar macht.
___________________________________________________
Die Berechnung der Normalen ging schneller als angenommen, da ich recht einfach von THREEf kopieren konnte und nur einige Änderungen anstanden.
Auch die Nähte sind schon fast weg. Im Bild erkennbar, dass am Äquator keine Naht sichtbar ist und an der Schnittstelle erster/letzter Keil nur noch auf der Nordhalbkugel.
Die Nahtglättung ist noch halbwegs überschaubar.
if (g.top > eqt) fehlt noch. Ebenso eine Prüfung auf optimierbarkeit der Zeilen.
Fünf mal } am Ende sind nicht gerade übersichtlich, da bieten sich dann abschließende Kommentare an. (Im Gesamtprogramm sind es hier dann 7 Klammern!) Durch die Faltung des Codes im Editor behält man (meistens) aber noch den Überblick. |
| | | | |
| | HofK | Nachdem auch die letzte Naht geglättet war, fiel mir ein, dass ich vorhatte bei non indexed BufferGeometry eine Explosionsdarstellung zu probieren.
Und das funktioniert dank der vorhandenen Daten denkbar einfach.
Da ich zur Berechnung der Vertex-Normalen die Normalen der Dreiecke (faces) benötigte, sind diese im Datenfeld g.faceNormals abgespeichert.
Addiert man nun zu jeder Ecke (vertex - Ortsvektor) ein Vielfaches dieser Dreiecks-Normalen, so treibt es die Dreiecke von der Mitte her auseinander.
Da die Dreiecke von Boden, Deckel und Keil identische Normalen haben (parallel!) werden sie gleichartig verschoben und bleiben so zusammen.
Man kann das nun auch in der Sandbox [...] ausprobieren. Die Funktion explode wirkt natürlich nur mit non indexed und nimmt lediglich den Zeitparameter t entgegen.
THREEp arbeitet nun mit der neuesten Revision 88 von three.js zusammen. Für THREEf werde ich explode nachrüsten. |
| | | | |
|
AntwortenThemenoptionen | 333.431 Betrachtungen |
ThemeninformationenDieses Thema hat 10 Teilnehmer: |