Comment dessiner une sphère 3D?

je veux dessiner une boule 3D ou une sphère en HTML 5.0 canvas. Je veux comprendre L'algorithme sur la façon de dessiner une sphère 3D. Qui peut partager ça avec moi?

17
demandé sur Peter O. 2009-10-18 17:09:16

4 réponses

vous aurez besoin de modéliser une sphère, et de lui faire varier les couleurs pour qu'au fur et à mesure qu'elle tourne, vous puissiez voir qu'elle n'est pas seulement une sphère, mais qu'elle est rendue.

autrement, une sphère dans l'espace, sans point de référence autour de elle ressemble à un cercle, si tout cela est d'une couleur solide.

Pour commencer, vous voulez essayer de dessiner un cercle avec des rectangles, qui est le principal primitif que vous avez.

Une fois que vous avez compris comment faire, ou créer un nouveau primitif, comme un triangle, en utilisant la méthode Path, et créer un cercle, alors vous êtes prêt à le déplacer en 3D.

la 3D est juste un truc, car vous allez prendre votre modèle, probablement généré par une équation, puis l'aplatir, comme vous déterminez quelles pièces seront vues, et puis l'afficher.

Mais, vous voulez changer la couleur des triangles basé sur quelle mesure ils sont à partir d'une source de lumière, ainsi qu'en fonction de l'angle de la partie de la lumière source.

c'est là que vous pouvez commencer à faire des optimisations, car si vous faites ce pixel par pixel alors vous raytracing. Si vous avez des blocs plus grands, et une source ponctuelle de lumière, et l'objet tourne mais ne se déplace pas autour alors vous pouvez recalculer comment la couleur change pour chaque triangle, alors il est juste une question de changer les couleurs pour simuler la rotation.

l'algorithme dépendra des simplifications que vous voulez faire, de sorte que vous gagnez de l'expérience revenir et demander, en montrant ce que vous avez fait jusqu'à présent.

voici un exemple de faire cela, et ci-dessous j'ai copié la partie 3D sphère, mais s'il vous plaît regardez le article.

function Sphere3D(radius) {
 this.point = new Array();
 this.color = "rgb(100,0,255)"
 this.radius = (typeof(radius) == "undefined") ? 20.0 : radius;
 this.radius = (typeof(radius) != "number") ? 20.0 : radius;
 this.numberOfVertexes = 0;

 // Loop from 0 to 360 degrees with a pitch of 10 degrees ... 
  for(alpha = 0; alpha <= 6.28; alpha += 0.17) {
   p = this.point[this.numberOfVertexes] = new Point3D();

   p.x = Math.cos(alpha) * this.radius;
   p.y = 0;
   p.z = Math.sin(alpha) * this.radius;

   this.numberOfVertexes++;
 }

 // Loop from 0 to 90 degrees with a pitch of 10 degrees ... 
 // (direction = 1)

 // Loop from 0 to 90 degrees with a pitch of 10 degrees ...
 // (direction = -1)

 for(var direction = 1; direction >= -1; direction -= 2) {
   for(var beta = 0.17; beta < 1.445; beta += 0.17) {

     var radius = Math.cos(beta) * this.radius;
     var fixedY = Math.sin(beta) * this.radius * direction;

     for(var alpha = 0; alpha < 6.28; alpha += 0.17) {
       p = this.point[this.numberOfVertexes] = new Point3D();

       p.x = Math.cos(alpha) * radius;
       p.y = fixedY;
       p.z = Math.sin(alpha) * radius;

       this.numberOfVertexes++;
     }
   }
 }
}
7
répondu James Black 2016-12-05 02:58:27

mise à Jour: Ce code est assez ancien et limité. Il y a des bibliothèques pour faire des sphères 3D maintenant:http://techslides.com/d3-globe-with-canvas-webgl-and-three-js/


il y a plus de dix ans, j'ai écrit une applet Java pour rendre une sphère texturée en faisant réellement le calcul pour déterminer où la surface de la sphère était dans la scène (pas en utilisant des triangles).

Je L'ai réécrit en JavaScript pour canvas et j'ai un démo rendu la terre comme une sphère:

texte alternatif http://sam.haslers.info/render-sphere/JavaScript + Toile.png

- je obtenir autour de 22 fps sur ma machine. Ce qui est à peu près aussi rapide que la version Java sur laquelle elle était basée renders at, si ce n'est un peu plus rapide!

maintenant, il y a longtemps que j'ai écrit le code Java - et c'était assez obtus - donc je ne me souviens pas vraiment comment ça marche, je l'ai juste porté en JavaScript. Cependant, il s'agit d'une version lente du code et je ne suis pas sûr que la version plus rapide était due à des optimisations dans les méthodes Java que j'ai utilisées pour manipuler les pixels ou à partir de speedups dans les maths qu'il fait pour trouver quel pixel à rendre à partir de la texture. Je correspondais aussi à l'époque avec quelqu'un qui avait une applet similaire qui était beaucoup plus rapide que la mienne, mais encore une fois je ne sais pas si l'une des améliorations de vitesse qu'ils ont eu serait possible dans JavaScript car il a pu compter sur les bibliothèques Java. (Je n'ont jamais vu leur code donc je ne sais pas comment ils ont fait.)

Donc être possible d'améliorer la vitesse. Mais cela fonctionne bien comme une preuve de concept.

Si vous êtes intéressé par la comparaison de la vitesse, les versions de Java sont ici:

ce sont des liens morts jusqu'à ce que je la prochaine mise à jour de mon site web

je vais essayer de convertir ma version plus rapide un certain temps pour voir si je peux obtenir des améliorations de vitesse dans la version JavaScript.

6
répondu Sam Hasler 2013-12-18 10:38:10

Vous pouvez essayer avec trois.la bibliothèque js, qui extrait beaucoup de code de la programmation WebGL de base. Inclure trois.js library dans votre html à partir de trois.js lib.

u peut utiliser le renderer canvas pour safari browser, webgl travaille pour chrome

s'il vous plaît trouver l' JS FIDDLE FOR SPHERE

var caméra, la scène, de matières, de la maille, la géométrie, le moteur de rendu

function drawSphere() {
    init();
    animate();

}

function init() {
    // camera 

    scene = new THREE.Scene()
    camera = new THREE.PerspectiveCamera(50, window.innerWidth / innerHeight, 1, 1000);
    camera.position.z = 300;
    scene.add(camera);

    // sphere object
    var radius = 50,
        segments = 10,
        rings = 10;
    geometry = new THREE.SphereGeometry(radius, segments, rings);
    material = new THREE.MeshNormalMaterial({
        color: 0x002288
    });
    mesh = new THREE.Mesh(geometry, material);

    //scene 
    ;
    scene.add(mesh);


    // renderer
    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

}


function animate() {
    requestAnimationFrame(animate);
    render();

}

function render() {

    mesh.rotation.x += .01;
    mesh.rotation.y += .02;
    renderer.render(scene, camera);


}

// fn callin
drawSphere();
4
répondu Bhupendra 2013-12-19 06:00:45

Eh bien, une image d'une sphère aura toujours une forme circulaire sur votre écran, donc la seule chose qui importe est l'ombre. Cela sera déterminé par l'endroit où vous placez votre source de lumière.

en ce qui concerne les algorithmes, traçage des rayons est le plus simple, mais aussi de loin le plus lent - donc vous ne voudriez probablement pas l'utiliser pour faire quelque chose de très compliqué dans un <CANVAS> (surtout compte tenu du manque d'accélération graphique disponible dans cet environnement), mais il pourrait être rapide ça suffit si tu veux juste faire une sphère.

0
répondu David 2009-10-18 13:19:16