Aller au contenu

Messages recommandés

Posté(e)

Voici un algorithme pour créer une sphère dans minecraft:

 

Premièrement, voici une sphère:

[ATTACH=full]8086[/ATTACH] Rien de plus classique, mais une forme complexe n'est-ce pas ?

 

Après quelques recherches, il est facilement possible de récupérer un algorithme qui permet de créer des disques ou des cercles:

m1202i13.PNGAlgorithmes de Bresenham et Andres.

 

Dans mes algorithmes qui sont des fonctions je vais simplement récupérer les locations dans une liste:

Pour les intéressés, j'ai refait Bresenham et Andres sous forme de fonction return.

[spoiler=Bresenham, Andres][spoiler=Cercle Bresenham]

function bresenham(radius:number,location:location,world:world) :: locations:
 set {_x} to 0
 set {_z} to {_radius}
 set {_m} to 5-4*{_radius}
 while {_x} <= {_z}:
   add location {_x}+x-location of {_location}, y-location of {_location}-1, {_z}+z-location of {_location} of {_world} to {_locations::*}
   add location {_z}+x-location of {_location}, y-location of {_location}-1, {_x}+z-location of {_location} of {_world} to {_locations::*}
   add location -1*{_x}+x-location of {_location}, y-location of {_location}-1, {_z}+z-location of {_location} of {_world} to {_locations::*}
   add location -1*{_z}+x-location of {_location}, y-location of {_location}-1, {_x}+z-location of {_location} of {_world} to {_locations::*}
   add location {_x}+x-location of {_location}, y-location of {_location}-1, -1*{_z}+z-location of {_location} of {_world} to {_locations::*}
   add location {_z}+x-location of {_location}, y-location of {_location}-1, -1*{_x}+z-location of {_location} of {_world} to {_locations::*}
   add location -1*{_x}+x-location of {_location}, y-location of {_location}-1, -1*{_z}+z-location of {_location} of {_world} to {_locations::*}
   add location -1*{_z}+x-location of {_location}, y-location of {_location}-1, -1*{_x}+z-location of {_location} of {_world} to {_locations::*}
   if {_m} > 0:
     remove 1 from {_z}
     set {_m} to {_m}-8*{_z}
   add 1 to {_x}
   set {_m} to {_m}+8*{_x}+4
 return {_locations::*}

 

[spoiler= Cercle Andres]

function andres(radius:number,location:location,world:world) :: locations:
 set {_x} to 0
 set {_z} to {_radius}
 set {_d} to {_radius}-1
 while {_z} >= {_x}:
   add location x-location of {_location}+{_x}, y-location of {_location}-1, z-location of {_location}+{_z} of {_world} to {_locations::*}
   add location x-location of {_location}+{_z}, y-location of {_location}-1, z-location of {_location}+{_x} of {_world} to {_locations::*}
   add location x-location of {_location}-{_x}, y-location of {_location}-1, z-location of {_location}+{_z} of {_world} to {_locations::*}
   add location x-location of {_location}-{_z}, y-location of {_location}-1, z-location of {_location}+{_x} of {_world} to {_locations::*}
   add location x-location of {_location}+{_x}, y-location of {_location}-1, z-location of {_location}-{_z} of {_world} to {_locations::*}
   add location x-location of {_location}+{_z}, y-location of {_location}-1, z-location of {_location}-{_x} of {_world} to {_locations::*}
   add location x-location of {_location}-{_x}, y-location of {_location}-1, z-location of {_location}-{_z} of {_world} to {_locations::*}
   add location x-location of {_location}-{_z}, y-location of {_location}-1, z-location of {_location}-{_x} of {_world} to {_locations::*}
   if {_d} >= 2*{_x}:
     set {_d} to {_d}-2*{_x}-1
     add 1 to {_x}
   else if {_d} < 2*({_radius}-{_z}):
     set {_d} to {_d}+2*{_z}-1
     remove 1 from {_z}
   else:
     set {_d} to {_d}+2*({_z}-{_x}-1)
     remove 1 from {_z}
     add 1 to {_x}
 return {_locations::*}

 

[spoiler=Disque Andres]

function disk(radius:number,location:location,world:world) :: locations:
 set {_x} to x-location of {_location}+{_radius}
 set {_y} to rounded down z-location of {_location}+{_radius}
 set {_d} to {_radius}-1
 set {_a} to {_radius}-1
 set {_b} to 0
 while {_a} >= {_b}:
   loop all integers between {_y}-{_a} and {_y}+{_a}:
     add location {_x}+{_b}-{_radius}, y-location of {_location}-1, loop-integer+0.5-{_radius} of {_world} to {_locations::*}
   loop all integers between {_y}-{_b} and {_y}+{_b}:
     add location {_x}+{_a}-{_radius}, y-location of {_location}-1, loop-integer+0.5-{_radius} of {_world} to {_locations::*}
   loop all integers between {_y}-{_a} and {_y}+{_a}:
     add location -1*{_radius}+{_x}-{_b}, y-location of {_location}-1, loop-integer+0.5-{_radius} of {_world} to {_locations::*}
   loop all integers between {_y}-{_b} and {_y}+{_b}:
     add location -1*{_radius}+{_x}-{_a}, y-location of {_location}-1, loop-integer+0.5-{_radius} of {_world} to {_locations::*}
   if {_d} >= 2*{_b}:
     set {_d} to {_d}-2*{_b}-1
     add 1 to {_b}
   else if {_d} < 2*({_radius}-{_a}):
     set {_d} to {_d}+2*{_a}-1
     remove 1 from {_a}
   else:
     set {_d} to {_d}+2*({_a}-{_b}-1)
     remove 1 from {_a}
     add 1 to {_b}
 return {_locations::*}

 

 

 

 

 

Passons à notre sphère:

 

Première chose à "savoir", une sphère de rayon r, est contenu dans un cube de côté 2r.

th?id=OIP.4TfPBtfxr1rT2MECKx1tFQHaIF&pid=15.1&P=0&w=300&h=300Le centre O, est aussi le centre de notre cube.

 

En géométrie cartésienne, une sphère de centre (x0,y0,z0) et de rayon r est l'ensemble des points (x,y,z) tel que:

(x-x0)²+ (y-y0)²+ (z-z0)²= r²

L'algorithme:

r = rayon
x0 = position x du centre
y0 = position y du centre
z0 = position z du centre
on se place dans deux coins opposés du cuboid de côté 2r de centre (x0,y0,z0)
créer une liste de position contenant les blocs de notre cuboid
saisir cette liste:
 x = position x du bloc
 y = position y du bloc
 z = position z du bloc
 si la difference entre (x-x0)²+(y-y0)²+(z-z0)² et r² < r:
   ajouter les positions de ce bloc à notre liste finale
renvoyer la liste finale

 

En skript:

 

Plusieurs étapes nécessaires:

 

  1. Récupérer un cuboid en format texte

  2. Récupérer les locations d'un cuboid

[spoiler=Cuboid sous format texte]

function bigger(numbers:numbers) :: number:
   loop {_numbers::*}:
       if {_max} is not set:
           set {_max} to loop-value
       else if loop-value is bigger or equal to {_max}:
           set {_max} to loop-value
   return {_max}

function smaller(numbers:numbers) :: number:
   loop {_numbers::*}:
       if {_min} is not set:
           set {_min} to loop-value
       else if loop-value is smaller or equal to {_min}:
           set {_min} to loop-value
   return {_min}

function cuboid(corner:location,corner2:location,world:world) :: text:
 set {_x::*} to rounded down x-location of {_corner} and rounded down x-location of {_corner2}
 set {_y::*} to rounded down y-location of {_corner} and rounded down y-location of {_corner2}
 set {_z::*} to rounded down z-location of {_corner} and rounded down z-location of {_corner2}
 add bigger({_x::*}) to {_c::*}
 add bigger({_y::*}) to {_c::*}
 add bigger({_z::*}) to {_c::*}
 add smaller({_x::*}) to {_c::*}
 add smaller({_y::*}) to {_c::*}
 add smaller({_z::*}) to {_c::*}
 return "%{_c::1}%,%{_c::4}%,%{_c::2}%,%{_c::5}%,%{_c::3}%,%{_c::6}%,%{_world}%"

 

 

 

[spoiler=Locations du cuboid]

function cuboids(cuboid:text) :: locations:
 loop {_cuboid} split by ",":
   if loop-value parsed as number is set:
     add loop-value parsed as number to {_c::*}
   else:
     set {_world} to loop-value parsed as world
 loop all numbers between {_c::2} and {_c::1}:
   loop all numbers between {_c::4} and {_c::3}:
     loop all numbers between {_c::6} and {_c::5}:
       add location loop-number-1, loop-number-2, loop-number-3 of {_world} to {_locations::*}
 return {_locations::*}

 

 

 

[spoiler=Fonction finale]

function sphere(radius:number,center:location,world:world) :: locations:
 set {_corner} to location x-location of {_center}+{_radius}, y-location of {_center}+{_radius}, z-location of {_center}+{_radius} of {_world}
 set {_corner2} to location x-location of {_center}-{_radius}, y-location of {_center}-{_radius}, z-location of {_center}-{_radius} of {_world}
 set {_x0} to x-location of {_center}
 set {_y0} to y-location of {_center}
 set {_z0} to z-location of {_center}
 loop cuboids(cuboid({_corner},{_corner2},{_world})):
   set {_x} to x-location of loop-value+0.5
   set {_y} to y-location of loop-value+0.5
   set {_z} to z-location of loop-value+0.5
   if difference between ({_x}-{_x0})^2+({_y}-{_y0})^2+({_z}-{_z0})^2 and {_radius}^2 is smaller than {_radius}:
     add loop-value to {_locations::*}
 return {_locations::*}

 

 

Bonne utilisation.

  • J'aime 1

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer.