3D vers 2D avec perspective

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
kernadec
Messages : 1606
Inscription : ven. 25/avr./2008 11:14

Re: 3D vers 2D avec perspective

Message par kernadec »

:mrgreen: :mrgreen: je dois que reconnaitre aussi que ce mode de lecture m'avait échappé

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

Re: 3D vers 2D avec perspective

Message par Le Soldat Inconnu »

j'ai repris le code d'Olivier à ma sauce histoire de bien tout comprendre :D

Et j'ai corrigé quelque soucis sur le sens de rotation, pour toujours avoir les rotations dans le sens trigo, avec la perspective, c'est plus facile à voir (touche P)

Pour faire tourner le repère, c'est les touches X Y Z I J K, voir commentaires dans le code

Code : Tout sélectionner

; Auteur : Le Soldat Inconnu
; Version de PB :  4.5

; Explication du programme :
; Exemple qui montre comment dessiner un repère IJK en 3D dans le XYZ (l'écran)

; Repère XYZ (l'écran)
; X : Ligne horizontal, sens + vers la droite
; Y : Ligne vertical, sens + vers le haut
; Z : Perpendiculaire à la surface de l'écran, sens + vers soi 

; Repère  IJK
; Votre objet 3D est représenté avec des coordonnées dans le repère IJK qui ensuite affiché dans le repère XYZ (l'écran) en fonction des angles de rotation entre le repère IJK et le repère XYZ

; Angle
; En radian, le sens de rotation est le sens trigonométrique (une rotation d'un angle positif fait tourner l'objet dans le sens trigonométrique, quand vous avez l'axe qui vient vers votre regard (sens + vers vous))

; Touche d'utilisation :
; Enter : Retour à l'origine (Initialise le repère IJK sur le repère XYZ)
; P : Mode perspective
; X : Change l'angle sur l'axe X
; Y : Change l'angle sur l'axe Y
; Z : Change l'angle sur l'axe Z
; I : Change l'angle sur l'axe I
; J : Change l'angle sur l'axe J
; K : Change l'angle sur l'axe K

#Optimisation = 1

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 Point3DP
	x.d
	y.d
	z.d
	p.d
EndStructure

CompilerIf #Optimisation
	#Angle_Resolution = 500
	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 Rotation_Origine(*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 Rotation_Axe_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 Rotation_Axe_Calcul(Axe1, Axe2, Cos, Sin)
	x = Axe1
	Axe1 = x * Cos - Axe2 * Sin
	Axe2 = Axe2 * Cos + x * Sin
EndMacro
Procedure Rotation_Axe_X(*Repere.Repere3D, Angle.d)
	Protected Cos.d, Sin.d, x.d
	
	Rotation_Axe_Angle()
	
	Rotation_Axe_Calcul(*Repere\iy, *Repere\iz, Cos, Sin)
	Rotation_Axe_Calcul(*Repere\jy, *Repere\jz, Cos, Sin)
	Rotation_Axe_Calcul(*Repere\ky, *Repere\kz, Cos, Sin)
	
EndProcedure
Procedure Rotation_Axe_Y(*Repere.Repere3D, Angle.d)
	Protected Cos.d, Sin.d, x.d
	
	Rotation_Axe_Angle()
	
	Rotation_Axe_Calcul(*Repere\iz, *Repere\ix, Cos, Sin)
	Rotation_Axe_Calcul(*Repere\jz, *Repere\jx, Cos, Sin)
	Rotation_Axe_Calcul(*Repere\kz, *Repere\kx, Cos, Sin)
	
EndProcedure
Procedure Rotation_Axe_Z(*Repere.Repere3D, Angle.d)
	Protected Cos.d, Sin.d, x.d
	
	Rotation_Axe_Angle()
	
	Rotation_Axe_Calcul(*Repere\ix, *Repere\iy, Cos, Sin)
	Rotation_Axe_Calcul(*Repere\jx, *Repere\jy, Cos, Sin)
	Rotation_Axe_Calcul(*Repere\kx, *Repere\ky, Cos, Sin)
	
EndProcedure
Procedure Rotation_Axe_I(*Repere.Repere3D, Angle.d)
	Protected Cos.d, Sin.d, x.d
	
	Rotation_Axe_Angle()
	
	Rotation_Axe_Calcul(*Repere\kx, *Repere\jx, Cos, Sin)
	Rotation_Axe_Calcul(*Repere\ky, *Repere\jy, Cos, Sin)
	Rotation_Axe_Calcul(*Repere\kz, *Repere\jz, Cos, Sin)
	
EndProcedure
Procedure Rotation_Axe_J(*Repere.Repere3D, Angle.d)
	Protected Cos.d, Sin.d, x.d
	
	Rotation_Axe_Angle()
	
	Rotation_Axe_Calcul(*Repere\ix, *Repere\kx, Cos, Sin)
	Rotation_Axe_Calcul(*Repere\iy, *Repere\ky, Cos, Sin)
	Rotation_Axe_Calcul(*Repere\iz, *Repere\kz, Cos, Sin)
	
EndProcedure
Procedure Rotation_Axe_K(*Repere.Repere3D, Angle.d)
	Protected Cos.d, Sin.d, x.d
	
	Rotation_Axe_Angle()
	
	Rotation_Axe_Calcul(*Repere\jx, *Repere\ix, Cos, Sin)
	Rotation_Axe_Calcul(*Repere\jy, *Repere\iy, Cos, Sin)
	Rotation_Axe_Calcul(*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 XYZ_P(*Repere.Repere3D, *PointIJK.Point3D, *PointXYZ.Point3DP, Perspective.q)
	*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
	
	*PointXYZ\p = 1 + Abs(*PointXYZ\z) / Perspective
	If *PointXYZ\z < 0
		*PointXYZ\p = 1 / *PointXYZ\p
	EndIf
	*PointXYZ\x * *PointXYZ\p
	*PointXYZ\y * *PointXYZ\p
	
EndProcedure


If InitSprite() = 0
	End
EndIf

If OpenWindow(0, 0, 0, 500, 500, "Repère 3D", #PB_Window_ScreenCentered | #PB_Window_SystemMenu) = 0
	End
EndIf

If OpenWindowedScreen(WindowID(0), 0, 0, 500, 500, 1, 0, 0) = 0
	End
EndIf

Rotation_Origine(@Repere)

Axe_I.Point3D
Axe_I\x = 200
Axe_J.Point3D
Axe_J\y = 200
Axe_K.Point3D
Axe_K\z = 200

FontID = LoadFont(0, "Verdana", 8, #PB_Font_HighQuality)

Repeat
	
	ClearScreen($FFFFFF)
	
	StartDrawing(ScreenOutput())
		DrawingFont(FontID)
		DrawingMode(#PB_2DDrawing_Transparent)
		
		; On affiche le repère
		; la ligne représentant l'axe I en vert
		If Perspective
			XYZ_P(@Repere, @Axe_I, @Coord.Point3DP, 400) ; on calcul les coordonnées de l'extrémité de la ligne pour l'affichage sur l'écran
			Circle(250 + Coord\x, 250 - Coord\y, 5 * Coord\p, RGB(0, 255, 0)) ; on trace un cerle sur le bout de la ligne. La variable Coord\p permet de prendre en compte la perspective sur une forme de taille définie, ici un cercle mais également une image par exemple.
		Else
			XYZ(@Repere, @Axe_I, @Coord.Point3DP)
			Circle(250 + Coord\x, 250 - Coord\y, 5, RGB(0, 255, 0)) ; on trace un cerle sur le bout de la ligne. La variable Coord\p permet de prendre en compte la perspective sur une forme de taille définie, ici un cercle mais également une image par exemple.
		EndIf
		LineXY(250, 250, 250 + Coord\x, 250 - Coord\y, RGB(0, 255, 0)) ; on trace une ligne verte à partir du centre de l'image vers les coordonnées calculées
		DrawText(255 + Coord\x, 255 - Coord\y, "I", 0) ; On affiche le label de l'axe
		
		; la ligne représentant l'axe J en rouge
		If Perspective
			XYZ_P(@Repere, @Axe_J, @Coord.Point3DP, 400) ; on calcul les coordonnées de l'extrémité de la ligne pour l'affichage sur l'écran
			Circle(250 + Coord\x, 250 - Coord\y, 5 * Coord\p, RGB(255, 0, 0))
		Else
			XYZ(@Repere, @Axe_J, @Coord.Point3DP)
			Circle(250 + Coord\x, 250 - Coord\y, 5, RGB(255, 0, 0))
		EndIf
		LineXY(250, 250, 250 + Coord\x, 250 - Coord\y, RGB(255, 0, 0))
		DrawText(255 + Coord\x, 255 - Coord\y, "J", 0)
		
		; la ligne représentant l'axe K en bleu
		If Perspective
			XYZ_P(@Repere, @Axe_K, @Coord.Point3DP, 400) ; on calcul les coordonnées de l'extrémité de la ligne pour l'affichage sur l'écran
			Circle(250 + Coord\x, 250 - Coord\y, 5 * Coord\p, RGB(0, 0, 255))
		Else
			XYZ(@Repere, @Axe_K, @Coord.Point3DP)
			Circle(250 + Coord\x, 250 - Coord\y, 5, RGB(0, 0, 255))
		EndIf
		LineXY(250, 250, 250 + Coord\x, 250 - Coord\y, RGB(0, 0, 255))
		DrawText(255 + Coord\x, 255 - Coord\y, "K", 0)
		
	StopDrawing()
	
	FlipBuffers()
	
	Repeat
		Event = WindowEvent()
		
		If Event = #WM_KEYDOWN
			Select EventwParam()
				Case 'P'
					Perspective = 1 - Perspective
				Case 'X'
					Rotation_Axe_X(@Repere, #PI / 6)
				Case 'Y'
					Rotation_Axe_Y(@Repere, #PI / 6)
				Case 'Z'
					Rotation_Axe_Z(@Repere, #PI / 6)
				Case 'I'
					Rotation_Axe_I(@Repere, #PI / 6)
				Case 'J'
					Rotation_Axe_J(@Repere, #PI / 6)
				Case 'K'
					Rotation_Axe_K(@Repere, #PI / 6)
				Case 13
					Rotation_Origine(@Repere)
			EndSelect
		EndIf
		
		If Event = #PB_Event_CloseWindow
			End
		EndIf
		
	Until Event = 0
	
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)]
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: 3D vers 2D avec perspective

Message par graph100 »

Eh bien, je crois que ce post corrige à peu près tout les codes en pseudo 3d que j'ai fait !
J'ai toujours eu le même problème que toi au début. (avec les mêmes cours de méca je pense xD)

Merci LSI et Olliver !
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: 3D vers 2D avec perspective

Message par Backup »

.........
Dernière modification par Backup le dim. 02/oct./2011 12:42, modifié 1 fois.
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: 3D vers 2D avec perspective

Message par G-Rom »

voila en tout cas ce qui représente pour moi une limite infranchissable
(de ma compréhension ) , n’étant pas allé assez loin dans les études ...
(pensez donc.. la 6em redoublée en plus.. )
Je n'ai pas été une flèche non plus à l'école , j'ai même pas le brevet des collèges , j'ai redoublé 2x...
la 6° & la 5°... je préférais faire le petit caïd... j'ai pas été plus loin que la seconde...
ca ne m'empêche pas de me lancer dans des trucs qui me dépasse complétement , et c'est là que l'on s'aperçoit que beaucoup de choses
sont basé sur des trucs simple , la 3D en fait partie , y a rien de compliqué en réalité.
Image
Le plan ( le carré à droite , c'est ton écran :) )
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: 3D vers 2D avec perspective

Message par graph100 »

aha !! oui mais ça c'est la 3d bricolée ;)

un peu comme le code suivant : (non corrigé selon la méthode expliquée ici ;'( pas le temps XD ) :

touche :

Code : Tout sélectionner

  If KeyboardPushed(#PB_Key_Pad7) : rot_x - vit : EndIf
  If KeyboardPushed(#PB_Key_Pad8) : rot_x + vit : EndIf
  If KeyboardPushed(#PB_Key_Pad4) : rot_y - vit : EndIf
  If KeyboardPushed(#PB_Key_Pad5) : rot_y + vit : EndIf
  If KeyboardPushed(#PB_Key_Pad1) : rot_z - vit : EndIf
  If KeyboardPushed(#PB_Key_Pad2) : rot_z + vit : EndIf
  
  If KeyboardPushed(#PB_Key_Pad9) : zoom * 1.5 : EndIf
  If KeyboardPushed(#PB_Key_Pad3) : zoom / 1.5 : EndIf
  
  If KeyboardPushed(#PB_Key_PageUp) : fact + 0.002 : EndIf
  If KeyboardPushed(#PB_Key_PageDown) : fact - 0.002 : EndIf
  
  If KeyboardPushed(#PB_Key_F1) : mode = 0 : EndIf
  If KeyboardPushed(#PB_Key_F2) : mode = 1 : EndIf
  If KeyboardPushed(#PB_Key_F3) : mode = 2 : EndIf

Code : Tout sélectionner

; tr = 40
; mo = 20 
tr = 10
mo = 10
l = 50

dimension = tr * mo - 1
dimension_t = mo - 1

Procedure.d Convert1(degre.d, radian.d) ; Convertti un nombre en degré en radian ou si degre = 0, le contraire
  If degre = 0
    ProcedureReturn ((180 * radian) / #PI)
  EndIf
  ProcedureReturn ((#PI * degre) / 180)
EndProcedure

Procedure FillTriangle(x1, y1, x2, y2, x3, y3, color) 
  For boucle = 0 To 1 
    If x1 > x2 : x = x2 : x2 = x1 : x1 = x : y = y2 : y2 = y1 : y1 = y :  EndIf 
    If x2 > x3 : x = x3 : x3 = x2 : x2 = x : y = y3 : y3 = y2 : y2 = y :  EndIf 
  Next
  
  If x1 = x2
    
  Else
    a.d = (y2 - y1) / (x2 - x1)
    b.d = y2 - a * x2
    
    a1.d = (y1 - y3) / (x1 - x3)
    b1.d = y3 - a1 * x3
    
    For x = x1 To x2
      LineXY(x, a * x + b, x, a1 * x + b1, color)
    Next
  EndIf
  
  If x2 = x3
    
  Else
    a.d = (y2 - y3) / (x2 - x3)
    b.d = y2 - a * x2
    
    a1.d = (y1 - y3) / (x1 - x3)
    b1.d = y1 - a1 * x1
    
    For x = x2 To x3
      LineXY(x, a * x + b, x, a1 * x + b1, color)
    Next
  EndIf
  
EndProcedure

Structure FACE
  x1.d
  y1.d
  z1.d
  
  x2.d
  y2.d
  z2.d
  
  x3.d
  y3.d
  z3.d
  
  x4.d
  y4.d
  z4.d
  
  z_min.d
  color.l
EndStructure

Structure List
  dimension.l
  adresse.l
  x.d
  y.d
  z.d
EndStructure

Procedure Cube(*objet.FACE, centre_x, centre_y, centre_z, cote); le tableau objet devrait faire 5 en taille, pour ne pas generer des erreurs
  Dim obj_cube.FACE(5)
  
  cote / 2
  
  ;{ calcul des faces
  obj_cube(0)\x1 = centre_x - cote
  obj_cube(0)\x2 = centre_x - cote
  obj_cube(0)\x3 = centre_x + cote
  obj_cube(0)\x4 = centre_x + cote
  
  obj_cube(0)\y1 = centre_y + cote
  obj_cube(0)\y2 = centre_y - cote
  obj_cube(0)\y3 = centre_y - cote
  obj_cube(0)\y4 = centre_y + cote
  
  obj_cube(0)\z1 = centre_z + cote
  obj_cube(0)\z2 = centre_z + cote
  obj_cube(0)\z3 = centre_z + cote
  obj_cube(0)\z4 = centre_z + cote
  obj_cube(0)\z_min = centre_z + cote
  obj_cube(0)\color = RGB(255, 0, 0)
  
  
  obj_cube(1)\x1 = centre_x - cote
  obj_cube(1)\x2 = centre_x - cote
  obj_cube(1)\x3 = centre_x + cote
  obj_cube(1)\x4 = centre_x + cote
  
  obj_cube(1)\y1 = centre_y + cote
  obj_cube(1)\y2 = centre_y + cote
  obj_cube(1)\y3 = centre_y + cote
  obj_cube(1)\y4 = centre_y + cote
  
  obj_cube(1)\z1 = centre_z + cote
  obj_cube(1)\z2 = centre_z - cote
  obj_cube(1)\z3 = centre_z - cote
  obj_cube(1)\z4 = centre_z + cote
  obj_cube(1)\z_min = centre_z - cote
  obj_cube(1)\color = RGB(255, 255, 0)
  
  
  obj_cube(2)\x1 = centre_x - cote
  obj_cube(2)\x2 = centre_x - cote
  obj_cube(2)\x3 = centre_x + cote
  obj_cube(2)\x4 = centre_x + cote
  
  obj_cube(2)\y1 = centre_y + cote
  obj_cube(2)\y2 = centre_y - cote
  obj_cube(2)\y3 = centre_y - cote
  obj_cube(2)\y4 = centre_y + cote
  
  obj_cube(2)\z1 = centre_z - cote
  obj_cube(2)\z2 = centre_z - cote
  obj_cube(2)\z3 = centre_z - cote
  obj_cube(2)\z4 = centre_z - cote
  obj_cube(2)\z_min = centre_z - cote
  obj_cube(2)\color = RGB(255, 0, 255)
  
  
  obj_cube(3)\x1 = centre_x - cote
  obj_cube(3)\x2 = centre_x - cote
  obj_cube(3)\x3 = centre_x + cote
  obj_cube(3)\x4 = centre_x + cote
  
  obj_cube(3)\y1 = centre_y - cote
  obj_cube(3)\y2 = centre_y - cote
  obj_cube(3)\y3 = centre_y - cote
  obj_cube(3)\y4 = centre_y - cote
  
  obj_cube(3)\z1 = centre_z + cote
  obj_cube(3)\z2 = centre_z - cote
  obj_cube(3)\z3 = centre_z - cote
  obj_cube(3)\z4 = centre_z + cote
  obj_cube(3)\z_min = centre_z - cote
  obj_cube(3)\color = RGB(0, 255, 255)
  
  
  obj_cube(4)\x1 = centre_x - cote
  obj_cube(4)\x2 = centre_x - cote
  obj_cube(4)\x3 = centre_x - cote
  obj_cube(4)\x4 = centre_x - cote
  
  obj_cube(4)\y1 = centre_y + cote
  obj_cube(4)\y2 = centre_y + cote
  obj_cube(4)\y3 = centre_y - cote
  obj_cube(4)\y4 = centre_y - cote
  
  obj_cube(4)\z1 = centre_z + cote
  obj_cube(4)\z2 = centre_z - cote
  obj_cube(4)\z3 = centre_z - cote
  obj_cube(4)\z4 = centre_z + cote
  obj_cube(4)\z_min = centre_z - cote
  obj_cube(4)\color = RGB(0, 255, 0)
  
  
  obj_cube(5)\x1 = centre_x + cote
  obj_cube(5)\x2 = centre_x + cote
  obj_cube(5)\x3 = centre_x + cote
  obj_cube(5)\x4 = centre_x + cote
  
  obj_cube(5)\y1 = centre_y + cote
  obj_cube(5)\y2 = centre_y + cote
  obj_cube(5)\y3 = centre_y - cote
  obj_cube(5)\y4 = centre_y - cote
  
  obj_cube(5)\z1 = centre_z + cote
  obj_cube(5)\z2 = centre_z - cote
  obj_cube(5)\z3 = centre_z - cote
  obj_cube(5)\z4 = centre_z + cote
  obj_cube(5)\z_min = centre_z - cote
  obj_cube(5)\color = RGB(0, 0, 255)
  ;}
  
  ; copie du tableau passer en parametre
  CopyMemory(obj_cube(), *objet, SizeOf(FACE) * 6)
EndProcedure

Procedure Sphere(*objet.FACE, centre_x.d, centre_y.d, centre_z.d, rayon.d, tranche, morceau, color)
  Dim Obj_S.FACE(tranche * morceau - 1)
  
  epais.d = rayon * 2 / tranche
  ang.d = 2 * #PI / morceau
  
  c = 0
  
  For a = 1 To tranche
    dist.d = Abs((a - 1) * epais - rayon)
    dist = rayon * rayon - dist * dist
    If dist < 0 : dist = 0 : EndIf
    ray_pla_1.d = Sqr(dist)
    
    dist.d = Abs(a * epais - rayon)
    dist = rayon * rayon - dist * dist
    If dist < 0 : dist = 0 : EndIf
    ray_pla.d = Sqr(dist)
    
    For b = 1 To morceau
      
      Obj_S(c)\x1 = ray_pla * Cos(ang * (b - 1)) + centre_x
      Obj_S(c)\x2 = ray_pla_1 * Cos(ang * (b - 1)) + centre_x
      Obj_S(c)\x3 = ray_pla_1 * Cos(b * ang) + centre_x
      Obj_S(c)\x4 = ray_pla * Cos(b * ang) + centre_x
      
      Obj_S(c)\y1 = a * epais - rayon + centre_y
      Obj_S(c)\y2 = (a - 1) * epais - rayon + centre_y
      Obj_S(c)\y3 = (a - 1) * epais - rayon + centre_y
      Obj_S(c)\y4 = a * epais - rayon + centre_y
      
      Obj_S(c)\z1 = ray_pla * Sin(ang * (b - 1)) + centre_z
      Obj_S(c)\z2 = ray_pla_1 * Sin(ang * (b - 1)) + centre_z
      Obj_S(c)\z3 = ray_pla_1 * Sin(b * ang) + centre_z
      Obj_S(c)\z4 = ray_pla * Sin(b * ang) + centre_z
      
;       Obj_S(c)\color = RGB(255 * b / morceau, 0, 255 * a / tranche)
      Obj_S(c)\color = color
      
      c + 1
    Next
  Next
  
  CopyMemory(obj_S(), *objet, SizeOf(FACE) * tranche * morceau)
  Dim Obj_S.FACE(0)
EndProcedure

Procedure Tube(*objet.FACE, x1.d, y1.d, z1.d, x2.d, y2.d, z2.d, rayon.d, morceau.l, color.l)
  Dim Obj_T.FACE(morceau - 1)
  
  a.d = x2 - x1
  b.d = y2 - y1
  c.d = z2 - z1
  
  dist.d = Sqr(a * a + b * b + c * c)
  
  a = rayon * a / dist
  b = rayon * b / dist
  c = rayon * c / dist
  
  distab.d = Sqr(a * a + b * b)
  If distab
    alpha.d = ACos(a / distab)
    If b < 0
      alpha = - alpha
    EndIf
  Else
    alpha.d = 0
  EndIf 
  If rayon
    phi.d = ACos(distab / rayon)
    If c < 0
      phi = -phi
    EndIf
  Else
    phi.d = 0
  EndIf
  
  ang.d = 2 * #PI / morceau
  
  cos_alpha.d = Cos(alpha)
  sin_alpha.d = Sin(alpha)
  cos_phi.d = Cos(phi)
  sin_phi.d = Sin(phi)
  
  For curs = 0 To morceau - 1
    
    Obj_T(curs)\x1 = rayon * (-Sin(curs * ang) * sin_phi * cos_alpha - Cos(curs * ang) * sin_alpha) + x1
    Obj_T(curs)\x2 = rayon * (-Sin(curs * ang + ang) * sin_phi * cos_alpha - Cos(curs * ang + ang) * sin_alpha) + x1
    Obj_T(curs)\x3 = rayon * (-Sin(curs * ang + ang) * sin_phi * cos_alpha - Cos(curs * ang + ang) * sin_alpha) + x2
    Obj_T(curs)\x4 = rayon * (-Sin(curs * ang) * sin_phi * cos_alpha - Cos(curs * ang) * sin_alpha) + x2
    
    Obj_T(curs)\y1 = rayon * (-Sin(curs * ang) * sin_phi * sin_alpha + Cos(curs * ang) * cos_alpha) + y1
    Obj_T(curs)\y2 = rayon * (-Sin(curs * ang + ang) * sin_phi * sin_alpha + Cos(curs * ang + ang) * cos_alpha) + y1
    Obj_T(curs)\y3 = rayon * (-Sin(curs * ang + ang) * sin_phi * sin_alpha + Cos(curs * ang + ang) * cos_alpha) + y2
    Obj_T(curs)\y4 = rayon * (-Sin(curs * ang) * sin_phi * sin_alpha + Cos(curs * ang) * cos_alpha) + y2
    
    Obj_T(curs)\z1 = rayon * (Sin(curs * ang) * cos_phi) + z1
    Obj_T(curs)\z2 = rayon * (Sin(curs * ang + ang) * cos_phi) + z1
    Obj_T(curs)\z3 = rayon * (Sin(curs * ang + ang) * cos_phi) + z2
    Obj_T(curs)\z4 = rayon * (Sin(curs * ang) * cos_phi) + z2
    
    Obj_T(curs)\color = color
    
  Next
  
  CopyMemory(Obj_T(), *objet, SizeOf(FACE) * morceau)
  Dim Obj_T.FACE(0)
EndProcedure

Procedure Tore(*objet.FACE, centre_x, centre_y, centre_z, rayon_tore, dist_centre_cercle, tranche, morceau)
  Dim Obj_T.FACE(tranche * morceau - 1)
  
  ang1.d = 2 * #PI / tranche
  ang.d = 2 * #PI / morceau
  
  
  
  CopyMemory(obj_T(), *objet, SizeOf(FACE) * tranche * morceau)
  Dim Obj_T.FACE(0)
EndProcedure

Procedure Display_3D(*objet.FACE, dimension, x_center.l, y_center.l, rotX.d, rotY.d, rotZ.d, Effect_rotation.l, zoom.d, zooZ.d, facteur_perspective.d, mode.l)
;   rotX.d                  ; angle en degré de rotation sur l'axe X
;   rotY.d                  ; angle en degré de rotation sur l'axe Y
;   rotZ.d                  ; angle en degré de rotation sur l'axe Z
;   Effect_rotation.l       ; 1 pour effectuer la rotation ou la 1ere fois, 0 sinon (juste pour affichage)
;   zoom.d                  ; facteur de zoom apppliquer a toute les axes
;   zooZ.d                ; facteur de zoom apppliquer a l'axe Z
;   facteur_perspective.d   ; facteur de 'perspective' , 0 pour pas de perspective
  
  If Effect_rotation = 1
    ; copie du tableau passé en parametre
    Dim Obj.FACE(dimension)
    CopyMemory(*objet, Obj(), SizeOf(FACE) * (dimension + 1))
    
    ; convertion des angles en radian
    rotx = Convert1(rotx, 0)
    roty = Convert1(roty, 0)
    rotz = Convert1(rotz, 0)
    
;     rotz = ACos(Sin(roty))
;     If ASin(Cos(rotx)) < 0
;       rotz + #PI / 2
;     EndIf
    
    angle.d = 0
    
    ;{  rotation
    For curs = 0 To dimension
      For point = 1 To 4
        If point = 1
          X.d = Obj(curs)\x1
          Y.d = Obj(curs)\y1
          Z.d = Obj(curs)\z1
        ElseIf point = 2
          X.d = Obj(curs)\x2
          Y.d = Obj(curs)\y2
          Z.d = Obj(curs)\z2
        ElseIf point = 3
          X.d = Obj(curs)\x3
          Y.d = Obj(curs)\y3
          Z.d = Obj(curs)\z3
        ElseIf point = 4
          X.d = Obj(curs)\x4
          Y.d = Obj(curs)\y4
          Z.d = Obj(curs)\z4
        EndIf
        
        X * zoom
        Y * zoom
        Z * zoom;  * zooZ
        
        ; ## passage dans le repère rotaté de rotx
        
;         Xa.d = X
        Ya.d = Y * Cos(rotx) - Z * Sin(rotx)
        Za.d = Y * Sin(rotx) + Z * Cos(rotx)
        
        ; ## passage dans le repère rotaté de roty
        
        Xb.d = X * Cos(roty) + Za * Sin(roty)
;         Yb.d = Ya
        Zb.d = -X * Sin(roty) + Za * Cos(roty)
        
        ; ## passage dans le repère rotaté de rotz
        
        X = Xb * Cos(rotz) - Ya * Sin(rotz)
        Y = Xb * Sin(rotz) + Ya * Cos(rotz)
        Z = Zb
        
;         If rotz ; rotation autour de z
;           dist.d = Sqr(X * X + Y * Y)
;           
;           If dist
;             angle = ACos(X / dist)
;             If Y < 0
;               angle = - angle
;             EndIf
;             angle + rotz
;             X = dist * Cos(angle)
;             Y = dist * Sin(angle)
;           EndIf
;         EndIf
;         
;         If roty ; rotation autour de y
;           dist.d = Sqr(Z * Z + X * X)
;           
;           If dist
;             angle = ACos(Z / dist)
;             If X < 0
;               angle = - angle
;             EndIf
;             angle + roty
;             Z = dist * Cos(angle)
;             X = dist * Sin(angle)
;           EndIf
;         EndIf
;         
;         If rotx ; rotation autour de x
;           dist.d = Sqr(Y * Y + Z * Z)
;           
;           If dist
;             angle = ACos(Y / dist)
;             If Z < 0
;               angle = - angle
;             EndIf
;             angle + rotx
;             Y = dist * Cos(angle)
;             Z = dist * Sin(angle)
;           EndIf
;         EndIf
        
        If point = 1
          Obj(curs)\x1 = X.d
          Obj(curs)\y1 = Y.d
          Obj(curs)\z1 = Z.d
          
          Obj(curs)\z_min = Z
        ElseIf point = 2
          Obj(curs)\x2 = X.d
          Obj(curs)\y2 = Y.d
          Obj(curs)\z2 = Z.d
        ElseIf point = 3
          Obj(curs)\x3 = X.d
          Obj(curs)\y3 = Y.d
          Obj(curs)\z3 = Z.d
        ElseIf point = 4
          Obj(curs)\x4 = X.d
          Obj(curs)\y4 = Y.d
          Obj(curs)\z4 = Z.d
        EndIf
        
        If Z < Obj(curs)\z_min : Obj(curs)\z_min = Z : EndIf
      Next
    Next
    ;}
    
    SortStructuredArray(Obj(), 0, OffsetOf(FACE\z_min), #PB_Sort_Double)
    
    
  EndIf
  
  ;{ affichage des lignes
  
  For curs = 0 To dimension
    coef_1.d = Pow(2.718281828459, -facteur_perspective * Obj(curs)\z1)
    coef_2.d = Pow(2.718281828459, -facteur_perspective * Obj(curs)\z2)
    coef_3.d = Pow(2.718281828459, -facteur_perspective * Obj(curs)\z3)
    coef_4.d = Pow(2.718281828459, -facteur_perspective * Obj(curs)\z4)
    
    x1.d = Obj(curs)\x1 * coef_1 + x_center
    x2.d = Obj(curs)\x2 * coef_2 + x_center
    x3.d = Obj(curs)\x3 * coef_3 + x_center
    x4.d = Obj(curs)\x4 * coef_4 + x_center
    
    y1.d = Obj(curs)\y1 * coef_1 + y_center
    y2.d = Obj(curs)\y2 * coef_2 + y_center
    y3.d = Obj(curs)\y3 * coef_3 + y_center
    y4.d = Obj(curs)\y4 * coef_4 + y_center
    
    x = (x1 + x2 + x3 + x4) / 4
    y = (y1 + y2 + y3 + y4) / 4
    
    LineXY(x1, y1, x2, y2, Obj(curs)\color)
    LineXY(x2, y2, x3, y3, Obj(curs)\color)
    LineXY(x3, y3, x4, y4, Obj(curs)\color)
    LineXY(x4, y4, x1, y1, Obj(curs)\color)
    
    If mode = 1
;       FillArea(x, y, Obj(curs)\color, Obj(curs)\color)
      FillTriangle(x1, y1, x2, y2, x3, y3, Obj(curs)\color)
      FillTriangle(x1, y1, x3, y3, x4, y4, Obj(curs)\color)
    EndIf
    
    If mode = 2
      DrawText(x1, y1, "1", Obj(curs)\color)
      DrawText(x2, y2, "2", Obj(curs)\color)
      DrawText(x3, y3, "3", Obj(curs)\color)
      DrawText(x4, y4, "4", Obj(curs)\color)
    EndIf
  Next
  
  ;}
  
EndProcedure

Procedure Display_All_3D(*listobjet.l, nb_objet, x_center.l, y_center.l, rotX.d, rotY.d, rotZ.d, Effect_rotation.l, zoom.d, zooZ.d, facteur_perspective.d, mode.l)
  Dim Obj_all.List(nb_objet - 1)
  CopyMemory(*listobjet, Obj_all(), SizeOf(List) * (nb_objet))
  
  ; convertion des angles en radian
  rotx1 = Convert1(rotx, 0)
  roty1 = Convert1(roty, 0)
  rotz1 = Convert1(rotz, 0)
  
  angle.d = 0
  
    ;{  rotation
    For curs = 0 To nb_objet - 1
        X.d = Obj_all(curs)\x
        Y.d = Obj_all(curs)\y
        Z.d = Obj_all(curs)\z
        
        X * zoom
        Y * zoom
        Z * zoom * zooZ
        
        ; ## passage dans le repère rotaté de rotx
        
;         Xa.d = X
        Ya.d = Y * Cos(rotx1) - Z * Sin(rotx1)
        Za.d = Y * Sin(rotx1) + Z * Cos(rotx1)
        
        ; ## passage dans le repère rotaté de roty
        
        Xb.d = X * Cos(roty1) + Za * Sin(roty1)
;         Yb.d = Ya
        Zb.d = -X * Sin(roty1) + Za * Cos(roty1)
        
        ; ## passage dans le repère rotaté de rotz
        
        X = Xb * Cos(rotz1) - Ya * Sin(rotz1)
        Y = Xb * Sin(rotz1) + Ya * Cos(rotz1)
        Z = Zb
        
;         If rotz ; rotation autour de z
;           dist.d = Sqr(X * X + Y * Y)
;           
;           If dist
;             angle = ACos(X / dist)
;             If Y < 0
;               angle = - angle
;             EndIf
;             angle + rotz1
;             X = dist * Cos(angle)
;             Y = dist * Sin(angle)
;           EndIf
;         EndIf
;         
;         If roty ; rotation autour de y
;           dist.d = Sqr(Z * Z + X * X)
;           
;           If dist
;             angle = ACos(Z / dist)
;             If X < 0
;               angle = - angle
;             EndIf
;             angle + roty1
;             Z = dist * Cos(angle)
;             X = dist * Sin(angle)
;           EndIf
;         EndIf
;         
;         If rotx ; rotation autour de x
;           dist.d = Sqr(Y * Y + Z * Z)
;           
;           If dist
;             angle = ACos(Y / dist)
;             If Z < 0
;               angle = - angle
;             EndIf
;             angle + rotx1
;             Y = dist * Cos(angle)
;             Z = dist * Sin(angle)
;           EndIf
;         EndIf
        
        Obj_all(curs)\x = X.d
        Obj_all(curs)\y = Y.d
        Obj_all(curs)\z = Z.d
    Next
    ;}
  
  SortStructuredArray(Obj_all(), 0, OffsetOf(List\z) , #PB_Sort_Double)
  
  For curs = 0 To nb_objet - 1
    Display_3D(obj_all(curs)\adresse, obj_all(curs)\dimension, x_center.l, y_center.l, rotX.d, rotY.d, rotZ.d, Effect_rotation.l, zoom.d, zooZ.d, facteur_perspective.d, mode.l)
  Next
  
EndProcedure

; ##########################################################################################
; ##########################################################################################

#Screen_W = 600
#Screen_H = 500

OpenWindow(0, 0, 0, #Screen_W, #Screen_H, "", #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)

If InitSprite() = 0 Or InitMouse() = 0 Or InitKeyboard() = 0 Or InitSprite3D() = 0 : End : EndIf

OpenWindowedScreen(WindowID(0), 0, 0, #Screen_W, #Screen_H, 0, 0, 0)
KeyboardMode(1)

nb_objet = 11

;{ 
; Macro def
; Dim aa.FACE(dimension)
; Dim ab.FACE(dimension)
; Dim ac.FACE(dimension)
; Dim ad.FACE(dimension)
; Dim ae.FACE(dimension)
; Dim af.FACE(dimension)
; Dim ag.FACE(dimension)
; Dim ah.FACE(dimension)
; 
; ;{ definition des spheres
; Sphere(aa(), 0, 0, 0, 10, tr, mo, #Green)
; Sphere(ab(), 20, 0, 0, 10, tr, mo, #Green)
; Sphere(ac(), 40, 0, 0, 10, tr, mo, #Green)
; Sphere(ad(), 60, 0, 0, 10, tr, mo, #Green)
; Sphere(ae(), 0, 20, 0, 10, tr, mo, #Green)
; Sphere(af(), 20, 20, 0, 10, tr, mo, #Green)
; Sphere(ag(), 40, 20, 0, 10, tr, mo, #Green)
; Sphere(ah(), 60, 20, 0, 10, tr, mo, #Green)
; 
; Dim List.list(nb_objet - 1)
; 
; ;{ list
; a = 0
; list(a)\adresse = @aa()
; list(a)\dimension = dimension
; list(a)\x = 0
; list(a)\y = 0
; list(a)\z = 0
; 
; a + 1
; list(a)\adresse = @ab()
; list(a)\dimension = dimension
; list(a)\x = 20
; list(a)\y = 0
; list(a)\z = 0
; 
; a + 1
; list(a)\adresse = @ac()
; list(a)\dimension = dimension
; list(a)\x = 40
; list(a)\y = 0
; list(a)\z = 0
; 
; a + 1
; list(a)\adresse = @ad()
; list(a)\dimension = dimension
; list(a)\x = 60
; list(a)\y = 0
; list(a)\z = 0
; 
; a + 1
; list(a)\adresse = @ae()
; list(a)\dimension = dimension
; list(a)\x = 0
; list(a)\y = 20
; list(a)\z = 0
; 
; a + 1
; list(a)\adresse = @af()
; list(a)\dimension = dimension
; list(a)\x = 20
; list(a)\y = 20
; list(a)\z = 0
; 
; a + 1
; list(a)\adresse = @ag()
; list(a)\dimension = dimension
; list(a)\x = 40
; list(a)\y = 20
; list(a)\z = 0
; 
; a + 1
; list(a)\adresse = @ah()
; list(a)\dimension = dimension
; list(a)\x = 60
; list(a)\y = 20
; list(a)\z = 0
; ;}
; EndMacro
;}

;{ 
Macro def
Dim aa.FACE(dimension)
Dim ab.FACE(dimension)
Dim ac.FACE(dimension)
Dim ad.FACE(dimension)
Dim ae.FACE(dimension)
Dim af.FACE(dimension)
Dim ag.FACE(dimension)
Dim ah.FACE(dimension)
Dim ai.FACE(dimension)
Dim aj.FACE(dimension)
Dim ak.FACE(dimension)

;{ definition des spheres
Sphere(aa(), 0, 0, 0, 10, tr, mo, #White)
Sphere(ab(), 20, 0, 0, 10, tr, mo, #Red)
Sphere(ac(), 40, 0, 0, 10, tr, mo, #Red)
Sphere(ad(), 60, 0, 0, 10, tr, mo, #Red)
Sphere(ae(), 0, 20, 0, 10, tr, mo, #Green)
Sphere(af(), 0, 40, 0, 10, tr, mo, #Green)
Sphere(ag(), 0, 60, 0, 10, tr, mo, #Green)
Sphere(ah(), 0, 0, 20, 10, tr, mo, #Blue)
Sphere(ai(), 0, 0, 40, 10, tr, mo, #Blue)
Sphere(aj(), 0, 0, 60, 10, tr, mo, #Blue)
Sphere(ak(), 60, 60, 60, 10, tr, mo, #Yellow)

Dim List.List(nb_objet - 1)

;{ list
a = 0
List(a)\adresse = @aa()
List(a)\dimension = dimension
List(a)\x = 0
List(a)\y = 0
List(a)\z = 0

a + 1
List(a)\adresse = @ab()
List(a)\dimension = dimension
List(a)\x = 20
List(a)\y = 0
List(a)\z = 0

a + 1
List(a)\adresse = @ac()
List(a)\dimension = dimension
List(a)\x = 40
List(a)\y = 0
List(a)\z = 0

a + 1
List(a)\adresse = @ad()
List(a)\dimension = dimension
List(a)\x = 60
List(a)\y = 0
List(a)\z = 0

a + 1
List(a)\adresse = @ae()
List(a)\dimension = dimension
List(a)\x = 0
List(a)\y = 20
List(a)\z = 0

a + 1
List(a)\adresse = @af()
List(a)\dimension = dimension
List(a)\x = 0
List(a)\y = 40
List(a)\z = 0

a + 1
List(a)\adresse = @ag()
List(a)\dimension = dimension
List(a)\x = 0
List(a)\y = 60
List(a)\z = 0

a + 1
List(a)\adresse = @ah()
List(a)\dimension = dimension
List(a)\x = 0
List(a)\y = 0
List(a)\z = 20

a + 1
List(a)\adresse = @ai()
List(a)\dimension = dimension
List(a)\x = 0
List(a)\y = 0
List(a)\z = 40

a + 1
List(a)\adresse = @aj()
List(a)\dimension = dimension
List(a)\x = 0
List(a)\y = 0
List(a)\z = 60

a + 1
List(a)\adresse = @ak()
List(a)\dimension = dimension
List(a)\x = 60
List(a)\y = 60
List(a)\z = 60
;}
EndMacro
;}
def

vit = 10
zoom.d = 1.5
zoom_z.d = 1
fact.d = -0.004

Repeat
  event = WindowEvent()
  ExamineKeyboard()
  
  If KeyboardPushed(#PB_Key_Pad7) : rot_x - vit : EndIf
  If KeyboardPushed(#PB_Key_Pad8) : rot_x + vit : EndIf
  If KeyboardPushed(#PB_Key_Pad4) : rot_y - vit : EndIf
  If KeyboardPushed(#PB_Key_Pad5) : rot_y + vit : EndIf
  If KeyboardPushed(#PB_Key_Pad1) : rot_z - vit : EndIf
  If KeyboardPushed(#PB_Key_Pad2) : rot_z + vit : EndIf
  
  If KeyboardPushed(#PB_Key_Pad9) : zoom * 1.5 : EndIf
  If KeyboardPushed(#PB_Key_Pad3) : zoom / 1.5 : EndIf
  
  If KeyboardPushed(#PB_Key_PageUp) : fact + 0.002 : EndIf
  If KeyboardPushed(#PB_Key_PageDown) : fact - 0.002 : EndIf
  
  If KeyboardPushed(#PB_Key_F1) : mode = 0 : EndIf
  If KeyboardPushed(#PB_Key_F2) : mode = 1 : EndIf
  If KeyboardPushed(#PB_Key_F3) : mode = 2 : EndIf
  
  If rot_x > 360 : rot_x - 360 : EndIf
  If rot_y > 360 : rot_y - 360 : EndIf
  If rot_z > 360 : rot_z - 360 : EndIf
  If rot_x < 0 : rot_x + 360 : EndIf
  If rot_y < 0 : rot_y + 360 : EndIf
  If rot_z < 0 : rot_z + 360 : EndIf
  
  ;{ changement des parametres des spheres
  If KeyboardPushed(#PB_Key_A) Or KeyboardPushed(#PB_Key_Z) Or KeyboardPushed(#PB_Key_Q) Or KeyboardPushed(#PB_Key_S)
    If KeyboardPushed(#PB_Key_A) : tr + 1 : EndIf
    If KeyboardPushed(#PB_Key_Z) And tr > 2 : tr - 1 : EndIf
    If KeyboardPushed(#PB_Key_Q) : mo + 1 : EndIf
    If KeyboardPushed(#PB_Key_S) And mo > 2 : mo - 1 : EndIf
    dimension = tr * mo
    dimension_t = mo - 1
    
    def
    
  EndIf
  ;}
  
  Delay(10)
  
  ClearScreen(0)
  
  If StartDrawing(ScreenOutput())
      Display_All_3D(@list(), nb_objet, #Screen_W / 2, #Screen_H / 2, rot_x, rot_y, rot_z, 1, zoom, 1, fact, mode)
      
      DrawText(0, 0, Str(rot_x), #White, 0)
      DrawText(0, 20, Str(rot_y), #White, 0)
      DrawText(0, 40, Str(rot_z), #White, 0)
      
    StopDrawing()
  EndIf
  
  FlipBuffers()
  
Until event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)

End

je m’étais lancé dans un projet beaucoup plus compliqué et je me suis noyé dans la complexité de mon code -_-
avec des formules de math vraiment chiantes et plein de condition !

Je suis partis sur une autre projection de ce que tu as fais :

Image

et la mon code : il bug, mais je suis incapable de comprendre pourquoi !! si je devais retravailler dessus je pense que je repartirais de 0 -_-

pour voir les touches à utiliser :

Code : Tout sélectionner

  If KeyboardPushed(#PB_Key_Z) : NC_CameraMove(@Camera, 10, 0, 0) : EndIf
  If KeyboardPushed(#PB_Key_S) : NC_CameraMove(@Camera, -10, 0, 0) : EndIf
  If KeyboardPushed(#PB_Key_Q) : NC_CameraMove(@Camera, 0, 10, 0) : EndIf
  If KeyboardPushed(#PB_Key_D) : NC_CameraMove(@Camera, 0, -10, 0) : EndIf
  
  If KeyboardPushed(#PB_Key_Up) : NC_CameraLocate(@Camera, Camera\cx, Camera\cy + 10, Camera\cz) : EndIf
  If KeyboardPushed(#PB_Key_Down) : NC_CameraLocate(@Camera, Camera\cx, Camera\cy - 10, Camera\cz) : EndIf
  If KeyboardPushed(#PB_Key_Left) : NC_CameraLocate(@Camera, Camera\cx + 10, Camera\cy, Camera\cz) : EndIf
  If KeyboardPushed(#PB_Key_Right) : NC_CameraLocate(@Camera, Camera\cx - 10, Camera\cy, Camera\cz) : EndIf
  If MouseDeltaX() Or MouseDeltaY() : NC_CameraLookAt(@Camera, camera\cx + camera\ax + MouseDeltaX() / coef, camera\cy + camera\ay + MouseDeltaY() / coef, camera\cz + camera\az) : EndIf
  
  If KeyboardPushed(#PB_Key_Pad9) : NC_CameraFocale(@Camera, Camera\P + 1) : EndIf
  If KeyboardPushed(#PB_Key_Pad3) : NC_CameraFocale(@Camera, Camera\P - 1) : EndIf
  
  If KeyboardPushed(#PB_Key_Pad7) : NC_CameraFOV(@Camera, ((360 * Camera\FOV) / #PI) + 2) : EndIf
  If KeyboardPushed(#PB_Key_Pad8) : NC_CameraFOV(@Camera, ((360 * Camera\FOV) / #PI) - 2) : EndIf
  
  If KeyboardPushed(#PB_Key_F1) : mode = 0 : EndIf
  If KeyboardPushed(#PB_Key_F2) : mode = 1 : EndIf
  If KeyboardPushed(#PB_Key_F3) : mode = 2 : EndIf
  
  If KeyboardPushed(#PB_Key_Pad5) : NC_CameraLookAt(@Camera, 0, 0, 0) : EndIf

Code : Tout sélectionner

Structure point_3D
  k.d
  x.d
  y.d
EndStructure

Structure triangle
  sommet1.l
  sommet2.l
  sommet3.l
  
  color.l
EndStructure

Structure pt
  x.d
  y.d
  z.d
  color.l
EndStructure

Structure vec
  x.d
  y.d
  z.d
EndStructure

Structure camera
  ; Données à définir
  
  ecranX.l ; position en x de l'écran
  ecranY.l ; position en y de l'écran
  ecranL.l ; largeur d'écran
  ecranH.l ; Hauteur d'écran
  
  cx.d ; position en x de la caméra "dans le monde 3D"
  cy.d ; position en y de la caméra
  cz.d ; position en z de la caméra
  
  P.d ; Profondeur du champ
  FOV.d ; Field Of Vision en rad doit être compris entre 0 et #PI
  
  ; Données à calculer
  
  Opx.d
  Opy.d
  Opz.d
  
  ; coordonnée du vec(n) au plan de la caméra, à définir par un calcul
  ax.d
  ay.d
  az.d
  
  ; coordonnée du vec(x) au plan de la caméra, à définir par un calcul : vec(x) = vec(z) - (vec(z).vec(n))*vec(n)
  xx.d
  xy.d
  xz.d
  
  ; coordonnée du vec(y) au plan de la caméra, à définir par un calcul : vec(y) = vec(n) ^ vec(x)
  yx.d
  yy.d
  yz.d
  
  ; constante du plan d
  d.d
  
  H.d ; Hauteur du champ / 2
  L.d ; largeur du champ / 2
  
  rapport.d ; rapport entre la taille du plan de focale de la cam et l'écran d'affichage
  
  ecran_centre_X.d
  ecran_centre_Y.d
EndStructure

Procedure.d Convert1(degre.d, radian.d) ; Convertti un nombre en degré en radian ou si degre = 0, le contraire
  If degre = 0
    ProcedureReturn ((180 * radian) / #PI)
  EndIf
  ProcedureReturn ((#PI * degre) / 180)
EndProcedure

; Forme volumique complexe prédessinnées

Procedure Sphere(*objet.pt, *sommet.triangle, centre_x.d, centre_y.d, centre_z.d, rayon.d, tranche, morceau, color)
  Dim Obj_S.pt(tranche * morceau * 4)
  
  epais.d = rayon * 2 / tranche
  ang.d = 2 * #PI / morceau
  
  c = 0
  
  For a = 1 To tranche
    dist.d = Abs((a - 1) * epais - rayon)
    dist = rayon * rayon - dist * dist
    If dist < 0 : dist = 0 : EndIf
    ray_pla_1.d = Sqr(dist)
    
    dist.d = Abs(a * epais - rayon)
    dist = rayon * rayon - dist * dist
    If dist < 0 : dist = 0 : EndIf
    ray_pla.d = Sqr(dist)
    
    For b = 1 To morceau
      c + 1
      Obj_S(c)\x = ray_pla * Cos(ang * (b - 1)) + centre_x
      Obj_S(c)\y = a * epais - rayon + centre_y
      Obj_S(c)\z = ray_pla * Sin(ang * (b - 1)) + centre_z
      
      c + 1
      Obj_S(c)\x = ray_pla_1 * Cos(ang * (b - 1)) + centre_x
      Obj_S(c)\y = (a - 1) * epais - rayon + centre_y
      Obj_S(c)\z = ray_pla_1 * Sin(ang * (b - 1)) + centre_z
      
      c + 1
      Obj_S(c)\x = ray_pla_1 * Cos(b * ang) + centre_x
      Obj_S(c)\y = (a - 1) * epais - rayon + centre_y
      Obj_S(c)\z = ray_pla_1 * Sin(b * ang) + centre_z
      
      c + 1
      Obj_S(c)\x = ray_pla * Cos(b * ang) + centre_x
      Obj_S(c)\y = a * epais - rayon + centre_y
      Obj_S(c)\z = ray_pla * Sin(b * ang) + centre_z
      
      
      
      *sommet + SizeOf(triangle)
      
      *sommet\sommet1 = c - 3 - 1
      *sommet\sommet2 = c - 2 - 1
      *sommet\sommet3 = c - 1 - 1
      *sommet\color = Random(#White)
      
      *sommet + SizeOf(triangle)
      
      *sommet\sommet1 = c - 3 - 1
      *sommet\sommet2 = c - 1 - 1
      *sommet\sommet3 = c - 1
      *sommet\color = Random(#White)
      
    Next
  Next
  
  Obj_S(0)\x = c
  
  CopyMemory(obj_S(), *objet, SizeOf(pt) * tranche * morceau)
  Dim Obj_S.pt(0)
EndProcedure

; Fonction auxiliaires

Procedure FillTriangle(x1, y1, x2, y2, x3, y3, color) ; dessine un triangle plein sans trou
  For boucle = 0 To 1 
    If x1 > x2 : x = x2 : x2 = x1 : x1 = x : y = y2 : y2 = y1 : y1 = y :  EndIf 
    If x2 > x3 : x = x3 : x3 = x2 : x2 = x : y = y3 : y3 = y2 : y2 = y :  EndIf 
  Next
  
  If x1 = x2
    
  Else
    a.d = (y2 - y1) / (x2 - x1)
    b.d = y2 - a * x2
    
    a1.d = (y1 - y3) / (x1 - x3)
    b1.d = y3 - a1 * x3
    
    For x = x1 To x2
      LineXY(x, a * x + b, x, a1 * x + b1, color)
    Next
  EndIf
  
  If x2 = x3
    
  Else
    a.d = (y2 - y3) / (x2 - x3)
    b.d = y2 - a * x2
    
    a1.d = (y1 - y3) / (x1 - x3)
    b1.d = y1 - a1 * x1
    
    For x = x2 To x3
      LineXY(x, a * x + b, x, a1 * x + b1, color)
    Next
  EndIf
  
EndProcedure

; Fonction interne pour le fonctionnement de la caméra

Procedure CameraPlan(*ca.camera, cible_x.d, cible_y.d, cible_z.d, mode.l) ; Calcul de toutes les données de la camera dépendant des données initiales
  ; mode défini si les vecteurs sont recalculés (mode = 0) ou pas (mode = 1)
  
  If mode = 0
    ; calcul de vec(n)
    *ca\ax = cible_x - *ca\cx
    *ca\ay = cible_y - *ca\cy
    *ca\az = cible_z - *ca\cz
    
    norme.d = Sqr(*ca\ax * *ca\ax + *ca\ay * *ca\ay + *ca\az * *ca\az)
    
    *ca\ax / norme
    *ca\ay / norme
    *ca\az / norme
  EndIf
  
  ; coordonnées de Op
  *ca\Opx = *ca\cx + *ca\ax * *ca\P
  *ca\Opy = *ca\cy + *ca\ay * *ca\P
  *ca\Opz = *ca\cz + *ca\az * *ca\P
  
  ; calcul de d
  *ca\d = - *ca\Opx * *ca\ax - *ca\Opy * *ca\ay - *ca\Opz * *ca\az
  
  If mode = 0
    ; définition de vec(x)
    
    ; test d'alignement sur Z
;     *ca\xx = - *ca\az * *ca\ax
;     *ca\xy = - *ca\az * *ca\ay
;     *ca\xz = 1 - *ca\az * *ca\az

    ; test d'alignement sur X
    *ca\xx = 1- *ca\ax * *ca\ax
    *ca\xy = - *ca\ax * *ca\ay
    *ca\xz = - *ca\ax * *ca\az
    
    norme.d = Sqr(*ca\xx * *ca\xx + *ca\xy * *ca\xy + *ca\xz * *ca\xz)
    
    *ca\xx / norme
    *ca\xy / norme
    *ca\xz / norme
    
    ; définition de vec(y) (produit vectoriel)
    *ca\yx = -*ca\az * *ca\xy + *ca\ay * *ca\xz
    *ca\yy = -*ca\ax * *ca\xz + *ca\az * *ca\xx
    *ca\yz = -*ca\ay * *ca\xx + *ca\ax * *ca\xy
  EndIf
  
  ; calcul de L.d ; Largeur du champ / 2
  *ca\L = *ca\P * Tan(*ca\FOV)
  
  ; calcul du rapport de la cam
  *ca\rapport = *ca\ecranL / (*ca\L * 2)
  
  ; calcul de H.d ; Hauteur du champ / 2
  *ca\H = (*ca\ecranH / *ca\rapport) / 2
EndProcedure

; Fonction de gestion de la caméra :

Procedure NC_CreateCamera(*Cam.camera, X.l, Y.l, Width.l, Height.l) ; ;-) NC pour No Carte graphique
  *Cam\ecranX = X
  *Cam\ecranY = Y
  *Cam\ecranL = Width
  *Cam\ecranH = Height
  *Cam\ecran_centre_X = Width / 2 + X
  *Cam\ecran_centre_Y = Height / 2 + Y
  *Cam\FOV = (#PI * (45 / 2)) / 180 ; par defaut crée une caméra de FOV 45°
  
  *Cam\cx = 0
  *Cam\cy = 0
  *Cam\cz = 0
  *Cam\P = 40
;   *Cam\rapport = 100 ; inutile avec l'introduction de FOV
  
  CameraPlan(*Cam, 10, 10, 10, 0)
EndProcedure

Procedure NC_CameraFocale(*Cam.camera, Focale.d) ; Change la distance du plan focal de la camera, par défaut il est de 40
  *Cam\P = Focale
  
  CameraPlan(*Cam, 0, 0, 0, 1)
EndProcedure

Procedure NC_CameraFOV(*Cam.camera, FOV.d) ; Change le champ de vision de la camera en degré, par défaut il est de 40, il va de 0° à 180° (non compris)
  *Cam\FOV = (#PI * (FOV / 2)) / 180
  
  CameraPlan(*Cam, 0, 0, 0, 1)
EndProcedure

Procedure NC_CameraLocate(*Cam.camera, x.d, y.d, z.d) ; Change les coordonées absolues de la caméra
  *Cam\cx = x
  *Cam\cy = y
  *Cam\cz = z
  
  CameraPlan(*Cam, 0, 0, 0, 1)
EndProcedure

Procedure NC_CameraLookAt(*Cam.camera, xcible.d, ycible.d, zcible.d) ; oriente la camera vers un point
  CameraPlan(*Cam, xcible, ycible, zcible, 0)
EndProcedure

Procedure NC_CameraMove(*Cam.camera, dx.d, dy.d, dz.d) ; deplace la caméra par rapport à ses axes internes (pour changer la position absolue voir CameraLocate_NC())
  *Cam\cx + dx * *Cam\ax + dz * *Cam\yx - dy * *Cam\xx
  *Cam\cy + dx * *Cam\ay + dz * *Cam\yy - dy * *Cam\xy
  *Cam\cz + dx * *Cam\az + dz * *Cam\yz - dy * *Cam\xz
  
  CameraPlan(*Cam, 0, 0, 0, 1)
EndProcedure

; Fonction d'affichage des objets 3D

Procedure Display_3D(*ca.camera, *coord.pt, *triangle.triangle)
  nb_points = *coord\x
  sizeofpt = SizeOf(pt) ; a remplacer par une constante lorsque la structure sera definie une fois pour toute
  
;   nbpointdessine = 0 ; uniquement du debug
  nbtriangledessine = 0 ; uniquement du debug
  
  Dim tableau.point_3D(nb_points - 1) ; le premier point sert à stocker le nb de point total
  
  For a = 1 To nb_points
    *coord + sizeofpt ; on avance d'une case dans le tableau (qui n'a qu'une seule colonne)
    
    ; calcul des coordonnées de la projection de M(x,y,z) sur le plan de la camera
    
    A0.d = (*coord\y - *ca\cy) / (*coord\x - *ca\cx)
    B0.d = (*coord\z - *ca\cz) / (*coord\x - *ca\cx)
    B.vec\x = (- *ca\d + (A0 * *ca\cx - *ca\cy) * *ca\ay + (B0 * *ca\cx - *ca\cz) * *ca\az) / (*ca\ay * A0 + *ca\ax + *ca\az * B0)
    
    A1.d = (*coord\x - *ca\cx) / (*coord\y - *ca\cy)
    B1.d = (*coord\z - *ca\cz) / (*coord\y - *ca\cy)
    B\y = (- *ca\d + (A1 * *ca\cy - *ca\cx) * *ca\ax + (B1 * *ca\cy - *ca\cz) * *ca\az) / (*ca\ax * A1 + *ca\ay + *ca\az * B1)
    
    A2.d = (*coord\x - *ca\cx) / (*coord\z - *ca\cz)
    B2.d = (*coord\y - *ca\cy) / (*coord\z - *ca\cz)
    B\z = (- *ca\d + (A2 * *ca\cz - *ca\cx) * *ca\ax + (B2 * *ca\cz - *ca\cy) * *ca\ay) / (*ca\ax * A2 + *ca\az + *ca\ay * B2)
    
    If (*coord\x - *ca\cx) <> 0 ; on n'affiche pas les points sur la caméra !!
      k.d = (B\x - *ca\cx) / (*coord\x - *ca\cx)
      
      If k <= 1 And k > 0 ; on teste si le point M est bien situé devant la caméra et apres le plan de focale
        ; coordonnées de B exprimées dans le plan focal : Bx = vec(Op B).vec(x) , By = vec(Op B).vec(y)
        Bx.d = (B\x - *ca\Opx) * *ca\xx + (B\y - *ca\Opy) * *ca\xy + (B\z - *ca\Opz) * *ca\xz
        By.d = (B\x - *ca\Opx) * *ca\yx + (B\y - *ca\Opy) * *ca\yy + (B\z - *ca\Opz) * *ca\yz
        
        tableau(a - 1)\x = *ca\ecran_centre_X + Bx * *ca\rapport
        tableau(a - 1)\y = *ca\ecran_centre_Y + By * *ca\rapport
        tableau(a - 1)\k = k
        
        
; ;         commenté pour tester l'affichage de triangle et non plus de points seuls
;         ; test si le point rentre dans l'écran:
;         If Bx < *ca\L And Bx > -*ca\L And By < *ca\H And By > -*ca\H
;           ScreenX.d = *ca\ecran_centre_X + Bx * *ca\rapport
;           ScreenY.d = *ca\ecran_centre_Y + By * *ca\rapport
;           
;           Circle(ScreenX, ScreenY, 1, *coord\color)
;           
; ;           If *coord\color = #Blue
; ;             Debug Bx
; ;           EndIf
;           
;           nbpointdessine + 1
;         EndIf
        
      EndIf
      
    EndIf
    
  Next
  
;   SortStructuredArray(tableau(), 1, OffsetOf(point_3D\k), #PB_Sort_Double)
  
  nb_tri = *triangle\sommet1
  sizeoftriangle = SizeOf(triangle)
  
  For a = 1 To nb_tri
    *triangle + sizeoftriangle
    
    If tableau(*triangle\sommet1)\k > 0 And tableau(*triangle\sommet1)\k <= 1 And tableau(*triangle\sommet2)\k > 0 And tableau(*triangle\sommet2)\k <= 1 And tableau(*triangle\sommet3)\k > 0 And tableau(*triangle\sommet3)\k <= 1
      FillTriangle(tableau(*triangle\sommet1)\x ,tableau(*triangle\sommet1)\y, tableau(*triangle\sommet2)\x, tableau(*triangle\sommet2)\y, tableau(*triangle\sommet3)\x, tableau(*triangle\sommet3)\y, *triangle\color)
      
      nbtriangledessine + 1
    EndIf
  Next
  
;   ProcedureReturn nbpointdessine
  ProcedureReturn nbtriangledessine
EndProcedure


; ##########################################################################################
; ##########################################################################################

#Screen_W = 600
#Screen_H = 500

OpenWindow(0, 0, 0, #Screen_W, #Screen_H, "", #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)

If InitSprite() = 0 Or InitMouse() = 0 Or InitKeyboard() = 0 Or InitSprite3D() = 0 : End : EndIf

OpenWindowedScreen(WindowID(0), 0, 0, #Screen_W, #Screen_H, 0, 0, 0)
KeyboardMode(1)

; definition des sommets

;{ repère
Dim co.pt(4) ; 4 points

co(0)\x = 4 ; nombre de points

;{ repère
  
  x = 20
  y = 0
  z = 0
  
  ; centre
  co(1)\x = x
  co(1)\y = y
  co(1)\z = z
  co(1)\color = #White
  
  ; x
  co(2)\x = 10 + x
  co(2)\y = y
  co(2)\z = z
  co(2)\color = #Red
  
  ; y
  co(3)\x = x
  co(3)\y = 10 + y
  co(3)\z = z
  co(3)\color = #Green
  
  ; z
  co(4)\x = x
  co(4)\y = y
  co(4)\z = 10 + z
  co(4)\color = #Blue
  
;}

; définition des triangles (l'index des sommets commence à 0)

Dim triangle.triangle(3)

triangle(0)\sommet1 = 3

;{ triangle du repère

; xOy
triangle(1)\sommet1 = 1
triangle(1)\sommet2 = 0
triangle(1)\sommet3 = 2
triangle(1)\color = #Blue

; yOz
triangle(2)\sommet1 = 2
triangle(2)\sommet2 = 0
triangle(2)\sommet3 = 3
triangle(2)\color = #Red

; zOx
triangle(3)\sommet1 = 3
triangle(3)\sommet2 = 0
triangle(3)\sommet3 = 1
triangle(3)\color = #Green

;}
;}

;{ Sphère

tranche = 10
morceau = 10

Dim Sphere_pt.pt(tranche * morceau * 4)
Dim Sphere_tr.triangle(tranche * morceau * 2)

Sphere(@Sphere_pt(), @Sphere_tr(0), 20, 0, 0, 20, tranche, morceau, 0)

Sphere_tr(0)\sommet1 = 200

;}

NC_CreateCamera(@Camera.camera, 0, 0, #Screen_W, #Screen_H)

NC_CameraLocate(@Camera, 500, 500, 500)
NC_CameraLookAt(@Camera, 0, 0, 0)

coef.d = 1000

Repeat
  event = WindowEvent()
  ExamineKeyboard()
  ExamineMouse()
  
  If KeyboardPushed(#PB_Key_Z) : NC_CameraMove(@Camera, 10, 0, 0) : EndIf
  If KeyboardPushed(#PB_Key_S) : NC_CameraMove(@Camera, -10, 0, 0) : EndIf
  If KeyboardPushed(#PB_Key_Q) : NC_CameraMove(@Camera, 0, 10, 0) : EndIf
  If KeyboardPushed(#PB_Key_D) : NC_CameraMove(@Camera, 0, -10, 0) : EndIf
  
  If KeyboardPushed(#PB_Key_Up) : NC_CameraLocate(@Camera, Camera\cx, Camera\cy + 10, Camera\cz) : EndIf
  If KeyboardPushed(#PB_Key_Down) : NC_CameraLocate(@Camera, Camera\cx, Camera\cy - 10, Camera\cz) : EndIf
  If KeyboardPushed(#PB_Key_Left) : NC_CameraLocate(@Camera, Camera\cx + 10, Camera\cy, Camera\cz) : EndIf
  If KeyboardPushed(#PB_Key_Right) : NC_CameraLocate(@Camera, Camera\cx - 10, Camera\cy, Camera\cz) : EndIf
  If MouseDeltaX() Or MouseDeltaY() : NC_CameraLookAt(@Camera, camera\cx + camera\ax + MouseDeltaX() / coef, camera\cy + camera\ay + MouseDeltaY() / coef, camera\cz + camera\az) : EndIf
  
  If KeyboardPushed(#PB_Key_Pad9) : NC_CameraFocale(@Camera, Camera\P + 1) : EndIf
  If KeyboardPushed(#PB_Key_Pad3) : NC_CameraFocale(@Camera, Camera\P - 1) : EndIf
  
  If KeyboardPushed(#PB_Key_Pad7) : NC_CameraFOV(@Camera, ((360 * Camera\FOV) / #PI) + 2) : EndIf
  If KeyboardPushed(#PB_Key_Pad8) : NC_CameraFOV(@Camera, ((360 * Camera\FOV) / #PI) - 2) : EndIf
  
  If KeyboardPushed(#PB_Key_F1) : mode = 0 : EndIf
  If KeyboardPushed(#PB_Key_F2) : mode = 1 : EndIf
  If KeyboardPushed(#PB_Key_F3) : mode = 2 : EndIf
  
  If KeyboardPushed(#PB_Key_Pad5) : NC_CameraLookAt(@Camera, 0, 0, 0) : EndIf
  
  Delay(10)
  
  ClearScreen(0)
  
  If StartDrawing(ScreenOutput())
  	
  	;       MeasureHiResIntervalStart()
  	res = ElapsedMilliseconds()
  	;       re = Display_3D(@Camera, @co(0), @triangle(0))
  	re = Display_3D(@Camera, @Sphere_pt(0), @Sphere_tr(0))
  	
  	res = ElapsedMilliseconds() - res
  	;       res.d = MeasureHiResIntervalStop()
  	
  	DrawText(0, 0, StrD(res * 1000, 3) + " ms")
  	
  	DrawText(0, 20, "Cam X = " + Str(camera\cx), #White, #Black)
      DrawText(0, 40, "Cam Y = " + Str(camera\cy), #White, #Black)
      DrawText(0, 60, "P = " + Str(camera\P), #White, #Black)
      DrawText(0, 80, "nb points = " + Str(re), #White, #Black)
      DrawText(0, 80, "nb triangles = " + Str(re), #White, #Black)
    StopDrawing()
  EndIf
  
  FlipBuffers()
  
Until event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)

End
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: 3D vers 2D avec perspective

Message par G-Rom »

Sympa ton code , mais je suspecte des erreurs de perspectives , je n'ai pas vérifié , mais j'ai l'impression que tu ne ramène pas le tout au centre de l'écran.
Si tu veut faire un code qui tiens la route , fragmente ton code par spécialité , vecteur3 , camera , matrice , vertex , mesh , texture , etc...
tu y vera plus clair.
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: 3D vers 2D avec perspective

Message par graph100 »

ben je ne comprend pas les erreurs.
Car la sphère n'est même pas affichée en entier, peut etre que la fonction de création de la sphère est cassée ??

Et puis il y les déplacements de caméra qui sont bizarre : tout va en diagonale -_-
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: 3D vers 2D avec perspective

Message par G-Rom »

Et puis il y les déplacements de caméra qui sont bizarre : tout va en diagonale -_-
Essaye de recentré les Point2D après projection , càd que dès lors que tu as fait ta projection 3D->2D

tu rajoute :
POINT 2D + TAILLE ECRAN / 2
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: 3D vers 2D avec perspective

Message par graph100 »

en ayant rejeté un oeil vite fait, je le fais la :

Code : Tout sélectionner

	tableau(a - 1)\x = *ca\ecran_centre_X + Bx * *ca\rapport 
	tableau(a - 1)\y = *ca\ecran_centre_Y + By * *ca\rapport 
mais de toute façon il faut repenser le code, car PB nous a donné de nouvelle possibilités depuis que j'ai fait ça ^^
regarde comment je gère mes objet sphère -_- c'est dégoutant, j'écris en mémoire et j'écrase le tableau avec un copymemory() !
J'ai aussi beaucoup changé ma programmation xD et appris des trucs.
par exemple je stocke un sizeof() :

Code : Tout sélectionner

sizeofpt = SizeOf(pt) 
en pensant que ça iras plus vite -_- alors que c'est remplacé comme une constante

enfin bon. je le reprendrais certainement cette année, car je vais être en colocation avec un matheux qui commence la prog xD
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: 3D vers 2D avec perspective

Message par G-Rom »

Qu'est ce que tu veut faire ? un moteur 3D software ?
si t'es un tendu , je peut t'aider aux transformations 3D ;)
va falloir que tu bouffes de la matrice 4x et du vecteur 3D :mrgreen:
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: 3D vers 2D avec perspective

Message par graph100 »

et bien pourquoi pas un moteur 3D software, pour le délire ,;)
normalement les transformation 3D etc.. je doit connaitre (pour mes études : mécanique des solides continus, déformations, charges, ruptures -_-)
mais ça n'est pas là ou je cartonne ! (hélas !)
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Répondre