Nuit noire (Carte de ciel)

Programmation d'applications complexes
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Nuit noire (Carte de ciel)

Message par Le Soldat Inconnu »

Salut,

Comme annoncé, je m'amuse sur un petit programme pour afficher la carte du ciel.
J'ai extrait une base de données de 118000 étoiles que j'exploite pour afficher une carte du ciel.

c'est pas du tout terminé mais je vais posté les avancé sur ce projet.

Pour le moment, j'affiche une carte du ciel dans j'ai filtré les étoiles les moins lumineuses (parce que avec 118000 étoiles, on voit des étoiles partout et on ne reconnait rien). Si vous arrivé a localisé des constellation, dite moi :D

Ce qu'il reste à faire :
-Rotation à la souris pas encore fonctionnel et peu esthétique
-Affichage des étoiles à l'aide de sprite 3D avec différent niveau de zoom pour différencier la luminosité de chaque étoile
-Modification du niveau de zoom à la souris en temps réel
-Modification du filtrage des étoiles en fonction de leur luminosité à la souris en temps réel


Avancement 12/12/10
Correction de la position des étoiles
Ajout d'une bulle d'information qui donne la position de l'étoile en heure (h) et degré (°). Pour imager, l'heure, c'est la position angulaire à laquelle on doit se tourner pour avoir l'étoile sur un axe vertical en face de soi. Les degrés donnent l'angle entre l'horizon et l'étoile.

Avancement 14/12/10
Correction sur la luminosité des étoiles (la magnitude est en échelle inversé, plus la valeur est faible et plus l'étoile est lumineuse, j'avais pris l'inverse)
Modification du niveau de zoom et de la visibilité par clic droit
Rotation sur l'axe Y par clic gauche (pas fait les autres axe encore)
Il faut appuyer sur F1 pour afficher le FPS et autre information

Si vous dézoomer au maximum (zoom x1) et que vous aller à l'angle Y de 190° (appuyé sur F1 pour le voir), vous pouvez apercevoir la grande ourse en haut de la carte (sauf je me sui trompé mais cela y ressemble drôlement et la position dans la carte du ciel semble bonne)


Avancement du 16/12/10
Modification du zoom et de la visibilité sur clic droit
Affichage des étoiles avec des sprites 3D, un peu plus lent qu'avec des pixels mais bien plus esthétique

il ne manque plus que la rotation à la souris et je vais regarder si il n'est pas possible d'optimiser la vitesse d'affichage

Avancement du 24/12/2010
La rotation à la souris fonctionne. J'ai du modifier pas mal de chose pour réussir.
Vous avez au centre de l'écran l'étoile polaire, La grande casserole est juste en dessous.

Avancement du 10/08/2011
Reprise complète du système d'affichage. J'ai gagné un poil en image par seconde.

Dernière version du code

Il vous faut le fichier "Etoile.list" qui contient la base de données des étoiles ainsi que les images :
http://partage.lsi-dev.com/etoiles.zip (2mo, à décompresser)


Attention, avec debugguer, c'est très lent

Code : Tout sélectionner

EnableExplicit


Structure Repere3D
	ix.d
	iy.d
	iz.d
	jx.d
	jy.d
	jz.d
	kx.d
	ky.d
	kz.d
EndStructure
Global Repere.Repere3D

Structure Point3D
	x.d
	y.d
	z.d
EndStructure
Structure Angle3D
	RA.d
	DE.d
EndStructure

Structure Star3D
	Display.Point3D
	Position.Point3D
	Light.i
	AngleRA.d
	AngleDE.d
	Magnitude.d
	Description.s
EndStructure

Global NewList Star.Star3D()

Define i.i

Define.i Screen_Width, Screen_Hight, Screen_Frequency, Screen_Synchronization
Define.d Angle_DE_Speed, Angle_RA_Speed, FPS, Display_Brake
Define.d Atmosphere, Atmosphere_Min, Atmosphere_Start, Atmosphere_Last.d
Define.d Visibility, Visibility_Max, Visibility_Start, Visibility_Min
Define Search_Distance.d, Search_Time.i, Search_Display.i
Define *Search_Star.Star3D, *Search_LastStar.Star3D
Define.i MouseX, MouseY, MouseDX, MouseDY, MouseX_Start, MouseY_Start
#Display_Speed_Brake = 0.5 ; Facteur de réduction de vitesse par seconde
Define.i DebugMode
Define.i Display_Center_X, Display_Center_Y, FPS_Counter, FPS_ElapsedTime
Define.i Display_Screen_XMin, Display_Screen_XMax, Display_Screen_YMin, Display_Screen_YMax
Define.i Display_Parameters
Define Display_StarInfo_X, Display_StarInfo_Y, Display_StarInfo_CX, Display_StarInfo_CY
Define Display_Zoom_X, Display_Zoom_Y, Display_Zoom_CX, Display_Zoom_CY, Display_Zoom_Text.s
Define Display_Visibility_X, Display_Visibility_Y, Display_Visibility_CX, Display_Visibility_CY, Display_Visibility_Text.s

#Star_Light_Precision = 50
#Star_Image_Size = 7
#Star_Display_Image = (#Star_Image_Size - 1) / 2
Define.i Star_Image, Star_Image_Size, Star_Image_Original, Star_Image_OriginalSize
Define.i Star_Display_MinimumLight, Star_Display_Center_X, Star_Display_Center_Y, Star_Display_MouseX, Star_Display_MouseY, Star_Display_ScreenX, Star_Display_ScreenY
Define.i Star_Calculation_Counter, Star_Display_Counter

Enumeration
	#Pointer
	#Pointer3D
	#Selection
	#Selection3D
	#Box
	#Box3D
	#StarImage
	#StarImage_End = #StarImage + #Star_Light_Precision
	#StarImage3D
	#StarImage3D_End = #StarImage3D + #Star_Light_Precision
EndEnumeration

; Utilisation de PNG
UsePNGImageDecoder()
UsePNGImageEncoder()

#Optimisation = 1


CompilerIf #Optimisation
	#Angle_Resolution = 200
	Global Dim PreCalcul_Cos.d(360 * #Angle_Resolution * 2)
	Global Dim PreCalcul_Sin.d(360 * #Angle_Resolution * 2)
	For i = -360 * #Angle_Resolution To 360 * #Angle_Resolution
		PreCalcul_Cos(i + 360 * #Angle_Resolution) = Cos(i * #PI / (180 * #Angle_Resolution))
		PreCalcul_Sin(i + 360 * #Angle_Resolution) = Sin(i * #PI / (180 * #Angle_Resolution))
	Next
CompilerEndIf

Procedure Rotate_Reset(*Repere.Repere3D)
	Repere\ix = 1
	Repere\iy = 0
	Repere\iz = 0
	Repere\jx = 0
	Repere\jy = 1
	Repere\jz = 0
	Repere\kx = 0
	Repere\ky = 0
	Repere\kz = 1
EndProcedure

Macro Rotate_Axis_Angle()
	CompilerIf #Optimisation
		Protected a.i
		a = Angle * #Angle_Resolution * 180 / #PI + 360 * #Angle_Resolution
		Cos = PreCalcul_Cos(a)
		Sin = PreCalcul_Sin(a)
	CompilerElse
		Cos = Cos(Angle)
		Sin = Sin(Angle)
	CompilerEndIf
EndMacro
Macro Rotate_Axis_Calculation(Axe1, Axe2, Cos, Sin)
	x = Axe1
	Axe1 = x * Cos - Axe2 * Sin
	Axe2 = Axe2 * Cos + x * Sin
EndMacro
Procedure Rotate_Axis_X(*Repere.Repere3D, Angle.d)
	Protected Cos.d, Sin.d, x.d
	
	Rotate_Axis_Angle()
	
	Rotate_Axis_Calculation(*Repere\iy, *Repere\iz, Cos, Sin)
	Rotate_Axis_Calculation(*Repere\jy, *Repere\jz, Cos, Sin)
	Rotate_Axis_Calculation(*Repere\ky, *Repere\kz, Cos, Sin)
	
EndProcedure
Procedure Rotate_Axis_Y(*Repere.Repere3D, Angle.d)
	Protected Cos.d, Sin.d, x.d
	
	Rotate_Axis_Angle()
	
	Rotate_Axis_Calculation(*Repere\iz, *Repere\ix, Cos, Sin)
	Rotate_Axis_Calculation(*Repere\jz, *Repere\jx, Cos, Sin)
	Rotate_Axis_Calculation(*Repere\kz, *Repere\kx, Cos, Sin)
	
EndProcedure
Procedure Rotate_Axis_Z(*Repere.Repere3D, Angle.d)
	Protected Cos.d, Sin.d, x.d
	
	Rotate_Axis_Angle()
	
	Rotate_Axis_Calculation(*Repere\ix, *Repere\iy, Cos, Sin)
	Rotate_Axis_Calculation(*Repere\jx, *Repere\jy, Cos, Sin)
	Rotate_Axis_Calculation(*Repere\kx, *Repere\ky, Cos, Sin)
	
EndProcedure
Procedure Rotate_Axis_I(*Repere.Repere3D, Angle.d)
	Protected Cos.d, Sin.d, x.d
	
	Rotate_Axis_Angle()
	
	Rotate_Axis_Calculation(*Repere\kx, *Repere\jx, Cos, Sin)
	Rotate_Axis_Calculation(*Repere\ky, *Repere\jy, Cos, Sin)
	Rotate_Axis_Calculation(*Repere\kz, *Repere\jz, Cos, Sin)
	
EndProcedure
Procedure Rotate_Axis_J(*Repere.Repere3D, Angle.d)
	Protected Cos.d, Sin.d, x.d
	
	Rotate_Axis_Angle()
	
	Rotate_Axis_Calculation(*Repere\ix, *Repere\kx, Cos, Sin)
	Rotate_Axis_Calculation(*Repere\iy, *Repere\ky, Cos, Sin)
	Rotate_Axis_Calculation(*Repere\iz, *Repere\kz, Cos, Sin)
	
EndProcedure
Procedure Rotate_Axis_K(*Repere.Repere3D, Angle.d)
	Protected Cos.d, Sin.d, x.d
	
	Rotate_Axis_Angle()
	
	Rotate_Axis_Calculation(*Repere\jx, *Repere\ix, Cos, Sin)
	Rotate_Axis_Calculation(*Repere\jy, *Repere\iy, Cos, Sin)
	Rotate_Axis_Calculation(*Repere\jz, *Repere\iz, Cos, Sin)
	
EndProcedure

Procedure XYZ(*Repere.Repere3D, *PointIJK.Point3D, *PointXYZ.Point3D)
	*PointXYZ\x = *PointIJK\x * *Repere\ix + *PointIJK\y * *Repere\jx + *PointIJK\z * *Repere\kx
	*PointXYZ\y = *PointIJK\x * *Repere\iy + *PointIJK\y * *Repere\jy + *PointIJK\z * *Repere\ky
	*PointXYZ\z = *PointIJK\x * *Repere\iz + *PointIJK\y * *Repere\jz + *PointIJK\z * *Repere\kz
EndProcedure


Procedure ResizeAlphaImage(Image, Width, Height)
	Protected x, xx, x1, x2, Memoire, Image_HDC, Image_Ancienne, Image_Bitmap.BITMAP, Image_BitmapInfo.BITMAPINFO
	If IsImage(Image)
		
		; Chargement du HDC
		Image_HDC = CreateCompatibleDC_(#Null)
		Image_Ancienne = SelectObject_(Image_HDC, ImageID(Image))
		
		; Dimension de l'image
		GetObject_(ImageID(Image), SizeOf(BITMAP), @Image_Bitmap)
		Image_BitmapInfo\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
		Image_BitmapInfo\bmiHeader\biWidth = Image_Bitmap\bmWidth
		Image_BitmapInfo\bmiHeader\biHeight = Image_Bitmap\bmHeight
		Image_BitmapInfo\bmiHeader\biPlanes = 1
		Image_BitmapInfo\bmiHeader\biBitCount = 32
		
		; Zone mémoire pour copier l'image
		xx = Image_Bitmap\bmWidth * Image_Bitmap\bmHeight - 1
		Protected Dim Memoire(xx)
		
		; Copie de l'image en mémoire
		GetDIBits_(Image_HDC, ImageID(Image), 0, Image_Bitmap\bmHeight, @Memoire(), @Image_BitmapInfo, #DIB_RGB_COLORS)
		
		; Modification de l'image en mémoire
		For x = 0 To xx
			If Memoire(x) = 0
				Memoire(x) = $00FFFFFF
			EndIf
		Next
		
		; Transfert de la mémoire dans la l'image de base
		SetDIBits_(Image_HDC, ImageID(Image), 0, Image_Bitmap\bmHeight, @Memoire(), @Image_BitmapInfo, #DIB_RGB_COLORS)
		
		; Fermeture du HDC
		SelectObject_(Image_HDC, Image_Ancienne)
		DeleteDC_(Image_HDC)
		
		ResizeImage(Image, Width, Height, #PB_Image_Smooth)
	EndIf
EndProcedure

Procedure Visibility(Visibility.d) ; Modilier la visibilité des étoiles (ciel plus ou moins clair)
	Protected Star_Max_Light.d
	LastElement(Star())
	Star_Max_Light = Visibility - Star()\Magnitude
	If Star_Max_Light > 0
		ForEach Star()
			Star()\Light = #Star_Light_Precision * (Visibility - Star()\Magnitude) / Star_Max_Light
		Next
	Else
		ForEach Star()
			Star()\Light = 0
		Next
	EndIf
EndProcedure
Procedure Position(Atmosphere.d, Atmosphere_Last.d) ; Modifier la taille de la carte
	ForEach Star()
		Star()\Display\x = Star()\Display\x * Atmosphere / Atmosphere_Last
		Star()\Display\y = Star()\Display\y * Atmosphere / Atmosphere_Last
		Star()\Display\z = Star()\Display\z * Atmosphere / Atmosphere_Last
	Next
EndProcedure

Procedure MySky() ; Afficher le ciel visible ce soir
	
	Rotate_Axis_X(@Repere, #PI / 2)
	
	; Le 21 mars à 0h, angle de 0 radian
	
	
	
	Rotate_Axis_Z(@Repere, -#PI / 2)
	
EndProcedure

;{- Chargement des étoiles
If ReadFile(0, "Etoiles.list")
	
	Repeat
		; Lecture des données de l'étoile
		AddElement(Star())
		Star()\AngleRA = ReadDouble(0)
		Star()\AngleDE = ReadDouble(0)
		Star()\Magnitude = ReadDouble(0)
		; précalcul
		Star()\Position\z = Cos(Star()\AngleRA * #PI / 180) * Cos(Star()\AngleDE * #PI / 180)
		Star()\Position\x = Sin(Star()\AngleRA * #PI / 180) * Cos(Star()\AngleDE * #PI / 180)
		Star()\Position\y = -Sin(Star()\AngleDE * #PI / 180)
		
		Star()\Description = StrD(Star()\AngleRA, 3) + " h , " + StrD(Star()\AngleDE, 3) + " °"
		
	Until Eof(0)
	
	; On trie les étoiles de la moins lumineuse à la plus lumineuse, de cette manière, on affiche les moins lumineuse en premier puis les plus lumineuse.
	; Cela évite de dessiner une étoile moins lumineuse sur un étoile plus lumineuse ce qui donne des résultats bizarres, étoiles très lumineuse qui clignote car une étoile peu lumineuse est placé non loin.
	SortStructuredList(Star(), #PB_Sort_Descending, OffsetOf(Star3D\Magnitude), #PB_Sort_Double)
	
	CloseFile(0)
EndIf
;} 
;{- Préparation
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 Or InitSprite3D() = 0
	MessageRequester("Erreur", "Impossible d'initialiser la souris ,le clavier ou l'écran. Vérifiez la présence de DirectX 9 ou supérieur.", 0)
	End
EndIf

; police
LoadFont(0, "Verdana", 9, #PB_Font_HighQuality)
;} 
;{- Initialisation des valeurs

; Dimension de l'écran
ExamineDesktops()
Screen_Width = DesktopWidth(0)
Screen_Hight = DesktopHeight(0)
Screen_Frequency = DesktopFrequency(0)
Screen_Synchronization = #PB_Screen_WaitSynchronization
FPS = 1

; Zoom
Atmosphere = (Screen_Hight + Screen_Width) / 2
If Screen_Hight < Screen_Width
	Atmosphere_Min = Screen_Hight / 2
Else
	Atmosphere_Min = Screen_Width / 2
EndIf
Position(Atmosphere, 1)
Atmosphere_Last = Atmosphere

; Visibilité
FirstElement(Star())
Visibility_Max = Star()\Magnitude
LastElement(Star())
Visibility_Min = Star()\Magnitude
Visibility = (Visibility_Max - Visibility_Min) * 65 / 100 + Visibility_Min
Visibility(Visibility)

; Repère
Rotate_Reset(@Repere)
; Angle de départ
MySky()

Star_Calculation_Counter = ListSize(Star())

;} 

Repeat
	
	;{- Ouverture de l'écran
	If OpenScreen(Screen_Width, Screen_Hight, 32, "Ecran", Screen_Synchronization, Screen_Frequency) = 0
		MessageRequester("Erreur", "Impossible d'ouvrir l'écran.", 0)
		End
	EndIf
	KeyboardMode(#PB_Keyboard_International)
	;} 
	;{- Chargement des sprites et polices
	LoadSprite(#Pointer, "Pointeur.png", #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
	CreateSprite3D(#Pointer3D, #Pointer)
	LoadSprite(#Selection, "Selection.png", #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
	CreateSprite3D(#Selection3D, #Selection)
	LoadSprite(#Box, "Bulle.png", #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
	CreateSprite3D(#Box3D, #Box)
	
	; Création des sprites des étoiles en fonction de la luminosité
	; Pour l'étoile avec la luminosité maximum, on prend l'image de l'étoile que l'on réduit à #Star_Image_Size
	; Pour une étoile avec 50% de la luminosité maximale, on ajoute une bordure vide autour de l'étoile équivalente à la taille de l'image sur 2, puis on réduit à #Star_Image_Size. L'image de l'étoile sera alors 50% plus petite
	; etc ...
	Star_Image_Original = LoadImage(#PB_Any, "Etoile.png")
	If Star_Image_Original
		Star_Image_OriginalSize = ImageWidth(Star_Image_Original)
		For i = 1 To #Star_Light_Precision
			Star_Image_Size = 105 * #Star_Light_Precision / i
			If Star_Image_Size & %1 = 0
				Star_Image_Size + 1
			EndIf
			If Star_Image_Size < Star_Image_OriginalSize * 10
				If Star_Display_MinimumLight = 0
					Star_Display_MinimumLight = i
				EndIf
				; Debug "Taille de l'image " + Str(i) + " avant redimensionnant = " + Str(Star_Image_Size)
				; Debug "Valeur réelle = " + StrD(105 * #Star_Light_Precision / i, 3)
				; Debug "Erreur de précision = " + StrD(((Star_Image_Size - 105 * #Star_Light_Precision / i) / (105 * #Star_Light_Precision / i)) * 100, 3) + "%"
				; Debug ""
				Star_Image = CreateImage(#PB_Any, Star_Image_Size, Star_Image_Size, 32 | #PB_Image_Transparent)
				StartDrawing(ImageOutput(Star_Image))
					DrawAlphaImage(ImageID(Star_Image_Original),(Star_Image_Size - Star_Image_OriginalSize) / 2,(Star_Image_Size - Star_Image_OriginalSize) / 2)
				StopDrawing()
				ResizeAlphaImage(Star_Image, #Star_Image_Size, #Star_Image_Size)
				SaveImage(Star_Image, "Temp.png", #PB_ImagePlugin_PNG)
				FreeImage(Star_Image)
				
				LoadSprite(#StarImage + i, "Temp.png", #PB_Sprite_AlphaBlending | #PB_Sprite_Texture)
				CreateSprite3D(#StarImage3D + i, #StarImage + i)
				
				DeleteFile("Temp.png")
			EndIf
		Next
		FreeImage(Star_Image_Original)
	EndIf
	
	;} 
	;{- Initialisation de l'affichage
	Display_Center_X = Screen_Width / 2
	Display_Center_Y = Screen_Hight / 2
	Display_Screen_XMin = -Display_Center_X
	Display_Screen_XMax = Display_Center_X - 1
	Display_Screen_YMin = -Display_Center_Y
	Display_Screen_YMax = Display_Center_Y - 1
	
	Star_Display_Center_X = Display_Center_X - #Star_Display_Image
	Star_Display_Center_Y = Display_Center_Y - #Star_Display_Image
	
	Display_StarInfo_X = Screen_Width - SpriteWidth(#Box) - 32
	Display_StarInfo_Y = 32
	Display_StarInfo_CX = Display_StarInfo_X + SpriteWidth(#Box) / 2
	Display_StarInfo_CY = Display_StarInfo_Y + SpriteHeight(#Box) / 2
	
	Display_Zoom_X = Screen_Width / 2 + 32
	Display_Zoom_Y = Screen_Hight / 2 - SpriteHeight(#Box) / 2
	Display_Zoom_CX = Display_Zoom_X + SpriteWidth(#Box) / 2
	Display_Zoom_CY = Display_Zoom_Y + SpriteHeight(#Box) / 2
	
	Display_Visibility_X = Screen_Width / 2 - SpriteWidth(#Box) - 32
	Display_Visibility_Y = Screen_Hight / 2 - SpriteHeight(#Box) / 2
	Display_Visibility_CX = Display_Visibility_X + SpriteWidth(#Box) / 2
	Display_Visibility_CY = Display_Visibility_Y + SpriteHeight(#Box) / 2
	
	MouseLocate(Display_Center_X, Display_Center_Y)
	;} 
	
	Repeat
		ClearScreen($000000)
		
		; On lit les évènements clavier et souris
		ExamineMouse()
		ExamineKeyboard()
		
		; Position de la souris
		MouseX = MouseX()
		MouseY = MouseY()
		Star_Display_MouseX = MouseX - #Star_Display_Image
		Star_Display_MouseY = MouseY - #Star_Display_Image
		MouseDX = MouseDeltaX()
		MouseDY = MouseDeltaY()
		
		; Debogage
		If KeyboardReleased(#PB_Key_F1) ; Affichage du débogage
			DebugMode = 1 - DebugMode
		EndIf
		If DebugMode And KeyboardReleased(#PB_Key_F2) ; Changment du mode de synchronisation
			Break
		EndIf
		
		;{- Déplacement de la carte du ciel à la souris ou au clavier
		If MouseButton(#PB_MouseButton_Left)
			Angle_DE_Speed = ASin(MouseDY / Atmosphere)
			Angle_RA_Speed = -ASin(MouseDX / Atmosphere)
		EndIf
		If MouseButton(#PB_MouseButton_Middle)
			MySky()
		EndIf
		If KeyboardPushed(#PB_Key_Up)
			Angle_DE_Speed = -#PI / 180
		EndIf
		If KeyboardPushed(#PB_Key_Down)
			Angle_DE_Speed = #PI / 180
		EndIf
		If KeyboardPushed(#PB_Key_Right)
			Angle_RA_Speed = -#PI / 180
		EndIf
		If KeyboardPushed(#PB_Key_Left)
			Angle_RA_Speed = #PI / 180
		EndIf
		If KeyboardPushed(#PB_Key_Space)
			Rotate_Axis_X(@Repere, #PI / 2)
		EndIf
		;} 
		
		;{- Modification des paramètres
		If MouseButton(#PB_MouseButton_Right)
			If Display_Parameters = 0
				MouseLocate(Display_Center_X, Display_Center_Y)
				MouseX_Start = MouseX
				MouseY_Start = MouseY
				Atmosphere_Start = Atmosphere
				Visibility_Start = Visibility
			EndIf
			Display_Parameters = 1
			If MouseDY
				If MouseY - Display_Center_Y > 32
					Atmosphere = Atmosphere_Start / (1 + (MouseY - Display_Center_Y - 32) * 5 / (Screen_Hight - 64))
				ElseIf MouseY - Display_Center_Y < -32
					Atmosphere = Atmosphere_Start * (1 + (Display_Center_Y + 32 - MouseY) * 5 / (Screen_Hight - 64))
				Else
					Atmosphere = Atmosphere_Start
				EndIf
				If Atmosphere < Atmosphere_Min
					Atmosphere = Atmosphere_Min
				EndIf
				Position(Atmosphere, Atmosphere_Last)
				Atmosphere_Last = Atmosphere
			EndIf
			If MouseDX
				If MouseX - Display_Center_X > 32
					Visibility = Visibility_Start + (MouseX - Display_Center_X - 32) * (Visibility_Max - Visibility_Min) / (Screen_Width - 64)
				ElseIf MouseX - Display_Center_X < -32
					Visibility = Visibility_Start + (MouseX - Display_Center_X + 32) * (Visibility_Max - Visibility_Min) / (Screen_Width - 64)
				Else
					Visibility = Visibility_Start
				EndIf
				If Visibility < Visibility_Min
					Visibility = Visibility_Min
				ElseIf Visibility > Visibility_Max
					Visibility = Visibility_Max
				EndIf
				Visibility(Visibility)
			EndIf
		Else
			If Display_Parameters
				MouseLocate(MouseX_Start + MouseX - Display_Center_X, MouseY_Start + MouseY - Display_Center_Y)
			EndIf
			Display_Parameters = 0
		EndIf
		;} 
		
		If Start3D()
				
				;- Affichage des étoiles
				; Initialisation de la recherche de l'étoile la plus proche de la souris
				Search_Distance = #Star_Image_Size * #Star_Image_Size
				*Search_LastStar = *Search_Star
				*Search_Star = 0
				Star_Display_Counter = 0
				; Rotation du repère
				Rotate_Axis_Y(@Repere, Angle_RA_Speed)
				Rotate_Axis_X(@Repere, Angle_DE_Speed)
				; Pour chaque étoile
				ForEach Star()
					If Star()\Light > Star_Display_MinimumLight
						XYZ(@Repere, @Star()\Position, @Star()\Display)
						; Affichage de l'étoile, si elle est sur l'écran et visible
						If Star()\Display\z < -0.1
							Star()\Display\x * Atmosphere
							Star()\Display\y * Atmosphere
							Star()\Display\z * Atmosphere
							If Star()\Display\x >= Display_Screen_XMin And Star()\Display\x < Display_Screen_XMax And Star()\Display\y >= Display_Screen_YMin And Star()\Display\y < Display_Screen_YMax
								Star_Display_ScreenX = Star_Display_Center_X + Star()\Display\x
								Star_Display_ScreenY = Star_Display_Center_Y + Star()\Display\y
								Star_Display_Counter + 1
								DisplaySprite3D(#StarImage3D + Star()\Light, Star_Display_ScreenX, Star_Display_ScreenY)
								; Recherche de l'étoile la plus proche de la souris
								Star_Display_ScreenX - Star_Display_MouseX
								If Star_Display_ScreenX < #Star_Image_Size
									Star_Display_ScreenY - Star_Display_MouseY
									If Star_Display_ScreenY < #Star_Image_Size And Star_Display_ScreenX * Star_Display_ScreenX + Star_Display_ScreenY * Star_Display_ScreenY < Search_Distance
										*Search_Star = @Star()
										Search_Distance = Star_Display_ScreenX * Star_Display_ScreenX + Star_Display_ScreenY * Star_Display_ScreenY
									EndIf
								EndIf
							EndIf
						EndIf
					EndIf
				Next
				; Fin de la recherche de l'étoile la plus proche de la souris
				If *Search_Star <> *Search_LastStar
					Search_Time = ElapsedMilliseconds()
				EndIf
				If *Search_Star <> 0 And ElapsedMilliseconds() - Search_Time > 250
					Search_Display = 1
				Else
					Search_Display = 0
				EndIf
				
				
				If Display_Parameters
					; Affichage des paramètres
					DisplaySprite3D(#Box3D, Display_Zoom_X, Display_Zoom_Y)
					DisplaySprite3D(#Box3D, Display_Visibility_X, Display_Visibility_Y)
				Else
					If Search_Display
						; Affichage de la sélection
						DisplaySprite3D(#Box3D, Display_StarInfo_X, Display_StarInfo_Y)
						DisplaySprite3D(#Selection3D, Display_Center_X + *Search_Star\Display\x - 10, Display_Center_Y + *Search_Star\Display\y - 10)
					EndIf
				EndIf
				; Affichage du pointeur
				DisplaySprite3D(#Pointer3D, MouseX, MouseY)
				
			Stop3D()
		EndIf
		
		; Texte à afficher
		StartDrawing(ScreenOutput())
			DrawingMode(#PB_2DDrawing_Transparent)
			DrawingFont(FontID(0))
			If Display_Parameters ; Affichage des paramètres
				Display_Zoom_Text = "Zoom x" + StrD(Atmosphere / Atmosphere_Min, 1)
				DrawText(Display_Zoom_CX - TextWidth(Display_Zoom_Text) / 2, Display_Zoom_CY - TextHeight(Display_Zoom_Text) / 2, Display_Zoom_Text, $FFFFFF)
				Display_Visibility_Text = "Visibilité = " + StrD(100 * (Visibility - Visibility_Min) / (Visibility_Max - Visibility_Min), 0) + "%"
				DrawText(Display_Visibility_CX - TextWidth(Display_Visibility_Text) / 2, Display_Visibility_CY - TextHeight(Display_Visibility_Text) / 2, Display_Visibility_Text, $FFFFFF)
			ElseIf Search_Display ; Position de l'étoile sélectionnée
				DrawText(Display_StarInfo_CX - TextWidth(*Search_Star\Description) / 2, Display_StarInfo_CY - TextHeight(*Search_Star\Description) / 2, *Search_Star\Description, $FFFFFF)
			EndIf
			
			If DebugMode
				; Debogage
				DrawText(0, 0, "FPS : " + StrD(FPS, 1) + " ; " + StrD(100 * FPS / Screen_Frequency, 1) + "%")
				DrawText(0, 20, "Synchronisation : " + Str(Screen_Synchronization) + " (F2 pour changer)")
				DrawText(0, 40, "Etoiles calculées : " + Str(Star_Calculation_Counter))
				DrawText(0, 60, "Etoiles affichées : " + Str(Star_Display_Counter))
				If *Search_Star <> 0
					DrawText(0, 80, "Etoile angle RA : " + StrD(*Search_Star\AngleRA))
					DrawText(0, 100, "Etoile angle DE : " + StrD(*Search_Star\AngleDE))
				EndIf
				
			EndIf
		StopDrawing()
		
		;{- Modification de la vitesse de rotation de l'affichage
		Angle_DE_Speed * Display_Brake ; Le ralentissement est calculé en même temps que le FPS car il dépend du FPS (le ralentissmeent est le même qlque soit le FPS
		Angle_RA_Speed * Display_Brake
		;} 
		
		FlipBuffers()
		
		;{ Calcul du FPS
		FPS_Counter + 1
		If FPS_Counter >= FPS
			FPS = FPS_Counter * 1000 / (ElapsedMilliseconds() - FPS_ElapsedTime)
			FPS_Counter = 0
			FPS_ElapsedTime = ElapsedMilliseconds()
			If FPS <= 0
				FPS = 1
			EndIf
			
			Display_Brake = Pow(#Display_Speed_Brake,(1 / FPS)) ; En ralentissant le mouvement de cette manière, on ne tient pas compte du FPS
			
		EndIf
		;} 
		
		If KeyboardPushed(#PB_Key_Escape) Or IsScreenActive() = 0 ; Fermer si Echap ou retour à Windows
			End
		EndIf
		
	ForEver
	
	; On change la synchronisation de l'écran
	CloseScreen()
	Select Screen_Synchronization
		Case #PB_Screen_NoSynchronization
			Screen_Synchronization = #PB_Screen_WaitSynchronization
		Case #PB_Screen_WaitSynchronization
			Screen_Synchronization = #PB_Screen_SmartSynchronization
		Case #PB_Screen_SmartSynchronization
			Screen_Synchronization = #PB_Screen_NoSynchronization
	EndSelect
	
ForEver
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
DominiqueB
Messages : 47
Inscription : sam. 01/mai/2004 14:41

Re: Nuit noire (Carte de ciel)

Message par DominiqueB »

Salut,

je teste ton programme et en mode debug j'ai une erreur en ligne 191,
c'est là où tu fais le Plot(), le message est le suivant :
Plot() est en dehors de la zone de dessin

Ma résolution d'écran : 1280 * 800

A +

Dominique
Dominique
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Nuit noire (Carte de ciel)

Message par Le Soldat Inconnu »

programme mis à jour. Il faut retélécharger le zip
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Huitbit
Messages : 939
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Re: Nuit noire (Carte de ciel)

Message par Huitbit »

Hello,

ça marche nickel sur mon pc en carton(fps = 39) :D
J'ai cru voir le Père Noel !
Par contre pour les constellations, c'est un peu dur.
Vivement la suite !

Hasta la vista !
Elevé au MSX !
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Nuit noire (Carte de ciel)

Message par Le Soldat Inconnu »

Ca évolue, mais pas vite :)

Je me suis aperçu que j'ai mal traduit la position de l'étoile dans mon repère (ce qui devait être en haut du ciel se retrouvait à gauche)
donc j'ai corrigé tout cela. Voir code dans le premier sujet.

Je remet ici la première version du code qui n'est plus fonctionnel car j'ai modifié la base de données des étoiles. cela servira d'historique pour les intéressés

Code ancienne version, le code le plus récent est dans le premier message

Code : Tout sélectionner

Structure Point3D
	x.d
	y.d
	z.d
EndStructure

Structure Star3D
	Position.Point3D
	Angle.Point3D
	Angle1.d
	Angle2.d
	Light.d
EndStructure

Global NewList Star.Star3D()
Global Star_Max_Light.d

Enumeration 
	#Pointer
	#Pointer3D
EndEnumeration

; Utilisation de PNG
UsePNGImageDecoder()

; précalcul des cos et sin
#Angle_Resolution = 100
Global Dim Calculation_Cos.d(360 * #Angle_Resolution)
Global Dim Calculation_Sin.d(360 * #Angle_Resolution)
For i = 0 To 360 * #Angle_Resolution
	Calculation_Cos(i) = Cos(i * #PI / (180 * #Angle_Resolution))
	Calculation_Sin(i) = Sin(i * #PI / (180 * #Angle_Resolution))
Next

Procedure Star_XYZ(*Star.Star3D, Atmosphere.d, Angle_X_Axis.d, Angle_Y_Axis.d, Angle_Z_Axis.d)
  ; Angle_X_Axis, ay, Angle_Z_Axis : angle de rotation du point sur l'Angle_X_Axise x, y et z, pour avoir un repère 3D décalé par rapport au repère de l'écran
  
  Protected Origine.Point3D, Calcul.Point3D, Sin.d, Cos.d
	
	Origine\x = Atmosphere * *Star\Angle\x
	Origine\y = Atmosphere * *Star\Angle\y
	Origine\z = Atmosphere * *Star\Angle\z
	
	; Rotation sur l'axe Z
	If Angle_Z_Axis
		; Cos = Cos(Angle_Z_Axis)
		; Sin = Sin(Angle_Z_Axis)
		Angle.i = Angle_Z_Axis * #Angle_Resolution * 180 / #PI
		Cos = Calculation_Cos(Angle)
		Sin = Calculation_Sin(Angle)
		Calcul\x = Origine\x * Cos - Origine\y * Sin
		Calcul\y = Origine\x * Sin + Origine\y * Cos
	Else
		Calcul\x = Origine\x
		Calcul\y = Origine\y
	EndIf
	; Debug StrD(Calcul\x) + " , " + StrD(Calcul\y) + " , " + StrD(Origine\z)
	
	; Rotation sur l'axe X
	If Angle_X_Axis
		; Cos = Cos(Angle_X_Axis)
		; Sin = Sin(Angle_X_Axis)
		Angle.i = Angle_X_Axis * #Angle_Resolution * 180 / #PI
		Cos = Calculation_Cos(Angle)
		Sin = Calculation_Sin(Angle)
		*Star\Position\y = Calcul\y * Cos - Origine\z * Sin
		Calcul\z = Calcul\y * Sin + Origine\z * Cos
	Else
		*Star\Position\y = Calcul\y
		Calcul\z = Origine\z
	EndIf
	; Debug StrD(Calcul\x) + " , " + StrD(*Star\Position\\y) + " , " + StrD(Calcul\z)
	
	; Rotation sur l'axe Y
	If Angle_Y_Axis
		; Cos = Cos(Angle_Y_Axis)
		; Sin = Sin(Angle_Y_Axis)
		Angle.i = Angle_Y_Axis * #Angle_Resolution * 180 / #PI
		Cos = Calculation_Cos(Angle)
		Sin = Calculation_Sin(Angle)
		*Star\Position\z = Calcul\z * Cos - Calcul\x * Sin
		*Star\Position\x = Calcul\z * Sin + Calcul\x * Cos
	Else
		*Star\Position\z = Calcul\z
		*Star\Position\x = Calcul\x
	EndIf
	; Debug StrD(*Star\Position\\x) + " , " + StrD(*Star\Position\\y) + " , " + StrD(*Star\Position\\z)
	
EndProcedure

Procedure Visibility(Variation.d) ; modilier la visibilité des étoiles (ciel plus ou moins clair)
	Star_Max_Light = 0
	ForEach Star()
		Star()\Light + Variation
		If Star()\Light > Star_Max_Light
			Star_Max_Light = Star()\Light
		EndIf
	Next
EndProcedure

;{- Chargement des étoiles
If ReadFile(0, "Etoiles.list")
	
	Repeat
		; Lecture des données de l'étoile
		AddElement(Star())
		Star()\Angle1 = ReadDouble(0)
		Star()\Angle2 = ReadDouble(0)
		Star()\Light = ReadDouble(0)
		; précalcul
		Star()\Angle\x = Cos(Star()\Angle1) * Cos(Star()\Angle2)
		Star()\Angle\y = Sin(Star()\Angle1) * Cos(Star()\Angle2)
		Star()\Angle\z = Sin(Star()\Angle2)
		
	Until Eof(0)
	
	; On trie les étoiles de la moins lumineuse à la plus lumineuse, de cette manière, on affiche les moins lumineuse en premier puis les plus lumineuse. 
	; Cela évite de dessiner une étoile moins lumineuse sur un étoile plus lumineuse ce qui donne des résultats bizarres, étoiles très lumineuse qui clignote car une étoile peu lumineuse est placé non loin.
	SortStructuredList(Star(), #PB_Sort_Ascending, OffsetOf(Star3D\Light), #PB_Sort_Double)
	
	CloseFile(0)
EndIf
;}

;{ Test de vitesse - Décommentez cette zone pour lancer le test
; Atmosphere.d = 1000
; Angle_X.d = 0.1
; Angle_Y.d = 0.1
; Angle_Z.d = 0.1
; 
; Temps1 = ElapsedMilliseconds()
; For nn = 1 To 50
	; ForEach Star()
		; Star_XYZ(@Star()\Position, Atmosphere, Angle_X, Angle_Y, Angle_Z)
	; Next
; Next
; Temps2 = ElapsedMilliseconds()
; 
; MessageRequester("Temps", Str(ListSize(Star())) + " étoiles" + Chr(10) + Str((Temps2 - Temps1)/50) + " ms")
; End
;}

;{- Ouverture de l'écran
ExamineDesktops()
Screen_Width = DesktopWidth(0)
Screen_Hight = DesktopHeight(0)

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

If OpenScreen(Screen_Width, Screen_Hight, 32, "Ecran", #PB_Screen_WaitSynchronization, DesktopFrequency(0)) = 0
  MessageRequester("Erreur", "Impossible d'ouvrir l'écran.", 0)
  End
EndIf
;}
;{- Chargement des sprites
LoadSprite(#Pointer,  "Pointeur.png", #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
CreateSprite3D(#Pointer3D, #Pointer)


;}

; Initialisation des valeurs
Define.d Angle_X, Angle_Y, Angle_Z, Atmosphere, Angle_X_Speed, Angle_Y_Speed, Angle_Z_Speed, FPS, Brake
Define.i Display_Center_X, Display_Center_Y, FPS_Counter, FPS_ElapsedTime
#Speed_Brake = 0.5
Visibility(-10)
Display_Center_X = Screen_Width / 2
Display_Center_Y = Screen_Hight / 2
Atmosphere = (Screen_Hight + Screen_Width) / 2
Angle_X = 0
Angle_Y = 0
FPS = 1

Repeat
  ClearScreen($000000)
	
  ; On lit les évènements clavier et souris
  ExamineMouse()
  ExamineKeyboard()
  
  ; Position de la souris
  MouseX = MouseX()
  MouseY = MouseY()
	MouseDX = MouseDeltaX()
	MouseDY = MouseDeltaY()
	
	; Déplacement de la carte du ciel à la souris
	If MouseButton(#PB_MouseButton_Left)
		Angle_Y_Speed = MouseDX / 1000
	EndIf
	; Modification de l'angle d'affichage
	Brake = 1 - #Speed_Brake / FPS ; En ralentissant le mouvement de cette manière, on ne tient pas compte du FPS
	
	Angle_X + Angle_X_Speed
	If Angle_X > 2 * #PI
		Angle_X - 2 * #PI
	ElseIf Angle_X < 0
		Angle_X + 2 * #PI
	EndIf
	Angle_X_Speed * Brake
	
	Angle_Y + Angle_Y_Speed
	If Angle_Y > 2 * #PI
		Angle_Y - 2 * #PI
	ElseIf Angle_Y < 0
		Angle_Y + 2 * #PI
	EndIf
	Angle_Y_Speed * Brake
	
	Angle_Z + Angle_Z_Speed
	If Angle_Z > 2 * #PI
		Angle_Z - 2 * #PI
	ElseIf Angle_Z < 0
		Angle_Z + 2 * #PI
	EndIf
	Angle_Z_Speed * Brake
	
	StartDrawing(ScreenOutput())
		ForEach Star()
			If Star()\Light > 0
				; Calcul de la position des étoiles
				Star_XYZ(@Star()\Position, Atmosphere, Angle_X, Angle_Y, 0)
				; Affichage de l'étoile, si elle est sur l'écran
				If Star()\Position\z > 0 And Star()\Position\x >= -Display_Center_X And Star()\Position\x < Display_Center_X - 1 And Star()\Position\y >= -Display_Center_Y And Star()\Position\y < Display_Center_Y - 1
					Color = 155 * Star()\Light / Star_Max_Light + 100
					Plot(Display_Center_X + Star()\Position\x, Display_Center_Y + Star()\Position\y, RGB(Color, Color, Color))
				EndIf
			EndIf
		Next
		
		DrawText(0, 0, Str(FPS))
		
	StopDrawing()
	
	If Start3D()
			
			; Affichage du pointeur
			DisplaySprite3D(#Pointer3D, MouseX, MouseY, 196)
			
		Stop3D()
	EndIf
  
  FlipBuffers()
	
	; Calcul du FPS
	FPS_Counter + 1
	If FPS_Counter >= FPS
		FPS = FPS_Counter * 1000 / (ElapsedMilliseconds() - FPS_ElapsedTime)
		FPS_Counter = 0
		FPS_ElapsedTime = ElapsedMilliseconds()
	EndIf
  
Until KeyboardPushed(#PB_Key_Escape)
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
DominiqueB
Messages : 47
Inscription : sam. 01/mai/2004 14:41

Re: Nuit noire (Carte de ciel)

Message par DominiqueB »

Merci ça marche nickel à présent !

Une idée : ce qui serait bien c'est de pouvoir mettre en évidence les principales
constellation lorsque le curseur est sur une des planètes de celles-ci.
Avec en plus en haut à droite son nom et quelques infos la concernant,
du genre sa distance de la terre, la meilleur période pour l'observer . . .

Encore merci pour ce programme !

Dominique
Dominique
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Nuit noire (Carte de ciel)

Message par Le Soldat Inconnu »

J'ai vu une grosse boulette sur la luminosité des étoiles. Elle est exprimée en "magnitude" donc plus c'est faible et plus c'est lumineux. et moi forcément, j'ai fais l'inverse. Je poste une correction demain. J'ai encore des truc à fignoler.
En tous cas, c'est mieux car j'arrive à voir la grande ourse :)
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Nuit noire (Carte de ciel)

Message par Ollivier »

Euh... Le Soldat Inconnu, j'ai écrit un post ici dans ton sujet de la section « Trucs & astuces ».

En effet, j'ai l'impression que tu as fait une erreur de calcul dans la procédure des rotations. Et ça m'a inspiré pour mettre au jour tous les détails essentiels à la 3D dans la section « Infos & tuto ».

Je n'ai pas testé ton programme ici. Mais s'il marche impeccable et que tu utilises la même procédure que dans la section «Trucs & astuces» alors c'est qu'il y a une sphère à but reproductif dans le pâté quelquepart...
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Nuit noire (Carte de ciel)

Message par Le Soldat Inconnu »

Code du premier sujet mis à jour, avec explication des changements.

Je pense avoir trouvé la grande ourse. Vous la voyez également ? (voir explication dans le premier sujet)


@Ollivier : Les calculs sont justes à mon avis. Reviens sur le sujet du repère 3D et dis moi. Sur le repère 3D j'avais fais une erreur d'affichage. Était-ce la cause de ton doute ?

Ancienne version du code, c'est le code avant mise à jour du premier sujet

Code : Tout sélectionner

Structure Point3D
	x.d
	y.d
	z.d
EndStructure

Structure Star3D
	Position.Point3D
	Angle.Point3D
	Angle1.d
	Angle2.d
	Light.d
EndStructure

Global NewList Star.Star3D()
Global Star_Max_Light.d

Enumeration 
	#Pointer
	#Pointer3D
	#Selection
	#Selection3D
	#Box
	#Box3D
EndEnumeration

; Utilisation de PNG
UsePNGImageDecoder()

; précalcul des cos et sin
#Angle_Resolution = 100
Global Dim Calculation_Cos.d(360 * #Angle_Resolution)
Global Dim Calculation_Sin.d(360 * #Angle_Resolution)
For i = 0 To 360 * #Angle_Resolution
	Calculation_Cos(i) = Cos(i * #PI / (180 * #Angle_Resolution))
	Calculation_Sin(i) = Sin(i * #PI / (180 * #Angle_Resolution))
Next

Procedure Star_XYZ(*Star.Star3D, Atmosphere.d, Angle_X_Axis.d, Angle_Y_Axis.d, Angle_Z_Axis.d)
  ; Angle_X_Axis, ay, Angle_Z_Axis : angle de rotation du point sur l'Angle_X_Axise x, y et z, pour avoir un repère 3D décalé par rapport au repère de l'écran
  
  Protected Origine.Point3D, Calcul.Point3D, Sin.d, Cos.d
	
	Origine\x = Atmosphere * *Star\Angle\x
	Origine\y = Atmosphere * *Star\Angle\y
	Origine\z = Atmosphere * *Star\Angle\z
	
	; Rotation sur l'axe Z
	If Angle_Z_Axis
		; Cos = Cos(Angle_Z_Axis)
		; Sin = Sin(Angle_Z_Axis)
		Angle.i = Angle_Z_Axis * #Angle_Resolution * 180 / #PI
		Cos = Calculation_Cos(Angle)
		Sin = Calculation_Sin(Angle)
		Calcul\x = Origine\x * Cos - Origine\y * Sin
		Calcul\y = Origine\x * Sin + Origine\y * Cos
	Else
		Calcul\x = Origine\x
		Calcul\y = Origine\y
	EndIf
	; Debug StrD(Calcul\x) + " , " + StrD(Calcul\y) + " , " + StrD(Origine\z)
	
	; Rotation sur l'axe X
	If Angle_X_Axis
		; Cos = Cos(Angle_X_Axis)
		; Sin = Sin(Angle_X_Axis)
		Angle.i = Angle_X_Axis * #Angle_Resolution * 180 / #PI
		Cos = Calculation_Cos(Angle)
		Sin = Calculation_Sin(Angle)
		*Star\Position\y = Calcul\y * Cos - Origine\z * Sin
		Calcul\z = Calcul\y * Sin + Origine\z * Cos
	Else
		*Star\Position\y = Calcul\y
		Calcul\z = Origine\z
	EndIf
	; Debug StrD(Calcul\x) + " , " + StrD(*Star\Position\\y) + " , " + StrD(Calcul\z)
	
	; Rotation sur l'axe Y
	If Angle_Y_Axis
		; Cos = Cos(Angle_Y_Axis)
		; Sin = Sin(Angle_Y_Axis)
		Angle.i = Angle_Y_Axis * #Angle_Resolution * 180 / #PI
		Cos = Calculation_Cos(Angle)
		Sin = Calculation_Sin(Angle)
		*Star\Position\z = Calcul\z * Cos - Calcul\x * Sin
		*Star\Position\x = Calcul\z * Sin + Calcul\x * Cos
	Else
		*Star\Position\z = Calcul\z
		*Star\Position\x = Calcul\x
	EndIf
	; Debug StrD(*Star\Position\\x) + " , " + StrD(*Star\Position\\y) + " , " + StrD(*Star\Position\\z)
	
EndProcedure

Procedure Visibility(Variation.d) ; modilier la visibilité des étoiles (ciel plus ou moins clair)
	ForEach Star()
		Star()\Light + Variation
	Next
	LastElement(Star())
	Star_Max_Light = Star()\Light
EndProcedure

;{- Chargement des étoiles
If ReadFile(0, "Etoiles.list")
	
	Repeat
		; Lecture des données de l'étoile
		AddElement(Star())
		Star()\Angle1 = ReadDouble(0)
		Star()\Angle2 = ReadDouble(0)
		Star()\Light = ReadDouble(0)
		; précalcul
		Star()\Angle\z = Cos(Star()\Angle1 * #PI / 180) * Cos(Star()\Angle2 * #PI / 180)
		Star()\Angle\x = Sin(Star()\Angle1 * #PI / 180) * Cos(Star()\Angle2 * #PI / 180)
		Star()\Angle\y = -Sin(Star()\Angle2 * #PI / 180)
		
	Until Eof(0)
	
	; On trie les étoiles de la moins lumineuse à la plus lumineuse, de cette manière, on affiche les moins lumineuse en premier puis les plus lumineuse. 
	; Cela évite de dessiner une étoile moins lumineuse sur un étoile plus lumineuse ce qui donne des résultats bizarres, étoiles très lumineuse qui clignote car une étoile peu lumineuse est placé non loin.
	SortStructuredList(Star(), #PB_Sort_Ascending, OffsetOf(Star3D\Light), #PB_Sort_Double)
	
	CloseFile(0)
EndIf
;}

;{ Test de vitesse - Décommentez cette zone pour lancer le test
; Atmosphere.d = 1000
; Angle_X.d = 0.1
; Angle_Y.d = 0.1
; Angle_Z.d = 0.1
; 
; Temps1 = ElapsedMilliseconds()
; For nn = 1 To 50
	; ForEach Star()
		; Star_XYZ(@Star()\Position, Atmosphere, Angle_X, Angle_Y, Angle_Z)
	; Next
; Next
; Temps2 = ElapsedMilliseconds()
; 
; MessageRequester("Temps", Str(ListSize(Star())) + " étoiles" + Chr(10) + Str((Temps2 - Temps1)/50) + " ms")
; End
;}

;{- Ouverture de l'écran
ExamineDesktops()
Screen_Width = DesktopWidth(0)
Screen_Hight = DesktopHeight(0)

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

If OpenScreen(Screen_Width, Screen_Hight, 32, "Ecran", #PB_Screen_WaitSynchronization, DesktopFrequency(0)) = 0
  MessageRequester("Erreur", "Impossible d'ouvrir l'écran.", 0)
  End
EndIf
;}
;{- Chargement des sprites et polices
LoadSprite(#Pointer,  "Pointeur.png", #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
CreateSprite3D(#Pointer3D, #Pointer)
LoadSprite(#Selection,  "Selection.png", #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
CreateSprite3D(#Selection3D, #Selection)
LoadSprite(#Box,  "Bulle.png", #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
CreateSprite3D(#Box3D, #Box)

LoadFont(0, "Verdana", 9, #PB_Font_HighQuality)
;}

;{- Initialisation des valeurs
Define.d Angle_X, Angle_Y, Angle_Z, Atmosphere, Angle_X_Speed, Angle_Y_Speed, Angle_Z_Speed, FPS, Brake, Star_ScreenX, Star_ScreenY
Define.i Display_Center_X, Display_Center_Y, FPS_Counter, FPS_ElapsedTime
Define Search_Distance.d, Search_Time.i, Search_Display.i
Define *Search_Star.Star3D, *Search_LastStar.Star3D
Define.i MouseX, MouseY, MouseDX, MouseDY
Define Display_StarInfo_X, Display_StarInfo_Y, Display_StarInfo_CX, Display_StarInfo_CY, Display_StarInfo_Text.s
#Speed_Brake = 0.5
Visibility(-10)
Display_Center_X = Screen_Width / 2
Display_Center_Y = Screen_Hight / 2
Atmosphere = (Screen_Hight + Screen_Width) / 2
Angle_X = 0
Angle_Y = 0
FPS = 1
Display_StarInfo_X = Screen_Width - SpriteWidth(#Box) - 32
Display_StarInfo_Y = 32
Display_StarInfo_CX = Display_StarInfo_X + SpriteWidth(#Box) / 2
Display_StarInfo_CY = Display_StarInfo_Y + SpriteHeight(#Box) / 2
;}

Repeat
  ClearScreen($000000)
	
  ; On lit les évènements clavier et souris
  ExamineMouse()
  ExamineKeyboard()
  
  ; Position de la souris
  MouseX = MouseX()
  MouseY = MouseY()
	MouseDX = MouseDeltaX()
	MouseDY = MouseDeltaY()
	
	; Déplacement de la carte du ciel à la souris
	If MouseButton(#PB_MouseButton_Left)
		Angle_Y_Speed = MouseDX / 1000
	EndIf
	; Modification de l'angle d'affichage
	Brake = 1 - #Speed_Brake / FPS ; En ralentissant le mouvement de cette manière, on ne tient pas compte du FPS
	
	Angle_X + Angle_X_Speed
	If Angle_X > 2 * #PI
		Angle_X - 2 * #PI
	ElseIf Angle_X < 0
		Angle_X + 2 * #PI
	EndIf
	Angle_X_Speed * Brake
	
	Angle_Y + Angle_Y_Speed
	If Angle_Y > 2 * #PI
		Angle_Y - 2 * #PI
	ElseIf Angle_Y < 0
		Angle_Y + 2 * #PI
	EndIf
	Angle_Y_Speed * Brake
	
	Angle_Z + Angle_Z_Speed
	If Angle_Z > 2 * #PI
		Angle_Z - 2 * #PI
	ElseIf Angle_Z < 0
		Angle_Z + 2 * #PI
	EndIf
	Angle_Z_Speed * Brake
	
	; Affichage provisoire des étoiles
	StartDrawing(ScreenOutput())
		
		Search_Distance = 50
		*Search_LastStar = *Search_Star
		*Search_Star = 0
		ForEach Star()
			If Star()\Light > 0
				; Calcul de la position des étoiles
				Star_XYZ(@Star()\Position, Atmosphere, Angle_X, Angle_Y, Angle_Z)
				; Affichage de l'étoile, si elle est sur l'écran
				If Star()\Position\z > 0 And Star()\Position\x >= -Display_Center_X And Star()\Position\x < Display_Center_X - 1 And Star()\Position\y >= -Display_Center_Y And Star()\Position\y < Display_Center_Y - 1
					Star_Color = 155 * Star()\Light / Star_Max_Light + 100
					Star_ScreenX = Display_Center_X + Star()\Position\x
					Star_ScreenY = Display_Center_Y + Star()\Position\y
					Plot(Star_ScreenX, Star_ScreenY, RGB(Star_Color, Star_Color, Star_Color))
					; Recherche de l'étoile la plus proche de la souris
					Star_ScreenX - MouseX
					Star_ScreenY - MouseY
					If Star_ScreenX * Star_ScreenX + Star_ScreenY * Star_ScreenY < Search_Distance
						*Search_Star = @Star()
						Search_Distance = Star_ScreenX * Star_ScreenX + Star_ScreenY * Star_ScreenY
					EndIf
				EndIf
			EndIf
		Next
		If *Search_Star <> *Search_LastStar
			Search_Time = ElapsedMilliseconds()
		EndIf
		If *Search_Star <> 0 And ElapsedMilliseconds() - Search_Time > 250
			Search_Display = 1
		Else
			Search_Display = 0
		EndIf
		
		; Debogage
		DrawText(0, 0, "FPS : " + Str(FPS))
		DrawText(0, 20, "Angle X : " + StrD(Angle_X * 180 / #PI))
		DrawText(0, 40, "Angle Y : " + StrD(Angle_Y * 180 / #PI))
		DrawText(0, 60, "Angle Z : " + StrD(Angle_Z * 180 / #PI))
		If *Search_Star <> 0
			DrawText(0, 80, "Etoile angle 1 : " + StrD(*Search_Star\Angle1))
			DrawText(0, 100, "Etoile angle 2 : " + StrD(*Search_Star\Angle2))
		EndIf
		
	StopDrawing()
	
	If Start3D()
			
			; Affichage des étoiles
			
			
			; Affichage de la sélection
			If Search_Display
				DisplaySprite3D(#Box3D, Display_StarInfo_X, Display_StarInfo_Y)
				DisplaySprite3D(#Selection3D, Display_Center_X + *Search_Star\Position\x - 10, Display_Center_Y + *Search_Star\Position\y - 10)
			EndIf
			
			; Affichage du pointeur
			DisplaySprite3D(#Pointer3D, MouseX, MouseY)
			
		Stop3D()
	EndIf
  
	; Texte à afficher
	StartDrawing(ScreenOutput())
		DrawingMode(#PB_2DDrawing_Transparent)
		DrawingFont(FontID(0))
		If Search_Display ; Position de l'étoile sélectionnée
			Display_StarInfo_Text = StrD(*Search_Star\Angle1, 3) + " h , " + StrD(*Search_Star\Angle2, 3) + " °"
			DrawText(Display_StarInfo_CX - TextWidth(Display_StarInfo_Text) / 2, Display_StarInfo_CY - TextHeight(Display_StarInfo_Text) / 2, Display_StarInfo_Text, $FFFFFF)
		EndIf
	StopDrawing()
	
  FlipBuffers()
	
	; Calcul du FPS
	FPS_Counter + 1
	If FPS_Counter >= FPS
		FPS = FPS_Counter * 1000 / (ElapsedMilliseconds() - FPS_ElapsedTime)
		FPS_Counter = 0
		FPS_ElapsedTime = ElapsedMilliseconds()
	EndIf
	
	If IsScreenActive() = 0
		End
	EndIf
  
Until KeyboardPushed(#PB_Key_Escape)
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Nuit noire (Carte de ciel)

Message par Le Soldat Inconnu »

Code mis à jour dans le premier sujet

Copie du code précédent avant dernière modification

Code : Tout sélectionner

Structure Point3D
	x.d
	y.d
	z.d
EndStructure

Structure Star3D
	Display.Point3D
	Light.d
	Position.Point3D
	Angle.Point3D
	AngleRA.d
	AngleDE.d
	Magnitude.d
EndStructure

Global NewList Star.Star3D()

Enumeration 
	#Pointer
	#Pointer3D
	#Selection
	#Selection3D
	#Box
	#Box3D
EndEnumeration

Define.d Angle_X, Angle_Y, Angle_Z, Angle_X_Speed, Angle_Y_Speed, Angle_Z_Speed, FPS, Brake, Star_ScreenX, Star_ScreenY
Global Atmosphere.d
Define.d Atmosphere_Min, Atmosphere_Start
Global Visibility.d
Define.d Visibility_Max, Visibility_Start
Define Search_Distance.d, Search_Time.i, Search_Display.i
Define *Search_Star.Star3D, *Search_LastStar.Star3D
Define.i MouseX, MouseY, MouseDX, MouseDY, MouseX_Start, MouseY_Start
Define.i DebugMode
Define.i Display_Center_X, Display_Center_Y, FPS_Counter, FPS_ElapsedTime
Define Display_StarInfo_X, Display_StarInfo_Y, Display_StarInfo_CX, Display_StarInfo_CY, Display_StarInfo_Text.s
Define Display_Zoom_X, Display_Zoom_Y, Display_Zoom_CX, Display_Zoom_CY, Display_Zoom_Text.s
Define Display_Visibility_X, Display_Visibility_Y, Display_Visibility_CX, Display_Visibility_CY, Display_Visibility_Text.s

; Utilisation de PNG
UsePNGImageDecoder()

; précalcul des cos et sin
#Angle_Resolution = 100
Global Dim Calculation_Cos.d(360 * #Angle_Resolution)
Global Dim Calculation_Sin.d(360 * #Angle_Resolution)
For i = 0 To 360 * #Angle_Resolution
	Calculation_Cos(i) = Cos(i * #PI / (180 * #Angle_Resolution))
	Calculation_Sin(i) = Sin(i * #PI / (180 * #Angle_Resolution))
Next

Procedure Star_XYZ(*Star.Star3D, Atmosphere.d, Angle_X_Axis.d, Angle_Y_Axis.d, Angle_Z_Axis.d)
  ; Angle_X_Axis, ay, Angle_Z_Axis : angle de rotation du point sur l'Angle_X_Axise x, y et z, pour avoir un repère 3D décalé par rapport au repère de l'écran
  
  Protected Calcul.Point3D, Sin.d, Cos.d, Angle.i
	
	; Rotation sur l'axe Z
	If Angle_Z_Axis
		; Cos = Cos(Angle_Z_Axis)
		; Sin = Sin(Angle_Z_Axis)
		Angle.i = Angle_Z_Axis * #Angle_Resolution * 180 / #PI
		Cos = Calculation_Cos(Angle)
		Sin = Calculation_Sin(Angle)
		Calcul\x = *Star\Position\x * Cos - *Star\Position\y * Sin
		Calcul\y = *Star\Position\x * Sin + *Star\Position\y * Cos
	Else
		Calcul\x = *Star\Position\x
		Calcul\y = *Star\Position\y
	EndIf
	; Debug StrD(Calcul\x) + " , " + StrD(Calcul\y) + " , " + StrD(Origine\z)
	
	; Rotation sur l'axe X
	If Angle_X_Axis
		; Cos = Cos(Angle_X_Axis)
		; Sin = Sin(Angle_X_Axis)
		Angle.i = Angle_X_Axis * #Angle_Resolution * 180 / #PI
		Cos = Calculation_Cos(Angle)
		Sin = Calculation_Sin(Angle)
		*Star\Display\y = Calcul\y * Cos - *Star\Position\z * Sin
		Calcul\z = Calcul\y * Sin + *Star\Position\z * Cos
	Else
		*Star\Display\y = Calcul\y
		Calcul\z = *Star\Position\z
	EndIf
	; Debug StrD(Calcul\x) + " , " + StrD(*Star\Display\\y) + " , " + StrD(Calcul\z)
	
	; Rotation sur l'axe Y
	If Angle_Y_Axis
		; Cos = Cos(Angle_Y_Axis)
		; Sin = Sin(Angle_Y_Axis)
		Angle.i = Angle_Y_Axis * #Angle_Resolution * 180 / #PI
		Cos = Calculation_Cos(Angle)
		Sin = Calculation_Sin(Angle)
		*Star\Display\z = Calcul\z * Cos - Calcul\x * Sin
		*Star\Display\x = Calcul\z * Sin + Calcul\x * Cos
	Else
		*Star\Display\z = Calcul\z
		*Star\Display\x = Calcul\x
	EndIf
	; Debug StrD(*Star\Display\\x) + " , " + StrD(*Star\Display\\y) + " , " + StrD(*Star\Display\\z)
	
EndProcedure

Procedure Visibility() ; modilier la visibilité des étoiles (ciel plus ou moins clair)
	Protected Star_Max_Light.d
	LastElement(Star())
	Star_Max_Light = Abs(Visibility - Star()\Magnitude)
	ForEach Star()
		Star()\Light = (Visibility - Star()\Magnitude) / Star_Max_Light
	Next
EndProcedure

Procedure Position()
	ForEach Star()
		Star()\Position\x = Star()\Angle\x * Atmosphere
		Star()\Position\y = Star()\Angle\y * Atmosphere
		Star()\Position\z = Star()\Angle\z * Atmosphere
	Next
EndProcedure

;{- Chargement des étoiles
If ReadFile(0, "Etoiles.list")
	
	Repeat
		; Lecture des données de l'étoile
		AddElement(Star())
		Star()\AngleRA = ReadDouble(0)
		Star()\AngleDE = ReadDouble(0)
		Star()\Magnitude = ReadDouble(0)
		; précalcul
		Star()\Angle\z = Cos(Star()\AngleRA * #PI / 180) * Cos(Star()\AngleDE * #PI / 180)
		Star()\Angle\x = Sin(Star()\AngleRA * #PI / 180) * Cos(Star()\AngleDE * #PI / 180)
		Star()\Angle\y = -Sin(Star()\AngleDE * #PI / 180)
		
	Until Eof(0)
	
	; On trie les étoiles de la moins lumineuse à la plus lumineuse, de cette manière, on affiche les moins lumineuse en premier puis les plus lumineuse. 
	; Cela évite de dessiner une étoile moins lumineuse sur un étoile plus lumineuse ce qui donne des résultats bizarres, étoiles très lumineuse qui clignote car une étoile peu lumineuse est placé non loin.
	SortStructuredList(Star(), #PB_Sort_Descending, OffsetOf(Star3D\Magnitude), #PB_Sort_Double)
	
	CloseFile(0)
EndIf
;}

;{ Test de vitesse - Décommentez cette zone pour lancer le test
; Atmosphere.d = 1000
; Position()
; Angle_X.d = 0.1
; Angle_Y.d = 0.1
; Angle_Z.d = 0.1
; 
; Temps1 = ElapsedMilliseconds()
; For nn = 1 To 50
	; ForEach Star()
		; Star_XYZ(@Star()\Display, Atmosphere, Angle_X, Angle_Y, Angle_Z)
	; Next
; Next
; Temps2 = ElapsedMilliseconds()
; 
; MessageRequester("Temps", Str(ListSize(Star())) + " étoiles" + Chr(10) + Str((Temps2 - Temps1)/50) + " ms")
; End
;}

;{- Ouverture de l'écran
ExamineDesktops()
Screen_Width = DesktopWidth(0)
Screen_Hight = DesktopHeight(0)

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

If OpenScreen(Screen_Width, Screen_Hight, 32, "Ecran", #PB_Screen_WaitSynchronization, DesktopFrequency(0)) = 0
  MessageRequester("Erreur", "Impossible d'ouvrir l'écran.", 0)
  End
EndIf
;}
;{- Chargement des sprites et polices
LoadSprite(#Pointer,  "Pointeur.png", #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
CreateSprite3D(#Pointer3D, #Pointer)
LoadSprite(#Selection,  "Selection.png", #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
CreateSprite3D(#Selection3D, #Selection)
LoadSprite(#Box,  "Bulle.png", #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
CreateSprite3D(#Box3D, #Box)

LoadFont(0, "Verdana", 9, #PB_Font_HighQuality)
;}

;{- Initialisation des valeurs
Visibility = 8
FirstElement(Star())
Visibility_Max = Star()\Magnitude
Visibility()

Atmosphere = (Screen_Hight + Screen_Width) / 2
If Screen_Hight < Screen_Width
	Atmosphere_Min = Screen_Hight / 2
Else
	Atmosphere_Min = Screen_Width / 2
EndIf
Position()

#Speed_Brake = 0.5
Angle_X = 0
Angle_Y = 0

FPS = 1

Display_Center_X = Screen_Width / 2
Display_Center_Y = Screen_Hight / 2

Display_StarInfo_X = Screen_Width - SpriteWidth(#Box) - 32
Display_StarInfo_Y = 32
Display_StarInfo_CX = Display_StarInfo_X + SpriteWidth(#Box) / 2
Display_StarInfo_CY = Display_StarInfo_Y + SpriteHeight(#Box) / 2

Display_Zoom_X = Screen_Width / 2 + 32
Display_Zoom_Y = Screen_Hight / 2 - SpriteHeight(#Box) / 2
Display_Zoom_CX = Display_Zoom_X + SpriteWidth(#Box) / 2
Display_Zoom_CY = Display_Zoom_Y + SpriteHeight(#Box) / 2

Display_Visibility_X = Screen_Width / 2 - SpriteWidth(#Box) - 32
Display_Visibility_Y = Screen_Hight / 2 - SpriteHeight(#Box) / 2
Display_Visibility_CX = Display_Visibility_X + SpriteWidth(#Box) / 2
Display_Visibility_CY = Display_Visibility_Y + SpriteHeight(#Box) / 2
;}

Repeat
  ClearScreen($000000)
	
  ; On lit les évènements clavier et souris
  ExamineMouse()
  ExamineKeyboard()
  
  ; Position de la souris
  MouseX = MouseX()
  MouseY = MouseY()
	MouseDX = MouseDeltaX()
	MouseDY = MouseDeltaY()
	
	; Debogage
	If KeyboardReleased(#PB_Key_F1)
		DebugMode = 1 - DebugMode
	EndIf
	
	; Déplacement de la carte du ciel à la souris
	If MouseButton(#PB_MouseButton_Left)
		Angle_Y_Speed = MouseDX / Atmosphere
	EndIf
	; Modification de l'angle d'affichage
	Brake = 1 - #Speed_Brake / FPS ; En ralentissant le mouvement de cette manière, on ne tient pas compte du FPS
	
	Angle_X + Angle_X_Speed
	If Angle_X > 2 * #PI
		Angle_X - 2 * #PI
	ElseIf Angle_X < 0
		Angle_X + 2 * #PI
	EndIf
	Angle_X_Speed * Brake
	
	Angle_Y + Angle_Y_Speed
	If Angle_Y > 2 * #PI
		Angle_Y - 2 * #PI
	ElseIf Angle_Y < 0
		Angle_Y + 2 * #PI
	EndIf
	Angle_Y_Speed * Brake
	
	Angle_Z + Angle_Z_Speed
	If Angle_Z > 2 * #PI
		Angle_Z - 2 * #PI
	ElseIf Angle_Z < 0
		Angle_Z + 2 * #PI
	EndIf
	Angle_Z_Speed * Brake
	
	; Modification des paramètres
	If MouseButton(#PB_MouseButton_Right)
		If Display_Parameters = 0
			MouseX_Start = MouseX
			MouseY_Start = MouseY
			Atmosphere_Start = Atmosphere
			Visibility_Start = Visibility
		EndIf
		Display_Parameters = 1
		If MouseDY
			Atmosphere = Atmosphere_Start - (MouseY - MouseY_Start) * 5
			If Atmosphere < Atmosphere_Min
				Atmosphere = Atmosphere_Min
			EndIf
			Position()
		EndIf
		If MouseDX
			Visibility = Visibility_Start + (MouseX - MouseX_Start) / 50
			If Visibility < 0
				Visibility = 0
			ElseIf Visibility > Visibility_Max
				Visibility = Visibility_Max
			EndIf
			Visibility()
		EndIf
	Else
		Display_Parameters = 0
	EndIf
	
	
	; Affichage provisoire des étoiles
	StartDrawing(ScreenOutput())
		
		; Initialisation de la recherche de l'étoile la plus proche de la souris
		Search_Distance = 50
		*Search_LastStar = *Search_Star
		*Search_Star = 0
		Star_Counter = 0
		; Pour chaque étoile
		ForEach Star()
			If Star()\Light > 0
				; Calcul de la position des étoiles
				Star_XYZ(@Star()\Display, Atmosphere, Angle_X, Angle_Y, Angle_Z)
				; Affichage de l'étoile, si elle est sur l'écran
				If Star()\Display\z > 0 And Star()\Display\x >= -Display_Center_X And Star()\Display\x < Display_Center_X - 1 And Star()\Display\y >= -Display_Center_Y And Star()\Display\y < Display_Center_Y - 1
					Star_Color = 255 * Star()\Light
					Star_ScreenX = Display_Center_X + Star()\Display\x
					Star_ScreenY = Display_Center_Y + Star()\Display\y
					Star_Counter + 1
					Plot(Star_ScreenX, Star_ScreenY, RGB(Star_Color, Star_Color, Star_Color))
					; Recherche de l'étoile la plus proche de la souris
					Star_ScreenX - MouseX
					Star_ScreenY - MouseY
					If Star_ScreenX * Star_ScreenX + Star_ScreenY * Star_ScreenY < Search_Distance
						*Search_Star = @Star()
						Search_Distance = Star_ScreenX * Star_ScreenX + Star_ScreenY * Star_ScreenY
					EndIf
				EndIf
			EndIf
		Next
		; Fin de la recherche de l'étoile la plus proche de la souris
		If *Search_Star <> *Search_LastStar
			Search_Time = ElapsedMilliseconds()
		EndIf
		If *Search_Star <> 0 And ElapsedMilliseconds() - Search_Time > 250
			Search_Display = 1
		Else
			Search_Display = 0
		EndIf
		
	StopDrawing()
	
	If Start3D()
			
			; Affichage des étoiles
			
			
			
			If Display_Parameters
				; Affichage des paramètres
				DisplaySprite3D(#Box3D, Display_Zoom_X, Display_Zoom_Y)
				DisplaySprite3D(#Box3D, Display_Visibility_X, Display_Visibility_Y)
			Else
				If Search_Display
					; Affichage de la sélection
					DisplaySprite3D(#Box3D, Display_StarInfo_X, Display_StarInfo_Y)
					DisplaySprite3D(#Selection3D, Display_Center_X + *Search_Star\Display\x - 10, Display_Center_Y + *Search_Star\Display\y - 10)
				EndIf
			EndIf
			; Affichage du pointeur
			DisplaySprite3D(#Pointer3D, MouseX, MouseY)
			
		Stop3D()
	EndIf
  
	; Texte à afficher
	StartDrawing(ScreenOutput())
		DrawingMode(#PB_2DDrawing_Transparent)
		DrawingFont(FontID(0))
		If Display_Parameters ; Affichage des paramètres
			Display_Zoom_Text = "Zoom x" + StrD(Atmosphere / Atmosphere_Min, 1)
			DrawText(Display_Zoom_CX - TextWidth(Display_Zoom_Text) / 2, Display_Zoom_CY - TextHeight(Display_Zoom_Text) / 2, Display_Zoom_Text, $FFFFFF)
			Display_Visibility_Text = "Visibilité = " + StrD(100 * Visibility / Visibility_Max, 0) + "%"
			DrawText(Display_Visibility_CX - TextWidth(Display_Visibility_Text) / 2, Display_Visibility_CY - TextHeight(Display_Visibility_Text) / 2, Display_Visibility_Text, $FFFFFF)
		ElseIf Search_Display ; Position de l'étoile sélectionnée
			Display_StarInfo_Text = StrD(*Search_Star\AngleRA, 3) + " h , " + StrD(*Search_Star\AngleDE, 3) + " °"
			DrawText(Display_StarInfo_CX - TextWidth(Display_StarInfo_Text) / 2, Display_StarInfo_CY - TextHeight(Display_StarInfo_Text) / 2, Display_StarInfo_Text, $FFFFFF)
		EndIf
		
		If DebugMode
			; Debogage
			DrawText(0, 0, "FPS : " + Str(FPS))
			DrawText(0, 20, "Angle X : " + StrD(Angle_X * 180 / #PI))
			DrawText(0, 40, "Angle Y : " + StrD(Angle_Y * 180 / #PI))
			DrawText(0, 60, "Angle Z : " + StrD(Angle_Z * 180 / #PI))
			DrawText(0, 80, "Etoiles affichées : " + Str(Star_Counter))
			If *Search_Star <> 0
				DrawText(0, 100, "Etoile angle 1 : " + StrD(*Search_Star\AngleRA))
				DrawText(0, 120, "Etoile angle 2 : " + StrD(*Search_Star\AngleDE))
			EndIf
		EndIf
		
	StopDrawing()
	
  FlipBuffers()
	
	; Calcul du FPS
	FPS_Counter + 1
	If FPS_Counter >= FPS
		FPS = FPS_Counter * 1000 / (ElapsedMilliseconds() - FPS_ElapsedTime)
		FPS_Counter = 0
		FPS_ElapsedTime = ElapsedMilliseconds()
	EndIf
	
	If IsScreenActive() = 0
		End
	EndIf
  
Until KeyboardPushed(#PB_Key_Escape)
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

Re: Nuit noire (Carte de ciel)

Message par kelebrindae »

Le Soldat Inconnu a écrit :En tous cas, c'est mieux car j'arrive à voir la grande ourse
Je crois que je l'ai trouvée aussi: la casserole commence à 165.933H, 61.751° et le manche finit à 206.886H, 49.313°, c'est ça ?

Mais si oui, une question me vient à l'esprit: est-il normal que la Grande Ourse, c'est-à-dire l'Etoile Polaire (repère traditionnel pour le nord) se trouve aux environs de 180H ? Je m'attendrais plutôt à trouver le nord à 0H... :?

Au fait: je trouve ce code génial! On a vraiment l'impression de regarder le ciel par une nuit d'été (et je trouve l'ergonomie plutôt sympa). Bravo!
Les idées sont le souvenir de choses qui ne se sont pas encore produites.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Nuit noire (Carte de ciel)

Message par Backup »

kelebrindae a écrit : est-il normal que la Grande Ourse, c'est-à-dire l'Etoile Polaire (repère traditionnel pour le nord) se trouve aux environs de 180H ? Je m'attendrais plutôt à trouver le nord à 0H...
je precise que je n'ai pas testé le prg
mais je répondrai que tout dépend du repere de réference

en effet l'etoile polaire est alignée sur le pole nord de notre planete
pas sur le centre de la galaxie ! (plutot en direction de la "voie lactée") ;)
Avatar de l’utilisateur
flaith
Messages : 1487
Inscription : jeu. 07/avr./2005 1:06
Localisation : Rennes
Contact :

Re: Nuit noire (Carte de ciel)

Message par flaith »

8O bo c'est, manquerait plus que certaines clignotent :D
boddhi
Messages : 573
Inscription : lun. 26/avr./2010 16:14
Localisation : N 48° 1' 33.6" / E 0° 36' 11.3"

Re: Nuit noire (Carte de ciel)

Message par boddhi »

kelebrindae a écrit :est-il normal que la Grande Ourse, c'est-à-dire l'Etoile Polaire
???

L'étoile polaire fait partie de la petite ourse... :wink:
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Nuit noire (Carte de ciel)

Message par Le Soldat Inconnu »

je travaille sur la rotation de la carte sur les 3 axes, mais c'est dur dur. Comme ça, on pourra voir le ciel dans la bonne direction (avec le nord au milieu de l'écran)
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Répondre