2009-10-06 5 views
2

J'apprends à utiliser Processing, et j'ai modifié l'un des exemples pour créer this applet. J'ai deux questions:Pourquoi mon application de traitement ne fonctionne-t-elle pas?

  1. Pourquoi les sphères sont oblates? Les sphères de l'exemple que j'ai découvert étaient belles et rondes.
  2. Pourquoi la lumière est-elle visible sur les bords extérieurs des sphères, lorsque la source ponctuelle se trouve entre elles?

Voici la source de ce petit programme:

int radius = 40; 
int spheredist = 320; 
int maxlevel = 7; 
float ecc = 0.28; 
int x1, x2, y1, y2; 

void setup() { 
    size(640, 360, P3D); 
    fill(204); 
    //smooth(); // makes spheres ugly 
    translate(width/2, height/2, 0); 
    x1 = -spheredist/2+radius; 
    x2 = spheredist/2-radius; 
    y1 = 
    y2 = 0; 
} 

void drawLightning(int x1_,int y1_,int x2_,int y2_,int lvl){ 
    if (lvl < maxlevel){ 
    int midx = (x1_ + x2_)/2; 
    int midy = (y1_ + y2_)/2; 
    float d = dist(x1_, y1_, x2_, y2_); 
    d *= ecc; 
    midx += random(-d, d); 
    midy += random(-d, d); 
    drawLightning(x1_, y1_, midx, midy, lvl+1); 
    drawLightning(midx, midy, x2_, y2_, lvl+1); 
    } else { 
    strokeWeight(10); 
    stroke(60,100,255,100); 
    line(x1_,y1_,x2_,y2_); 
    strokeWeight(1); 
    stroke(255); 
    line(x1_,y1_,x2_,y2_); 
    } 
} 

void draw() { 
    background(0); 
    noStroke(); 
    int brt = 200; 
    pointLight(brt/2, brt/2, brt/2, spheredist/2, -spheredist, spheredist); 
    ambientLight(brt/8,brt/8,brt/8); 


    if ((mouseX > width/4 && mouseX < width*3/4) && 
     (mouseY > height/2-radius && mouseY < height/2+radius)) { 
    pushMatrix(); 
    translate(width/2, height/2, 0); 
    pointLight(100, 100, 255, 0, 0, 0); 
    popMatrix(); 
    } 

    pushMatrix(); 
    translate(width/2 - spheredist/2, height/2, 0); 
    sphere(radius); 
    translate(spheredist, 0, 0); 
    sphere(radius); 
    popMatrix(); 

    if ((mouseX > width/4 && mouseX < width*3/4) && 
     (mouseY > height/2-radius && mouseY < height/2+radius)) { 
    pushMatrix(); 
    translate(width/2, height/2, 0); 
    drawLightning(x1,y1,x2,y2,0); 
    popMatrix(); 
    } 
} 
+0

Je ne vois pas comment quelqu'un peut dire sans voir votre code. –

+0

@Bart: Désolé, je m'habitue toujours à Processing. La page de l'applet génère un lien de code source, que je pensais afficher la source, et que je pensais être la convention pour publier ses croquis. Je vais modifier la question pour l'inclure ici. – PaulMcG

+0

@Paul McGuire: Merci. Je ne savais pas qu'un lien vers la source était là. Je n'ai pas essayé d'exécuter l'applet car les applets de traitement ne peuvent pas être exécutées avec le plugin Java IcedTea pour Firefox sur ma machine Linux 64 bits, malheureusement. Je regarderai le code plus tard. –

Répondre

3

Le lisse La fonction ne fonctionne pas bien dans ce cas parce que vous avez des polygones adjacents. C'est un peu difficile à suivre sans une image, mais pensez à un pixel qui est sur le bord entre deux polygones. Pour l'exemple, disons que l'arrière-plan est (0,0,0) et les polygones sont (255,255,255). Le premier polygone dessine et frappe ce pixel. Il en couvre la moitié, il calcule donc 0,5 * (0,0,0) + 0,5 * (255,255,255) et enregistre (126,126,126) la nouvelle valeur pour ce pixel. Le deuxième polygone dessine. Il couvre également la moitié du pixel, donc il calcule 0,5 * (126,126,126) + 0,5 * (255,255,255) et enregistre (190,190,190). Ce n'est pas correct parce que les deux polygones doivent avoir chacun une moitié différente et avoir une couleur de (255,255,255). Mais vous ne pouvez pas comprendre cela si vous dessinez chaque polygone individuellement et n'enregistrez aucune information de couverture entre les deux.

Les cartes graphiques modernes supportent quelque chose appelé multisample antialiasing. Cela permet d'économiser des informations sur la partie du pixel couverte par le premier polygone. Le traitement essaie de simuler ceci sans le support matériel, donc il utilise un truc qui fonctionne plutôt bien quand vous n'avez pas de primitives attenantes, mais qui tombe en morceaux quand vous le faites.

En ce qui concerne l'aplatissement. Par défaut, le traitement remplit la fenêtre entière et votre taille n'est pas carrée. La façon la plus simple de gérer cela est d'utiliser la fonction ortho pour rendre le ratio d'aspect de votre caméra carré. Essayez d'ajouter ceci à votre configuration:

ortho (-360,360, -180,180, -10,10);

+0

Merci - le rapport d'aspect fixe l'aplatissement des sphères. ortho aide, mais maintenant je reçois un rétro-éclairage étrange. – PaulMcG

0

A propos des beaux bords arrondis, essayez d'appeler la méthode lisse() dans la configuration():

void setup() { 
    // ... 
    smooth(); 
    // ... 
} 
+0

Merci pour votre réponse, mais cela ne fait qu'empirer les choses. Les triangles qui constituent les surfaces des sphères deviennent visibles et la lumière montre "à travers" les sphères. – PaulMcG

+0

Ah oui, lisse() est AFAIK seulement utilisé pour le dessin 2D dans le traitement. Il ne m'est pas venu à l'esprit que tu faisais un dessin en 3D. Malheureusement, je n'ai jamais fait beaucoup de 3D dans le traitement. –

Questions connexes