Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les forums > Programmation > Autres langages > Atelier Cod'Art > Lecture du sujet

Atelier Cod'Art

Vous devez être inscrit pour pouvoir poster des messages

Page : Précédente  1  2  3  ...  11  12  13  14 
Auteur Message
1 visiteur sur ce sujet (1 anonyme)
Page : Précédente  1  2  3  ...  11  12  13  14 
Hors ligne lastsseldon # Posté le 02/06/2008 à 01:34:47
Avatar
Groupe : Membres
Reprise du dernier message de la page précédente :
Très bonne idée :)

Une implémentation naïve en Forth (pour changer un peu) reposant sur le triangle de Pascal :

Code : Autre
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
: nl     newline type ;
: star   [char] # emit ;
: spaces 0 ?do space loop ;
: even   2 mod 0= ;
: .even  even if space else star then ;

: out? ( y x -- ? )
    dup 0= >r = r> or ;
: pascal ( y x -- n )
    2dup out?
    if 2drop 1
    else
        swap 1- swap 2dup recurse >r
        1- recurse r> +
    then ;

: print-line ( i -- )
    dup 1- swap 0 ?do
        dup i pascal .even
        space
    loop drop ;

: sierpinski ( size -- )
    dup 1 do
        nl
        dup i - spaces
        i print-line
    loop drop ;


Code : Console
~/Documents/Forth> gforth sierpinsky.fs                                                             
redefined nl  redefined spaces  Gforth 0.6.2, Copyright (C) 1995-2003 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
17 sierpinski  
                # 
               # # 
              #   # 
             # # # # 
            #       # 
           # #     # # 
          #   #   #   # 
         # # # # # # # # 
        #               # 
       # #             # # 
      #   #           #   # 
     # # # #         # # # # 
    #       #       #       # 
   # #     # #     # #     # # 
  #   #   #   #   #   #   #   # 
 # # # # # # # # # # # # # # # #  ok


[gnustep,etoile,Io ,haskell, erlang ]
 
Hors ligne diacred # Posté le 02/06/2008 à 06:37:32
Pastafarianism rules.
Avatar
Groupe : Membres
:)

En remplacant le contenu des prints (en rajoutant des espaces), on arrive aussi a trouver des triangles equilibres niveau hauteur largeur.
Par contre arrive pas a depasser 128 comme puissance de deux, mon ecran suis pas :p

Edit : Ca a l'air assez complexe d'un point de vue syntaxique le Forth.
Édité le 02/06/2008 à 06:39:29 par diacred

Clavier Qwerty, pas d'accents. Donc... Désolé pour les fautes.
Capoeira... is life :), site de l'assoc' ©Diacred ... L'amour est la principale cause de l'achat d'alcool :-°
... Et s'il t'arrive de croiser Alice, Agnès ou Cassandra; rappelle leur que leur nom rime avec syphilis, herpès et sida.
 
Hors ligne lastsseldon # Posté le 22/07/2008 à 22:50:43
Avatar
Groupe : Membres
Bonsoir,

Un petite expérience avec le dithering : Le principe est de représenter une image en niveau gris en utilisant uniquement deux couleurs, le noir et le blanc (la nuance se fait donc grâce à la juxtaposition des pixels).

marylinlena

Code : OCaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
let ( @$ ) f x = f x

(* Algo *)
let dither mat =
  let w, h = Array.length mat, Array.length mat.(0) in
  let points = [ (1, 0), 7 ; (-1, 1), 3 ; (0, 1), 5 ; (1, 1), 1 ] in
  for x = 0 to w - 1 do
    for y = 0 to h - 1 do
      let old_color = mat.(x).(y) in
      let new_color = if old_color < 127 then 0 else 255 in
      let quant_error = (old_color - new_color) / 16 in

      mat.(x).(y) <- new_color ;
      let f ((dx, dy), factor) =
        let px, py = x + dx, y + dy in
        if px >= 0 && px < w && py >= 0 && py < h
        then mat.(px).(py) <- mat.(px).(py) + factor * quant_error in
      List.iter f points
    done
  done

(* IO *)
open Images
open OImages

let load_img filename =
  let img = rgb24 @$ load filename [] in
  let w, h = img#width, img#height in
  let mat = Array.make_matrix w h 0 in
  for x = 0 to w - 1 do
    for y = 0 to h - 1 do
      let pixel = img#get x y in
      let gris = (pixel.r + pixel.g + pixel.b) / 3 in
      mat.(x).(y) <- gris ;
    done ;
  done ;
  mat

let save_img src dst mat =
  let img = rgb24 @$ load src [] in
  for x = 0 to img#width - 1 do
    for y = 0 to img#height - 1 do
      let gris = max 0 (min 255 mat.(x).(y)) in
      img#set x y {r=gris; g=gris; b=gris}
    done
  done ;
  img#save dst None []

let () =
  let filename = "marylin.jpg" in
  let img = load_img filename in
  dither img ;
  save_img filename "output.jpg" img ;


[gnustep,etoile,Io ,haskell, erlang ]
 
Hors ligne zulon # Posté le 23/07/2008 à 08:52:17
The shrieker shrieks.
Avatar
Groupe : Membres
Wow, c'est vachement bien réussi :p . La deuxième image n'utilise vraiment que du noir et du blanc ? C'est assez impressionnant.
Mais comment as-tu trouvé les bonnes valeurs pour points ? Par l'expérimentation, ou via des calcules compliqués ?

(heureusement que tout le monde n'oublie pas Cod'Art, je trouve vraiment rien à montrer moi :-° ).
Hors ligne lastsseldon # Posté le 23/07/2008 à 13:57:07
Avatar
Groupe : Membres
Tout est dans le lien, c'est assez simple comme algo en fait :) .

Floyd-Steinberg dithering


[gnustep,etoile,Io ,haskell, erlang ]
 
Hors ligne lastsseldon # Posté le 24/07/2008 à 14:37:20
Avatar
Groupe : Membres
Je viens de réécrire mon code Forth précédent pour qu'il soit moins naif :

Code : Autre
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
0 value size
0 value acc
0 value addr
: init-size    dup 1+ to size ;
: init-acc     0 to acc ;
: init-addr    here to addr ;
: init         init-size init-acc init-addr ;

: get          cells + @ ;
: add          dup acc + swap to acc ;
: +line        init 0 do dup i get add , loop drop acc , addr size ;

: even?        2 mod 0= ;
: .bin         if space else ." #" then ;
: print-line   0 do dup i get even? .bin loop drop ;

: iter         0 do 2dup print-line cr +line loop 2drop ;
: sierpinky    here 1 , 1 rot iter ;

16 sierpinky bye


Et de coder une variante du dithering : Cette fois, le principe consiste à utiliser des cercles plus ou moins grand pour représenter les nuances de gris. Le résultat est intéressant, surtout si on se place à une certaine distance de l'image (ou si on la redimmensionne pour qu'elle soit plus petite) : les cercles disparaissent !

einstein

Halftone

Code : OCaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
let ( @$ ) f x = f x
let uncurry f (a, b) = f a b

let pi = 4.0 *. atan 1.0
let matrix_length mat = Array.length mat, Array.length mat.(0)

let resize (new_h, new_w) img =
  let out = Array.make_matrix new_w new_h (0, 0) in
  let w, h = matrix_length img in
  let adjust (x, y) = (new_w * x) / w, (new_h * y) / h in
  for y = 0 to h - 1 do
    for x = 0 to w - 1 do
      let x', y' = adjust (x, y) in
      let color = img.(x).(y) in
      let old, nb = out.(x').(y') in
      out.(x').(y') <- (old + color, nb + 1)
    done
  done ;
  Array.map (Array.map (uncurry ( / ))) out

(* IO *)
open Images
open OImages

let load_img filename =
  let img = rgb24 @$ load filename [] in
  let h, w = img#height, img#width in
  let mat = Array.make_matrix w h 0 in
  for y = 0 to h - 1 do
    for x = 0 to w - 1 do
      let pixel = img#get x y in
      let gris = (pixel.r + pixel.g + pixel.b) / 3 in
      mat.(x).(y) <- gris ;
    done ;
  done ;
  mat

open Cairo
let render size img =
  let w, h = matrix_length img in
  let new_h, new_w = h / size, w / size in
  let resized = resize (new_h, new_w) img in

  let surface = Cairo.image_surface_create Cairo.FORMAT_ARGB32
                    ~height: (h - size) ~width: (w - size) in
  let ctx = Cairo.create surface in
  Cairo.set_source_rgb ctx ~red: 0.0 ~green: 0.0 ~blue: 0.0 ;

  let draw_circle x y radius =
    Cairo.arc ctx
              ~xc: x
              ~yc: y
              ~radius: radius
              ~angle1: 0.0
              ~angle2: (2.0 *. pi) ;
    Cairo.fill ctx in

  let adjust (x, y) = (float @$ w * x) /. (float new_w),
                      (float @$ h * y) /. (float new_h) in
  for y = 0 to new_h - 1 do
    for x = 0 to new_w - 1 do
      let x', y' = adjust (x, y) in
      let color = 255 - resized.(x).(y) in
      let radius = (float @$ size * color) /. 255.0 in
      draw_circle x' y' radius
    done
  done ;
  surface

let () =
  let filename = "einstein.jpg" in
  let img = load_img filename in
  let surface = render 8 img in
  Cairo_png.surface_write_to_file surface "output.png"


[gnustep,etoile,Io ,haskell, erlang ]
 
Hors ligne Krankkatze # Posté le 16/09/2008 à 20:43:12
Ob-la-di, Ob-la-da
Avatar
Groupe : Membres
J'ai pour ma part codé un flocon de Koch avec Tkinter (trois semaines après mon arrivée, ma famille d'accueil cède et passe le vieil ordinateur familial sous Linux. J'étais tout heureux de retrouver Python et puis j'avais trouvé mon algo en bio alors je l'ai implémenté avec la première lib que j'ai installée). Deux choses : d'abord c'est très chiant, le truc est hyper long. J'ai pompé le truc de Last avec t.speed('fastest') mais il faut quand même attendre et c'est pas marrant donc si quelqu'un a une idée de comment pas attendre du tout ca serait cool. Et deuxièmement je sais pas comment redimentionner cette stupide fenêtre, mais comme ca me désole de faire un truc tout riquiqui et ben je fais quand même mon truc sur 729 pixels de large. Il faut donc agrandir la fenêtre, si quelqu'un sait comment pas avoir à le faire pareil je serais heureux de tirer un enseignement de son savoir.

Mon algo est un peu bizarre je suppose, étant donné que je pars de l'élément de base (un segment de longueur 729/(iterations*3) que j'écris "F" (pour t.forward() ) dans une chaîne, et ensuite à chaque itération je fais "a = a+"L"+a+"R"+a+"L"+a", c'est à dire qu'en gros, la nouvelle chaine est l'ancienne chaine, tourner à gauche (t.left() ), l'ancienne chaîne, tourner à droite (t.right() ), l'ancienne chaîne, tourner à gauche, l'ancienne chaîne.
Ensuite j'interprête ma chaîne.

Voilà le rendu avec 6 itérations (c'est le max que je peux faire vu que ca me fait 1 pixel par segment. Sinon il faut que vous ayez un écran de plus 2147 pixels de large, chaud) :

Image utilisateur


Et voilà le code :

Code : Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import turtle as t

t.speed('fastest')

a = "F"
l = 729
iterations = 6
a = "F"
i = 0
while i < iterations:
	l /= 3
	i += 1
	a = a+"L"+a+"R"+a+"L"+a

t.up()
t.left(180) # Je place mon curseur
t.forward(300)
t.left (180)
t.down()

for i in a:
	if i == "F":
		t.forward(l)
	elif i == "L":
		t.left(60)
	else:
		t.right(120)
t.up()
t.forward(2000) # Je vire mon curseur.

raw_input()

Vous pouvez le télécharger en version user-friendly (c'est à dire avec "Drucken Sie auf Enter um das Programm zu beenden. " à la fin au lieu d'un raw_input() vide, c'était pour faire genre auprès de ma famille d'accueil et tout) ici.
 
Hors ligne wgmpgp # Posté le 16/09/2008 à 20:58:28
Rotoclap true fan
Avatar
Groupe : Membres
Tu devrais tenter de faire pareil avec une lib genre Cairo qui supporte des tailles de lignes < 1px (vectoriel, toussa). En plus turtle (et pas Tkinter), c'est moche.
 
Hors ligne Krankkatze # Posté le 17/09/2008 à 18:56:12
Ob-la-di, Ob-la-da
Avatar
Groupe : Membres
Comment on peut supporter des tailles de lignes < 1 px ? enfin aucun intérêt vu qu'on peut pas l'afficher de toute manière, si ? :-'
 
Hors ligne coucou747 # Posté le 17/09/2008 à 19:03:18
Avatar
Groupe : Membres
krankkatze, tu peux zoomer dessus ?
Hors ligne Krankkatze # Posté le 17/09/2008 à 20:48:55
Ob-la-di, Ob-la-da
Avatar
Groupe : Membres
Bah, avec une fractale ...
Je suis en train d'installer la lib, je vais voir ce que je peux faire.

Edit : j'ai pas trouvé de document sur comment utiliser Cairo comme une tortue :-°
Y'a moyen de faire ou pas ? Parce que sinon ca va etre galere vu que mon algo est basé sur le fait qu'on dessine des traits et des angles :S

Sinon le pere de ma corres' m'a déniché le bouquin de Mandelbrot en allemand :D J'ai trouvé une fractale qui a l'air chouette mais je sais pas comment ca s'appelle et comment trouver des infos dessus (du genre si y'a des trucs a respecter pour que ca marche). C'est genre a la base on a un rectangle vertical, et à son sommet y'en a deux (dont j'arrive pas a savoir s'ils sont identiques ou pas, puisque leur extremité se fond dans le premier rectangle, et en plus y'en a un qui est plus grand que l'autre), qui partent a gauche et à droite, et ainsi de suite. Ca finit par faire un arbre qui est assez joli. Je ne l'ai pas trouvée dans la liste de fractales par dimension de Hausdorff de Wikipédia. Quelqu'un a une idée ?
Édité le 17/09/2008 à 21:04:11 par Krankkatze
 
Hors ligne wgmpgp # Posté le 17/09/2008 à 21:43:22
Rotoclap true fan
Avatar
Groupe : Membres
C'est une variante de l'arbre de Pythagore, déja traité dans ce topic (notamment par moi en Ocaml en changeant les rectangles par des vecteurs, ça rendait plutôt pas mal).

Pour Cairo à utiliser comme une tortue... t'as des méthodes moveto ou des trucs du genre (ou ptet lineto) qui te permettent de te déplacer en fonction de ta position actuelle. 'fin j'ai pas utilisé depuis longtemps. J'ai des codes Ocaml qui utilisent Cairo sur http://ln-s.net/2EEN si tu veux t'inspirer (c'est les .html).
 
Hors ligne Krankkatze # Posté le 17/09/2008 à 22:15:16
Ob-la-di, Ob-la-da
Avatar
Groupe : Membres
Hmmm en fait spas tout à fait comme ton truc avec les vecteurs, parce que les rectangles partent à la perpendiculaire du rectangle de l'itération d'avant. Demain je ferai peut-être un scan pour être plus explicite :p
 
Hors ligne XT95 # Posté le 29/09/2008 à 21:48:17
Avatar
Groupe : Membres
Allez hop, j'apporte ma pierre a l'édifice :)

Technique :
- raycasting
- objet 3d procedural
- brouillard lineaire
- rendu basique d'éclairage ( produit scalaire )


EDIT : si certains s'amusent à trouver de jolies formes mathématiques, n'hésitez pas a poster un screen et la formule ;) .
Image utilisateur

main.cpp
Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <iostream>
#include <cmath>
#include <SDL/SDL.h>

#include "tool.h"




#define PASS   256.0
#define REPEAT 3.f
#define SIZEX  512
#define SIZEY  512

//-----------------------------------------------------------------------------

// Procudral 3D mesh \o/

//-----------------------------------------------------------------------------
float obj( float x, float y,float z )
{
    x *= REPEAT;
    y *= REPEAT;
    z *= REPEAT;
	return fabs( cos(x)*cos(y)*cos(z)+sin(x)*sin(y)*sin(z) );
}

//-----------------------------------------------------------------------------

//  Main

//-----------------------------------------------------------------------------
int main(int argc, char *argv[])
{
    //Init SDL
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Surface *ecran = SDL_SetVideoMode(SIZEX, SIZEY, 32, SDL_HWSURFACE);



    //Start raycasting
    for(float x=0.f; x<1.f; x+= 1.f/SIZEX)
    for(float y=0.f; y<1.f; y+= 1.f/SIZEY)
    {
        Uint32 pixel;
        vec3 ray    = { x-0.3, y, 0.0 };        
        vec3 rayDir = { x*4-2.0, y*4-2.0, 1.0 };
        rayDir.x /= 128;
        rayDir.y /= 128;
        rayDir.z /= 128;
        vec3 color = { 1.0f, 0.5f, 0.3f };
        for(float i=0; i<PASS; i++ )
        {
            float intensity = obj(ray.x, ray.y, ray.z);
            if( intensity > 0.6 ) // Intensity > 0.6 = solid, else blank
            {
                //Compute normal
                vec3 n = { 0.f, 0.f, 0.f};
                n.x = obj(ray.x, ray.y, ray.z)-obj(ray.x-0.1, ray.y, ray.z);
                n.y = obj(ray.x, ray.y, ray.z)-obj(ray.x, ray.y-0.1, ray.z);
                n.z = obj(ray.x, ray.y, ray.z)-obj(ray.x, ray.y, ray.z-0.1);
                Normalize(n);

                //Light dir
                vec3 l = { 0.0,1.0,0.0};

                 //Diffuse light
                float lighting = fmax( dot(l,n), 0.0);

                //Final color
                color.x = fmin( lighting+(i/PASS*1.0), 1.0); // light + linear fog
                color.y = fmin( lighting+(i/PASS*0.5), 1.0); // light + linear fog
                color.z = fmin( lighting+(i/PASS*0.3), 1.0); // light + linear fog
                break;
            }

            //Init to next pass :)
            ray.x += rayDir.x;
            ray.y += rayDir.y;
            ray.z += rayDir.z;
        }

        //SDL Pixel stuff
        pixel=SDL_MapRGBA(ecran->format, (int)(color.x*255), (int)(color.y*255), (int)(color.z*255), 255);
        SetPixel(ecran,(int)(x*SIZEX),(int)(y*SIZEY),pixel);
    }

    //Display & sleep
    SDL_Flip(ecran);
    Sleep();


    SDL_SaveBMP(ecran, "render.bmp");

    SDL_Quit();
    return 0;
}




tooh.h
Code : C++
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//-----------------------------------------------------------------------------

// vec3 struct

//-----------------------------------------------------------------------------
typedef struct
{
    float x,y,z;
}vec3;

//-----------------------------------------------------------------------------

// Length

//-----------------------------------------------------------------------------

float Length( float x, float y, float z )

{

    return sqrt( x*x + y*y + z*z);

}

//-----------------------------------------------------------------------------

// Normalize

//-----------------------------------------------------------------------------

void Normalize( vec3 &vec )

{

    vec.x /= Length( vec.x, vec.y, vec.z );

    vec.y /= Length( vec.x, vec.y, vec.z );

    vec.z /= Length( vec.x, vec.y, vec.z );

}



//-----------------------------------------------------------------------------

// dot product

//-----------------------------------------------------------------------------

float dot( vec3 &a, vec3 &b )

{

    return (a.x * b.x) + (a.y * b.y) + (a.z * b.z);

}



//-----------------------------------------------------------------------------

// SetPixel

//-----------------------------------------------------------------------------
void SetPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
    int nbOctetsParPixel = surface->format->BytesPerPixel;
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * nbOctetsParPixel;
    switch(nbOctetsParPixel)
    {
        case 1:
            *p = pixel;
            break;

        case 2:
            *(Uint16 *)p = pixel;
            break;

        case 3:
            if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
            {
                p[0] = (pixel >> 16) & 0xff;
                p[1] = (pixel >> 8) & 0xff;
                p[2] = pixel & 0xff;
            }
            else
            {
                p[0] = pixel & 0xff;
                p[1] = (pixel >> 8) & 0xff;
                p[2] = (pixel >> 16) & 0xff;
            }
            break;

        case 4:
            *(Uint32 *)p = pixel;
            break;
    }
}

//-----------------------------------------------------------------------------

// Sleep

//-----------------------------------------------------------------------------
void Sleep()
{
    int continuer = 1;
    SDL_Event event;
 
    while (continuer)
    {
        SDL_WaitEvent(&event);
        switch(event.type)
        {
            case SDL_QUIT:
                continuer = 0;
        }
    }
}
Édité le 30/09/2008 à 18:58:08 par XT95

#opengl@irc.epiknet.net
http://XT95.e3b.org
 
Hors ligne wgmpgp # Posté le 29/09/2008 à 22:02:37
Rotoclap true fan
Avatar
Groupe : Membres
Rien à dire, tout simplement superbe. Ah si, ça manque d'antialiasing.
Hors ligne XT95 # Posté le 29/09/2008 à 22:07:01
Avatar
Groupe : Membres
Effectivement, un ptit peu d'antialiasing ne ferrait pas de mal =) !
Je rajouterais ca demain !

#opengl@irc.epiknet.net
http://XT95.e3b.org
 
Hors ligne zulon # Posté le 30/09/2008 à 12:07:13
The shrieker shrieks.
Avatar
Groupe : Membres
Le rendu est beau, surtout pour un code aussi court :p . Bien que je ne comprenne pas très bien comment tu as fait. C'est quoi du "raycasting" ? Il me semblait que le but de ce topic était aussi d'expliquer comment on arrivait à faire des trucs cools :) .

Le code en lui-même, par contre, est assez imbuvable. 5 lignes de commentaires pour annoncer une fonction, je trouve ça excessif :/ . Surtout quand ces mêmes commentaires ne donnent aucune indication supplémentaire sur ladite fonction.
Que fait la obj par exemple ? Ça a l'air d'être le cœur du programme (elle est souvent appelée), et il n'y a pas vraiment d'explications.
Et en plus, les fonctions sont définies dans le header, et ça c'est moche.
Au passage, fabs, fmax et fmin sont déclarées dans math.h (cmath ici), pourquoi les réécrire o_O ?
Hors ligne XT95 # Posté le 30/09/2008 à 19:23:24
Avatar
Groupe : Membres
Citation : zulon
Le rendu est beau, surtout pour un code aussi court :p . Bien que je ne comprenne pas très bien comment tu as fait. C'est quoi du "raycasting" ? Il me semblait que le but de ce topic était aussi d'expliquer comment on arrivait à faire des trucs cools :) .

En fait, je viens de vérifier sur le wiki, ca s'appelerait plutot du rendu par voxel ..
Explication :
Code : Autre
1
2
3
4
5
6
7
8
9
Pour chaque pixel de l'écran :
    on lance un rayon en z (profondeur) qui avance de 1 jusqu'à 256 par exemple ( 256 = distance max).
        pour chaque point parcouru, on appel obj qui renvoit l'intensité de l'objet (entre 0 et 1) pour ce point.
        si l'intensité de l'objet est supérieur a 0.6 on considere qu'il présence de l'objet en ce point
           on calcul donc la couleur de ce pixel (avec la lumiere et le brouillard)
           on arrete la boucle en z
        sinon
           on affiche la couleur de fond
    on passe au pixel suivant


Citation : zulon
Le code en lui-même, par contre, est assez imbuvable. 5 lignes de commentaires pour annoncer une fonction, je trouve ça excessif :/ . Surtout quand ces mêmes commentaires ne donnent aucune indication supplémentaire sur ladite fonction.

Il n'y a en fait que 3 lignes, c'est lors du paste avec le zcode que ce "bug" est apparu.. Lorsque l'on a de nombreuses fonctions dans un fichier, ces 3 lignes font bien "ressortir chaque fonction", chacun ses habitudes =)


Citation : zulon
Que fait la obj par exemple ? Ça a l'air d'être le cœur du programme (elle est souvent appelée), et il n'y a pas vraiment d'explications.

La fonction obj est l'objet 3D que l'on veut afficher, elle prend en argument une position dans l'espace et renvoit une intensité entre 0 et 1. Si l'intensité est superieur a 0.5 par exemple (dans le cas de mon code 0.6), il y a présence de l'objet (et donc on calcul l'intensité lumineuse de ce point toussa).
Elle est appelé souvent : pour connaitre si le point testé fait partit de l'objet ou non, et pour le calcul de la normal de ce point.

Citation : zulon
Et en plus, les fonctions sont définies dans le header, et ça c'est moche.

En meme temps vu la taille du projet j'ai pas trouvé l'utilité de faire un .cpp en plus .. Surtout que c'est juste 2,3 fonctions "outil" pas vraiment le code en lui meme.

Citation : zulon
Au passage, fabs, fmax et fmin sont déclarées dans math.h (cmath ici), pourquoi les réécrire o_O ?

Effectivement, j'ai tenté abs (sans le f)et ca m'avait rien donné, alors j'en ai écrit une vite fait =]. C'est corrigé.
Édité le 30/09/2008 à 19:29:19 par XT95

#opengl@irc.epiknet.net
http://XT95.e3b.org
 
Hors ligne nax # Posté le 11/11/2008 à 13:14:02
Avatar
Groupe : Membres
Bon je remonte un peu le sujet j'ai découvert hier et voilà mes premiers résultats :
Du classique mais je passerait à plus élaboré / original quand je serais plus à l'aise avec Ocaml ;)

Triangles de Sierpinski
Sierpinski :
Secret (cliquez pour afficher)
Code : OCaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
open Graphics;;
open_graph " 500x500";;
let color n = let coef = n mod 255 in rgb coef coef coef;;

let rec draw size x y = 
  if (size > 0) then 
    begin  
      set_color ( color size );
      
      moveto x y;
      lineto (x+size) y;
      moveto x y;
      lineto x (y+size);
      moveto (x+size) y;
      lineto x (y+size);
      
      (* (fill_poly [|x,y; x+size,y; x,size+y|]); *)

      draw (size/2) x y;
      draw (size/2) (x+size/2) y;
      draw (size/2) x (y+size/2);
    end
;;
  
  
draw 500 0 0;;
wait_next_event [Key_pressed; Button_down];;


Mandelbrot :

Mandelbrot
Code :
Secret (cliquez pour afficher)
Code : OCaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
open Graphics;;


(* Dessine l'ensemble de Mandelbrot *)
(*
  zn+1 = zn^2 + c
*)

open_graph " 800x800";;

let couleur i j = 
  let rec mandel_rec max i x y a b =
    if ( (i = max) || (x*.x +. y*.y > 4.) ) then i
    else let temp = x in 
      mandel_rec max (i+1) (x*.x-.y*.y+.a) (2.*.temp*.y +. b) a b
  in
  let iter = (mandel_rec 500 0 0. 0. i j) 
  in
    if (iter >= 500) then rgb 0 0 0
    else rgb (iter mod 255) (iter+32 mod 255) (iter+64 mod 255)
;;

let mandelbrot taille = 
  for x = 0 to taille-1 do
    for y = 0 to taille-1 do
      let x2 = 3. *. float_of_int (x - taille / 2) /. (float_of_int (taille))in
      let y2 = 3. *. float_of_int (y - taille / 2) /. (float_of_int (taille)) in
        set_color (couleur x2 y2);
        plot x y
    done
  done
;;
	


mandelbrot 800;;

ignore (read_key ());;



XT95 : Comment as tu écrit la fonction obj() ?
Édité le 11/11/2008 à 17:28:51 par nax
 
Hors ligne bluestorm # Posté le 11/11/2008 à 15:40:55
dont ask to ask
Avatar
Groupe : Membres
Code : OCaml
1
2
3
4
5
6
moveto x y;
      lineto (x+size) y;
      moveto x y;
      lineto x (y+size);
      moveto (x+size) y;
      lineto x (y+size);


Code : OCaml
1
2
3
4
moveto x y;
      lineto (x+size) y;
      lineto x (y+size);
      lineto x y;


Et il sert à quoi ce truc, vu que t'as le fill_poly ensuite ?
 
Hors ligne nax # Posté le 11/11/2008 à 15:43:54
Avatar
Groupe : Membres
J'ai rajouté fill_poly après et j'ai pas enlevé les lignes.

J'ai transposé le code de XT95 en Ocaml et s'obtient des dessins étranges :D, ce doit être amusant de modifier la fonction obj pour varier les formes.

Image utilisateur

Secret (cliquez pour afficher)
Code : OCaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
open Graphics;;

type vect ={x:float; y:float; z:float};;

let abs x = 
  max x (-.x);;
 
let obj x y z =
  let x2 = x *. 3. in
  let y2 = y *. 3. in
  let z2 = z *. 3. in
    abs( cos(x2)*.cos(y2)*.cos(z2)+.sin(x2)*.sin