Page 1 sur 1

La Terre est ronde

Publié : mer. 04/janv./2006 12:02
par Le Soldat Inconnu
Salut,

Un petit trip : à partir d'un planisphère (donc d'une image plate), j'ai dessiné la terre en 3d.

Voilà le code, il faut ma lib "Effect"
http://www.lsi-dev.com/index.php?mod=ar ... ires&id=70

Je conseille d'avoir une bonne machine, sinon, il faut éditer le fichier "carte.ini" créer et diminuer le diamètre de la planète.

Le programme ne suffit pas seul, vous trouverez tous les fichiers ici : (le programme compilé et le code avec les fichier images)
http://perso.wanadoo.fr/lesoldatinconnu/bazar.htm

Code : Tout sélectionner

;- Ecran
ExamineDesktops()
Global Ecran_Hauteur, Ecran_Largeur, Ecran_Centre_X, Ecran_Centre_Y, Ecran_Synchronisation
Ecran_Largeur = DesktopWidth(0)
Ecran_Hauteur = DesktopHeight(0)
Ecran_Centre_X = Ecran_Largeur / 2
Ecran_Centre_Y = Ecran_Hauteur / 2
Ecran_Synchronisation = 1

;- Planète
UsePNGImageDecoder()

DataSection
  Carte : IncludeBinary "Carte.png"
EndDataSection
CatchImage(0, ?Carte)
; LoadImage(0, "Carte.png")

Global Image_Hauteur, Image_Largeur
Image_Largeur = ImageWidth() - 1
Image_Hauteur = ImageHeight() - 1
Dim Carte_Bord.l(Image_Hauteur)
Dim Carte_Largeur.l(Image_Hauteur)
Dim Carte(Image_Largeur, Image_Hauteur)
GetImageBits(ImageID(), @Carte())
; On recherche le bord de la carte
; Le noir représente du vide
For y = 0 To Image_Hauteur
  Bord = -1
  Repeat
    Bord + 1
    Couleur = Carte(Bord, y)
  Until Couleur <> 0
  Bord + 2
  Carte_Bord(y) = Bord
  Carte_Largeur(y) = Image_Largeur - 2 * Bord + 1
Next

;- Paramètres dimensionnels de la planète
Global Planete_Rayon.f, Planete_Rotation.f 
Planete_Rayon = 175
Planete_Rotation = 0.002

;- Autres parametres
#Pi = 3.14159265
#Pi_Inv = 1 / #Pi
#ASin_Definition = 2000
Dim ASin_Valeur.f(#ASin_Definition * 2)

Procedure Parametres()
  
  If FileSize("Carte.ini") = -1
    If CreatePreferences("Carte.ini")
      PreferenceComment("LSI Développements - www.lsi-dev.com")
      WritePreferenceLong("Synchronisation", 1)
      WritePreferenceLong("Rayon", 175)
      WritePreferenceLong("Vitesse", 20)
      ClosePreferences()
    EndIf
  EndIf

  OpenPreferences("Carte.ini")
  Ecran_Synchronisation = ReadPreferenceLong("Synchronisation", 1)
  Planete_Rayon = ReadPreferenceLong("Rayon", 175)
  Planete_Rotation = ReadPreferenceLong("Vitesse", 20)
  Planete_Rotation / 10000
  ClosePreferences()
  
EndProcedure

Procedure Calcul_Preliminaire()
  
  For n = -#ASin_Definition To #ASin_Definition
    ASin_Valeur(n + #ASin_Definition) = ASin(n / #ASin_Definition)
  Next
  
EndProcedure

Procedure Planete(x, y, Rayon, Longitude_Depart.f)
  StartDrawing(ScreenOutput())
    
    Rayon2 = Rayon * Rayon
    
    For nn = -Rayon To Rayon
      
      nn2 = nn * nn
      
      ; Rayon de la coupe horizontale de la planète à la distance nn de l'équateur
      Rayon_H.f = Sqr(Rayon2 - nn2)
      
      ; Calcul de la latitude (variant de 0 à 1 équivalent de -90° à +90°)
      Temp = nn * #ASin_Definition / Rayon + #ASin_Definition
      Latitude.f = ASin_Valeur(Temp) * #Pi_Inv
      PosY = Image_Hauteur * (Latitude + 0.5)
      
      For n = -Rayon To Rayon
        
        If Abs(n) < Rayon_H
          
          ; Calcul de la longitude (variant de 0 à 1 équivalent de -90° à +90°)
          If Rayon_H = 0
            Longitude.f = 0
          Else
            Temp = n * #ASin_Definition / Rayon_H + #ASin_Definition
            Longitude.f = ASin_Valeur(Temp) * #Pi_Inv
          EndIf
          
          ; Ajustement de la longitude en fonction du point de départ
          Longitude + Longitude_Depart
          If Longitude > 1
            Longitude - 2
          ElseIf Longitude < -1
            Longitude + 2
          EndIf
          
          PosX = Carte_Bord(PosY) + Carte_Largeur(PosY) * (Longitude * 0.5 + 0.5)
          
          ; Effet de lumiere
          Lumiere_Distance.f = Sqr(n * n + nn2)
          Temp = Lumiere_Distance * #ASin_Definition / Rayon + #ASin_Definition
          Lumiere.f = ASin_Valeur(Temp) * #Pi_Inv * 2
          Lumiere * Lumiere
           
          xx = x + n
          yy = y + nn
          If xx >= 0 And xx < Ecran_Largeur And yy >= 0 And yy < Ecran_Hauteur
            Plot(xx, yy, ColorLuminosity(Carte(PosX, PosY), 1 - Lumiere))
          EndIf
        EndIf
        
      Next
    Next
  StopDrawing()
EndProcedure


; On ouvre l'openscreen
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  MessageRequester("Erreur", "Impossible d'initialiser la souris ,le clavier ou l'écran. Vérifiez la présence de DirectX 7 ou supérieur.", 0)
  End
EndIf

If OpenScreen(Ecran_Largeur, Ecran_Hauteur, 32, "Carte") = 0
  MessageRequester("Erreur", "Impossible d'ouvrir l'écran.", 0)
  End
EndIf

Parametres()
Calcul_Preliminaire()

Repeat
  ClearScreen(0, 0, 0)
  
  ; On lit les évènements clavier et souris
  ExamineMouse()
  ExamineKeyboard()
  
  Longitude.f + Planete_Rotation
  If Longitude >= 2
    Longitude = 0
  EndIf
  Planete(Ecran_Centre_X, Ecran_Centre_Y, Planete_Rayon, Longitude)
  
  If KeyboardReleased(#PB_Key_F1)
    Deboguage = Deboguage ! 1
  EndIf
  If Deboguage
    StartDrawing(ScreenOutput())
      
      BackColor(0, 0, 0)
      FrontColor(255, 255, 255)
      
      ; Calcul du FPS
      Cpt + 1
      If Cpt >= FPS.f
        FPS = Cpt * 1000 / (ElapsedMilliseconds() - Temps)
        Cpt = 0
        Temps = ElapsedMilliseconds()
      EndIf
      
      Locate(5, 5)
      DrawText("FPS = " + StrF(FPS, 1))
      Locate(5, 25)
      DrawText("Longitude = " + StrF(Longitude * 180, 1) + "°")
      Locate(5, 25)
      DrawText("Longitude = " + StrF(Longitude * 180, 1) + "°")
      Locate(5, 45)
      DrawText("Rayon = " + StrF(Planete_Rayon, 0))
      Locate(5, 65)
      DrawText("Vitesse = " + StrF(Planete_Rotation, 4))
      
    StopDrawing()
  EndIf
  
  FlipBuffers(Ecran_Synchronisation)
  
Until KeyboardPushed(#PB_Key_Escape)
Bon amusement

Publié : mer. 04/janv./2006 12:41
par lionel_om
Simpa ton prog... 8)