3D vers 2D avec perspective
Re: 3D vers 2D avec perspective
@LSI
Je doute sur la crédibilité de tes calculs de rotation. Et je trouve étrange que personne n'en ai encore fait la remarque avant que tu commences l'optimisation.
Peut-être devrions-nous préparer un ensemble de conventions sur les rotations dans l'espace dans la section Info&Tuto ?
Ollivier
Je doute sur la crédibilité de tes calculs de rotation. Et je trouve étrange que personne n'en ai encore fait la remarque avant que tu commences l'optimisation.
Peut-être devrions-nous préparer un ensemble de conventions sur les rotations dans l'espace dans la section Info&Tuto ?
Ollivier
Re: 3D vers 2D avec perspective
Moi, je me fous des calculs, tant que ça me dise que mon portable est une bombe! 

-
- Messages : 4312
- Inscription : mer. 28/janv./2004 20:58
- Localisation : Clermont ferrand OU Olsztyn
- Contact :
Re: 3D vers 2D avec perspective
Mes calcul sont basé sur les équations de changement de repère de mes cours de mécaniques. et je n'ai jamais de problèmes avec. Je vais faire quelques test pour voir.
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)]
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
-
- Messages : 4312
- Inscription : mer. 28/janv./2004 20:58
- Localisation : Clermont ferrand OU Olsztyn
- Contact :
Re: 3D vers 2D avec perspective
Après test, j'avais une erreur d'affichage car l'écran affiche les Y de haut en bas, donc j'ai inversé l'affichage des Y en les mettant en négatif.
Sinon, pour le calcul, il est OK. Le sens de rotation de chaque axe est bon (sens trigo). Et le sens mon repère XYZ est correct (vérifier par la règle des 3 doigts, pouce et index à angle droit, majeur perpendiculaire à la pause de la main. Pouce = axe X, Index = axe Y, majeur = axe Z)
J'ai ajouter un mode manuel pour pouvoir jouer manuellement avec les angles. Regarde le premier sujet. L'entête du programme décrit les touches.
Si il y a qlqchose qui te choques, dis moi. parce que pour moi, tous est OK.
Sinon, pour le calcul, il est OK. Le sens de rotation de chaque axe est bon (sens trigo). Et le sens mon repère XYZ est correct (vérifier par la règle des 3 doigts, pouce et index à angle droit, majeur perpendiculaire à la pause de la main. Pouce = axe X, Index = axe Y, majeur = axe Z)
J'ai ajouter un mode manuel pour pouvoir jouer manuellement avec les angles. Regarde le premier sujet. L'entête du programme décrit les touches.
Si il y a qlqchose qui te choques, dis moi. parce que pour moi, tous est OK.
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)]
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Re: 3D vers 2D avec perspective
Bonjour LSI,
Je te prie de m'excuser de t'avoir snobé: c'est involontaire. J'ai ommis quelque peu certaines choses ces derniers temps...
Je viens de vérifier ton programme. Il possède la même erreur qu'à l'origine. Dès que j'ai du temps, je me concentre sur ce problème...
Je te prie de m'excuser de t'avoir snobé: c'est involontaire. J'ai ommis quelque peu certaines choses ces derniers temps...

Je viens de vérifier ton programme. Il possède la même erreur qu'à l'origine. Dès que j'ai du temps, je me concentre sur ce problème...
Re: 3D vers 2D avec perspective
Voilà...
* J'ai, d'abord été page 1 de ce sujet récupérer le tout premier code du post n°1. Je précise au cas où une étourderie m'eusse contraint à copier un autre code que celui décrit et normalement concerné! Si l'erreur est là, j'en suis confus.
* Une fois collé chez moi, chaque modification dans ton code a été clairement balisé. Ne sont balisés que mes ajouts de code m'appartenant et mes suppressions effectuées sur le code t'appartenant. Ainsi, tu vois parfaitement ce que j'ai modifié, quelqu'en soit la modification volontaire!
* J'ai totalisé 6 modifications commentées, numérotées et ordonnées de 1 à 6. Ainsi, tu peux manuellement effectuer l'annulation de mes modifications MAIS en prenant soin de respecter l'ordre décroissant de la modification numéro 6 qui est la première annulation jusqu'à la modification numéro 1 qui est, elle, la dernière annulation. Ainsi, en comparant avec l'originale, tu as la possibilité de voir parfaitement ce que j'ai modifié par mégarde, quelqu'en soit la modification involontaire!
* L'exécution du diptique obtenu, tu peux aisément tester les 3 rotations offertes par ton procédé calculatoire : cela fonctionne impeccablement.
Les touches HAUT et BAS exécutent la rotation absolue sur l'axe des x (de couleur verte);
Les touches TAB et A exécutent la rotation absolue sur l'axe des y (de couleur rouge);
Les touches GAUCHE et DROITE exécutent la rotation relative sur l'axe des z (de couleur bleue);
(Rem 1 : J'ai donné des définitions de ce que je nomme la « rotation absolue » et la « rotation relative ». Ce sont des définitions personnelles et je ne suis pas académicien donc tu as éventuellement un jargon à m'apprendre à ce sujet.
Rem 2 : Le fait que ton procédé exécute 2 rotations absolues selon 2 premiers axes et une rotation relative selon le 3ème axe restant n'est pas un défaut invalidant. Cependant, le procédé d'exécution de 3 rotations absolues, comme son procédé complémentaire d'exécution de 3 rotations relatives approche d'une conception plus « conventionnelle », de par leur simplicité d'utilisation - L'utilisateur est respectivement soit le décor qui contraint l'objet par une rotation, soit l'objet lui-même qui se contraint par une rotation - Dans ton code, ce dicernement de repérage reste ambigü selon les axes concernés)
* Durant l'exécution, l'appui sur la touche ESPACE, provoque le démarrage d'une DEMO. Cette démonstration opère en 4 temps:
1) Les 3 axes sont mis à zéro
2) Une rotation de pi/3 est exécutée sur l'axe des x
3) Une rotation de pi/3 est exécutée sur l'axe des y
4) Une rotation de pi/3 est exécutée sur l'axe des z
On obtient une orientation particulière du trièdre.
* Au départ d'une exécution, en respectant quelques gestes simples de contrôle, tu peux procéder comme suit:
1) Fais des va-et-vients avec les touches HAUT et BAS pour contrôler la rotation sur l'axe des x (axe vert)
2) Appuie sur ESPACE pour déclencher la démo.
3) Fais à nouveau des va-et-vients selon l'axe des x, c'est-à-dire de manière similaire à l'étape 1
Question : la rotation de l'étape 3 selon l'axe des x est-elle désormais crédible?
Mon avis est de dire non car ni une rotation absolue, ni une rotation relative au trièdre ne se caractèrise en cette rotation. Cette rotation s'effectue désormais (après la démo) selon un axe intermédiaire actuellement invisible. S'il y a une rotation selon un axe « fantôme », le choix de remettre en cause ton procédé sur le plan de la crédibilité me semble conforme.
* J'ai, d'abord été page 1 de ce sujet récupérer le tout premier code du post n°1. Je précise au cas où une étourderie m'eusse contraint à copier un autre code que celui décrit et normalement concerné! Si l'erreur est là, j'en suis confus.

* Une fois collé chez moi, chaque modification dans ton code a été clairement balisé. Ne sont balisés que mes ajouts de code m'appartenant et mes suppressions effectuées sur le code t'appartenant. Ainsi, tu vois parfaitement ce que j'ai modifié, quelqu'en soit la modification volontaire!
* J'ai totalisé 6 modifications commentées, numérotées et ordonnées de 1 à 6. Ainsi, tu peux manuellement effectuer l'annulation de mes modifications MAIS en prenant soin de respecter l'ordre décroissant de la modification numéro 6 qui est la première annulation jusqu'à la modification numéro 1 qui est, elle, la dernière annulation. Ainsi, en comparant avec l'originale, tu as la possibilité de voir parfaitement ce que j'ai modifié par mégarde, quelqu'en soit la modification involontaire!
* L'exécution du diptique obtenu, tu peux aisément tester les 3 rotations offertes par ton procédé calculatoire : cela fonctionne impeccablement.
Les touches HAUT et BAS exécutent la rotation absolue sur l'axe des x (de couleur verte);
Les touches TAB et A exécutent la rotation absolue sur l'axe des y (de couleur rouge);
Les touches GAUCHE et DROITE exécutent la rotation relative sur l'axe des z (de couleur bleue);
(Rem 1 : J'ai donné des définitions de ce que je nomme la « rotation absolue » et la « rotation relative ». Ce sont des définitions personnelles et je ne suis pas académicien donc tu as éventuellement un jargon à m'apprendre à ce sujet.
Rem 2 : Le fait que ton procédé exécute 2 rotations absolues selon 2 premiers axes et une rotation relative selon le 3ème axe restant n'est pas un défaut invalidant. Cependant, le procédé d'exécution de 3 rotations absolues, comme son procédé complémentaire d'exécution de 3 rotations relatives approche d'une conception plus « conventionnelle », de par leur simplicité d'utilisation - L'utilisateur est respectivement soit le décor qui contraint l'objet par une rotation, soit l'objet lui-même qui se contraint par une rotation - Dans ton code, ce dicernement de repérage reste ambigü selon les axes concernés)
* Durant l'exécution, l'appui sur la touche ESPACE, provoque le démarrage d'une DEMO. Cette démonstration opère en 4 temps:
1) Les 3 axes sont mis à zéro
2) Une rotation de pi/3 est exécutée sur l'axe des x
3) Une rotation de pi/3 est exécutée sur l'axe des y
4) Une rotation de pi/3 est exécutée sur l'axe des z
On obtient une orientation particulière du trièdre.
* Au départ d'une exécution, en respectant quelques gestes simples de contrôle, tu peux procéder comme suit:
1) Fais des va-et-vients avec les touches HAUT et BAS pour contrôler la rotation sur l'axe des x (axe vert)
2) Appuie sur ESPACE pour déclencher la démo.
3) Fais à nouveau des va-et-vients selon l'axe des x, c'est-à-dire de manière similaire à l'étape 1
Question : la rotation de l'étape 3 selon l'axe des x est-elle désormais crédible?
Mon avis est de dire non car ni une rotation absolue, ni une rotation relative au trièdre ne se caractèrise en cette rotation. Cette rotation s'effectue désormais (après la démo) selon un axe intermédiaire actuellement invisible. S'il y a une rotation selon un axe « fantôme », le choix de remettre en cause ton procédé sur le plan de la crédibilité me semble conforme.
Code : Tout sélectionner
; Auteur : Le Soldat Inconnu
; Version de PB : 4.5
;
; Explication du programme :
; Exemple qui montre comment dessiner un repère XYZ en 3D
; Touche d'utilisation :
; Enter : Passage de la rotation automatique à manuelle
; X : En mode de rotation manuelle, change l'angle sur l'axe X
; Y : En mode de rotation manuelle, change l'angle sur l'axe Y
; Z : En mode de rotation manuelle, change l'angle sur l'axe Z
Structure Point3D
x.d
y.d
z.d
EndStructure
Structure Point3DP
x.d
y.d
z.d
p.d
EndStructure
#Angle_Resolution = 100
Global Dim Calculation_Cos.d(360 * #Angle_Resolution * 2)
Global Dim Calculation_Sin.d(360 * #Angle_Resolution * 2)
For i = -360 * #Angle_Resolution To 360 * #Angle_Resolution
Calculation_Cos(i + 360 * #Angle_Resolution) = Cos(i * #PI / (180 * #Angle_Resolution))
Calculation_Sin(i + 360 * #Angle_Resolution) = Sin(i * #PI / (180 * #Angle_Resolution))
Next
Procedure XYZ_Rotate(*Origine.Point3D, Angle_X_Axis.d, Angle_Y_Axis.d, Angle_Z_Axis.d, *Final.Point3D)
; 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
; 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 + 360 * #Angle_Resolution
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 + 360 * #Angle_Resolution
Cos = Calculation_Cos(Angle)
Sin = Calculation_Sin(Angle)
*Final\y = Calcul\y * Cos - *Origine\z * Sin
Calcul\z = Calcul\y * Sin + *Origine\z * Cos
Else
*Final\y = Calcul\y
Calcul\z = *Origine\z
EndIf
; Debug StrD(Calcul\x) + " , " + StrD(*Final\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 + 360 * #Angle_Resolution
Cos = Calculation_Cos(Angle)
Sin = Calculation_Sin(Angle)
*Final\z = Calcul\z * Cos - Calcul\x * Sin
*Final\x = Calcul\z * Sin + Calcul\x * Cos
Else
*Final\z = Calcul\z
*Final\x = Calcul\x
EndIf
; Debug StrD(*Final\x) + " , " + StrD(*Final\y) + " , " + StrD(*Final\z)
EndProcedure
Procedure XYFrom3D(*Origine.Point3D, Angle_X_Axis.d, Angle_Y_Axis.d, Angle_Z_Axis.d, Perspective.q, *Final.Point3DP)
; 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
XYZ_Rotate(*Origine.Point3D, Angle_X_Axis.d, Angle_Y_Axis.d, Angle_Z_Axis.d, *Final.Point3DP)
*Final\p = 1 + Abs(*Final\z) / Perspective
If *Final\z < 0
*Final\p = 1 / *Final\p
EndIf
*Final\x * *Final\p
*Final\y * *Final\p
EndProcedure
If InitSprite() = 0
End
EndIf
If OpenWindow(0, 0, 0, 500, 500, "Le Soldat Inconnu", #PB_Window_ScreenCentered | #PB_Window_SystemMenu) = 0
End
EndIf
If OpenWindowedScreen(WindowID(0), 0, 0, 500, 500, 1, 0, 0) = 0
End
EndIf
AngleX.d = 0
AngleY.d = 0
AngleZ.d = 0
Rotation_Auto = 1
FontID = LoadFont(0, "Verdana", 8, #PB_Font_HighQuality)
;- 4) INITIALISATION CLAVIER AJOUTE *************v
If InitKeyboard() = 0: MessageRequester("Erreur", "Clavier ingérable!"): End: Else: KeyboardMode(#PB_Keyboard_International): EndIf
; FIN INIT CLAVIER AJOUTE **********************^
Repeat
;- 3) ATTENTE AJOUTEE **************************v (comme d'hab)
Delay(1)
; FIN ATTENTE AJOUTEE **************************^
ClearScreen($FFFFFF)
; On change l'angle d'inclinaison du texte (en fait, on change les angles entre le repère écran et le repère du texte)
; Vous pouver mettre les paramètres que vous voulez pour changer la rotation du repère 3D
;- 5) INTERFACE CLAVIER AJOUTE ****************************v
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape): End : EndIf ; Redondance de la fin de boucle
If KeyboardPushed(#PB_Key_Up): AngleX - 0.05: EndIf
If KeyboardPushed(#PB_Key_Down): AngleX + 0.05: EndIf
If KeyboardPushed(#PB_Key_Left): AngleZ - 0.05: EndIf
If KeyboardPushed(#PB_Key_Right): AngleZ + 0.05: EndIf
If KeyboardPushed(#PB_Key_Tab): AngleY - 0.05: EndIf
If KeyboardPushed(#PB_Key_A): AngleY + 0.05: EndIf
If KeyboardPushed(#PB_Key_Space): Demo | 1 : EndIf
; FIN GESTION CLAVIER AJOUTE ******************************^
;- 6) DEMO AJOUT ****************************************v
If Demo & 3
Demo | 2
If Demo & 1
Demo & ~$1
AngleX = 0.
AngleY = 0.
AngleZ = 0.
Phase = 0
EndIf
Select Phase
Case 0
AngleX + 0.05
If AngleX => #PI / 3.
Phase = 1
EndIf
Case 1
AngleZ + 0.05
If AngleZ => #PI / 3.
Phase = 2
EndIf
Case 2
AngleY + 0.05
If AngleY => #PI / 3.
Phase = 15
EndIf
Case 15
Demo & ~$2
EndSelect
EndIf
; FIN DEMO AJOUT ****************************************^
;- 2) MOUVEMENT AUTOMATIQUE COMMENTE *********v
;If Rotation_Auto
; AngleX + 0.005
; AngleY + 0.003
; AngleZ + 0.002
;EndIf
; FIN MVT AUTO COMMENTE *********************^
If AngleX > 2 * #PI
AngleX - 2 * #PI
ElseIf AngleX < 0
AngleX + 2 * #PI
EndIf
If AngleY > 2 * #PI
AngleY - 2 * #PI
ElseIf AngleY < 0
AngleY + 2 * #PI
EndIf
If AngleZ > 2 * #PI
AngleZ - 2 * #PI
ElseIf AngleZ < 0
AngleZ + 2 * #PI
EndIf
X_Origine.Point3D
X_Origine\x = 200
Y_Origine.Point3D
Y_Origine\y = 200
Z_Origine.Point3D
Z_Origine\z = 200
StartDrawing(ScreenOutput())
DrawingFont(FontID)
DrawingMode(#PB_2DDrawing_Transparent)
; On affiche le repère
; la ligne représentant l'axe X en vert
XYFrom3D(@X_Origine, AngleX, AngleY, AngleZ, 400, @Coord.Point3DP) ; on calcul les coordonnées de l'extrémité de la ligne pour l'affichage sur l'écran
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
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.
DrawText(255 + Coord\x, 255 - Coord\y, "X", 0) ;On affiche le label de l'axe
; la ligne représentant l'axe Y en rouge
XYFrom3D(@Y_Origine, AngleX, AngleY, AngleZ, 400, @Coord.Point3DP) ; on calcul les coordonnées de l'extrémité de la ligne pour l'affichage sur l'écran
LineXY(250, 250, 250 + Coord\x, 250 - Coord\y, RGB(255, 0, 0))
Circle(250 + Coord\x, 250 - Coord\y, 5 * Coord\p, RGB(255, 0, 0))
DrawText(255 + Coord\x, 255 - Coord\y, "Y", 0)
; la ligne représentant l'axe Z en bleu
XYFrom3D(@Z_Origine, AngleX, AngleY, AngleZ, 400, @Coord.Point3DP) ; on calcul les coordonnées de l'extrémité de la ligne pour l'affichage sur l'écran
LineXY(250, 250, 250 + Coord\x, 250 - Coord\y, RGB(0, 0, 255))
Circle(250 + Coord\x, 250 - Coord\y, 5 * Coord\p, RGB(0, 0, 255))
DrawText(255 + Coord\x, 255 - Coord\y, "Z", 0)
StopDrawing()
FlipBuffers()
Repeat
Event = WindowEvent()
;- 1) INTERFACE COMMENTEE *********v
;If Event = #WM_KEYUP
; Select EventwParam()
; Case 'X'
; AngleX + #PI/6
; Case 'Y'
; AngleY + #PI/6
; Case 'Z'
; AngleZ + #PI/6
; Case 13
; Rotation_Auto = 1 - Rotation_Auto
; AngleX = 0
; AngleY = 0
; AngleZ = 0
; EndSelect
;EndIf
; FIN INTERFACE COMMENTEE ********^
If Event = #PB_Event_CloseWindow
End
EndIf
Until Event = 0
ForEver
-
- Messages : 4312
- Inscription : mer. 28/janv./2004 20:58
- Localisation : Clermont ferrand OU Olsztyn
- Contact :
Re: 3D vers 2D avec perspective
Alors, reprenons le procédé, je fais d'abord tourner sur l'axe Z, puis sur l'axe X et enfin sur l'axe Y. Car il faut bien choisir un ordre, n'est ce pas ?
Donc le seul axe dont la rotation te semblera crédible est l'axe Z, le premier.
En terme de rotation par rapport à un axe, cela te choque ? C'est normal, je parle de changement de repère, c'est un repère que je tourne sur 3 axes pour obtenir un nouveau repère.
Il faut toujours penser que la rotation du repère (et non de l'axe) se fait par rapport à l'origine et non par rapport au dernier résultat. Et en fonction de l'ordre définie de rotation soit Z puis X puis Y
Si tu veux une rotation crédible par rapport à un axe, c'est bien plus compliqué qu'un simple changement de repère et je dois dire que je sèche.
En mettant l'axe que l'on souhaite tourner en premier le rendu visuel est mieux sauf que l'orientation du repère n'est pas la même en fonction de l'ordre de rotation X Y Z (ce qui est normal). Donc ça ne va pas.
Si tu as une solution pour cela, je suis preneur.
voici mon essai
Donc le seul axe dont la rotation te semblera crédible est l'axe Z, le premier.
En terme de rotation par rapport à un axe, cela te choque ? C'est normal, je parle de changement de repère, c'est un repère que je tourne sur 3 axes pour obtenir un nouveau repère.
Il faut toujours penser que la rotation du repère (et non de l'axe) se fait par rapport à l'origine et non par rapport au dernier résultat. Et en fonction de l'ordre définie de rotation soit Z puis X puis Y
Si tu veux une rotation crédible par rapport à un axe, c'est bien plus compliqué qu'un simple changement de repère et je dois dire que je sèche.
En mettant l'axe que l'on souhaite tourner en premier le rendu visuel est mieux sauf que l'orientation du repère n'est pas la même en fonction de l'ordre de rotation X Y Z (ce qui est normal). Donc ça ne va pas.
Si tu as une solution pour cela, je suis preneur.
voici mon essai
Code : Tout sélectionner
; Auteur : Le Soldat Inconnu
; Version de PB : 4.5
;
; Explication du programme :
; Exemple qui montre comment dessiner un repère XYZ en 3D
; Touche d'utilisation :
; Enter : Passage de la rotation automatique à manuelle
; X : En mode de rotation manuelle, change l'angle sur l'axe X
; Y : En mode de rotation manuelle, change l'angle sur l'axe Y
; Z : En mode de rotation manuelle, change l'angle sur l'axe Z
Structure Point3D
x.d
y.d
z.d
EndStructure
Structure Point3DP
x.d
y.d
z.d
p.d
EndStructure
#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 XYZ_Rotate(*Origine.Point3D, Angle_X_Axis.d, Angle_Y_Axis.d, Angle_Z_Axis.d, Order.i, *Final.Point3D)
; 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
Select Order
Case 2 ;- Axe Y en premier
; Rotation sur l'axe Y
Angle.i = Angle_Y_Axis * #Angle_Resolution * 180 / #PI
Cos = Calculation_Cos(Angle)
Sin = Calculation_Sin(Angle)
Calcul\z = *Origine\z * Cos - *Origine\x * Sin
Calcul\x = *Origine\z * Sin + *Origine\x * Cos
; Rotation sur l'axe Z
Angle.i = Angle_Z_Axis * #Angle_Resolution * 180 / #PI
Cos = Calculation_Cos(Angle)
Sin = Calculation_Sin(Angle)
*Final\x = Calcul\x * Cos - *Origine\y * Sin
Calcul\y = Calcul\x * Sin + *Origine\y * Cos
; Rotation sur l'axe X
Angle.i = Angle_X_Axis * #Angle_Resolution * 180 / #PI
Cos = Calculation_Cos(Angle)
Sin = Calculation_Sin(Angle)
*Final\y = Calcul\y * Cos - Calcul\z * Sin
*Final\z = Calcul\y * Sin + Calcul\z * Cos
Case 3 ;- Axe Z en premier
; Rotation sur l'axe Z
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
; Rotation sur l'axe X
Angle.i = Angle_X_Axis * #Angle_Resolution * 180 / #PI
Cos = Calculation_Cos(Angle)
Sin = Calculation_Sin(Angle)
*Final\y = Calcul\y * Cos - *Origine\z * Sin
Calcul\z = Calcul\y * Sin + *Origine\z * Cos
; Rotation sur l'axe Y
Angle.i = Angle_Y_Axis * #Angle_Resolution * 180 / #PI
Cos = Calculation_Cos(Angle)
Sin = Calculation_Sin(Angle)
*Final\z = Calcul\z * Cos - Calcul\x * Sin
*Final\x = Calcul\z * Sin + Calcul\x * Cos
Default ;- Axe X en premier
; Rotation sur l'axe X
Angle.i = Angle_X_Axis * #Angle_Resolution * 180 / #PI
Cos = Calculation_Cos(Angle)
Sin = Calculation_Sin(Angle)
Calcul\y = *Origine\y * Cos - *Origine\z * Sin
Calcul\z = *Origine\y * Sin + *Origine\z * Cos
; Rotation sur l'axe Y
Angle.i = Angle_Y_Axis * #Angle_Resolution * 180 / #PI
Cos = Calculation_Cos(Angle)
Sin = Calculation_Sin(Angle)
*Final\z = Calcul\z * Cos - *Origine\x * Sin
Calcul\x = Calcul\z * Sin + *Origine\x * Cos
; Rotation sur l'axe Z
Angle.i = Angle_Z_Axis * #Angle_Resolution * 180 / #PI
Cos = Calculation_Cos(Angle)
Sin = Calculation_Sin(Angle)
*Final\x = Calcul\x * Cos - Calcul\y * Sin
*Final\y = Calcul\x * Sin + Calcul\y * Cos
EndSelect
EndProcedure
Procedure XYFrom3D(*Origine.Point3D, Angle_X_Axis.d, Angle_Y_Axis.d, Angle_Z_Axis.d, Order.i, Perspective.q, *Final.Point3DP)
; 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
XYZ_Rotate(*Origine.Point3D, Angle_X_Axis.d, Angle_Y_Axis.d, Angle_Z_Axis.d, Order.i, *Final.Point3DP)
*Final\p = 1 + Abs(*Final\z) / Perspective
If *Final\z < 0
*Final\p = 1 / *Final\p
EndIf
*Final\x * *Final\p
*Final\y * *Final\p
EndProcedure
If InitSprite() = 0
End
EndIf
If OpenWindow(0, 0, 0, 500, 500, "Le Soldat Inconnu", #PB_Window_ScreenCentered | #PB_Window_SystemMenu) = 0
End
EndIf
If OpenWindowedScreen(WindowID(0), 0, 0, 500, 500, 1, 0, 0) = 0
End
EndIf
AngleX.d = 0
AngleY.d = 0
AngleZ.d = 0
AngleX2.d = AngleX
AngleY2.d = AngleY
AngleZ2.d = AngleZ
Rotation_Auto = 1
X_Origine.Point3D
X_Origine\x = 200
Y_Origine.Point3D
Y_Origine\y = 200
Z_Origine.Point3D
Z_Origine\z = 200
FontID = LoadFont(0, "Verdana", 8, #PB_Font_HighQuality)
Repeat
ClearScreen($FFFFFF)
; On change l'angle d'inclinaison du texte (en fait, on change les angles entre le repère écran et le repère du texte)
; Vous pouvez mettre les paramètres que vous voulez pour changer la rotation du repère 3D
If Rotation_Auto
AngleX + 0.005
AngleY + 0.003
AngleZ + 0.002
EndIf
If AngleX > 2 * #PI
AngleX - 2 * #PI
ElseIf AngleX < 0
AngleX + 2 * #PI
EndIf
If AngleY > 2 * #PI
AngleY - 2 * #PI
ElseIf AngleY < 0
AngleY + 2 * #PI
EndIf
If AngleZ > 2 * #PI
AngleZ - 2 * #PI
ElseIf AngleZ < 0
AngleZ + 2 * #PI
EndIf
; Recherche de l'axe qui bouge pour ordonner les rotations
If AngleX <> AngleX2
Ordre = 1
ElseIf AngleY <> AngleY2
Ordre = 2
ElseIf AngleZ <> AngleZ2
Ordre = 3
EndIf
AngleX2.d = AngleX
AngleY2.d = AngleY
AngleZ2.d = AngleZ
StartDrawing(ScreenOutput())
DrawingFont(FontID)
DrawingMode(#PB_2DDrawing_Transparent)
; On affiche le repère
; la ligne représentant l'axe X en vert
XYFrom3D(@X_Origine, AngleX, AngleY, AngleZ, Ordre, 400, @Coord.Point3DP) ; on calcul les coordonnées de l'extrémité de la ligne pour l'affichage sur l'écran
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
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.
DrawText(255 + Coord\x, 255 - Coord\y, "X", 0) ;On affiche le label de l'axe
; la ligne représentant l'axe Y en rouge
XYFrom3D(@Y_Origine, AngleX, AngleY, AngleZ, Ordre, 400, @Coord.Point3DP) ; on calcul les coordonnées de l'extrémité de la ligne pour l'affichage sur l'écran
LineXY(250, 250, 250 + Coord\x, 250 - Coord\y, RGB(255, 0, 0))
Circle(250 + Coord\x, 250 - Coord\y, 5 * Coord\p, RGB(255, 0, 0))
DrawText(255 + Coord\x, 255 - Coord\y, "Y", 0)
; la ligne représentant l'axe Z en bleu
XYFrom3D(@Z_Origine, AngleX, AngleY, AngleZ, Ordre, 400, @Coord.Point3DP) ; on calcul les coordonnées de l'extrémité de la ligne pour l'affichage sur l'écran
LineXY(250, 250, 250 + Coord\x, 250 - Coord\y, RGB(0, 0, 255))
Circle(250 + Coord\x, 250 - Coord\y, 5 * Coord\p, RGB(0, 0, 255))
DrawText(255 + Coord\x, 255 - Coord\y, "Z", 0)
StopDrawing()
FlipBuffers()
Repeat
Event = WindowEvent()
If Event = #WM_KEYUP
Select EventwParam()
Case 'X'
AngleX + #PI/6
Case 'Y'
AngleY + #PI/6
Case 'Z'
AngleZ + #PI/6
Case 13
Rotation_Auto = 1 - Rotation_Auto
AngleX = 0
AngleY = 0
AngleZ = 0
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)]
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Re: 3D vers 2D avec perspective
Bonjour LSI,
Une rotation sans axe, c'est comme un oiseau sans aile...
Dans ce code, tu disposes de 12 rotations (rien que ça...) contrôlées par 12 touches. Elles doivent être toutes testées, et bourrinement s'il le faut!
2 touches par rotation (sens positif et sens négatif)
2 types de rotation (absolue et relative)
3 axes par rotations (x, y et z)
2 * 2 * 3 = 12 ; Le compte y est.
Rotations absolues:
Flèche HAUT/Flèche BAS Selon Axe X
Flèche GAUCHE/Flèche DROITE Selon Axe Z
Touche TABULATION/Touche A Selon Axe Y
Rotations relatives:
Pavé numérique TOUCHE 4/TOUCHE 6 Selon Axe i
Pavé numérique TOUCHE 8/TOUCHE 2 Selon Axe j
Pavé numérique TOUCHE 9/TOUCHE 3 Selon Axe k
Parmi ces 12 rotations qui te font tourner le trièdre dans tous les sens possibles et inimaginables, aucune rotation ne s'exécute autrement qu'autour d'un axe bien défini, calculable, clairement affiché à l'écran, et tout, et tout...
Une rotation sans axe, c'est comme un oiseau sans aile...
Ce n'est pas ma nature de critiquer sans offrir de solutions. On va dire que la roue tourne! C'est toi maintenant qui va juger si mon petit bout de code est « crédible » ou pas.Le Soldat Inconnu a écrit :Si tu as une solution pour cela, je suis preneur.

Dans ce code, tu disposes de 12 rotations (rien que ça...) contrôlées par 12 touches. Elles doivent être toutes testées, et bourrinement s'il le faut!
2 touches par rotation (sens positif et sens négatif)
2 types de rotation (absolue et relative)
3 axes par rotations (x, y et z)
2 * 2 * 3 = 12 ; Le compte y est.
Rotations absolues:
Flèche HAUT/Flèche BAS Selon Axe X
Flèche GAUCHE/Flèche DROITE Selon Axe Z
Touche TABULATION/Touche A Selon Axe Y
Rotations relatives:
Pavé numérique TOUCHE 4/TOUCHE 6 Selon Axe i
Pavé numérique TOUCHE 8/TOUCHE 2 Selon Axe j
Pavé numérique TOUCHE 9/TOUCHE 3 Selon Axe k
Parmi ces 12 rotations qui te font tourner le trièdre dans tous les sens possibles et inimaginables, aucune rotation ne s'exécute autrement qu'autour d'un axe bien défini, calculable, clairement affiché à l'écran, et tout, et tout...
Code : Tout sélectionner
;_______________________________________________________
; Titre : ROTATIONS 3D ABSOLUES ET RELATIVES (PIVOT)
; Auteur : OLLIVIER
; Date : 08/01/2011
; Outil numérique utilisé : MATRICE 2x2
; Sens de la base : INDIRECT
; Perspective ISOMETRIQUE
; Interface CLAVIER
;¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Structure IJK
Ix.D: Iy.D: Iz.D
Jx.D: Jy.D: Jz.D
Kx.D: Ky.D: Kz.D
EndStructure
Base .IJK: Base \Ix = 1. : Base \Jy = 1. : Base \Kz = 1.
Base0.IJK: Base0\Ix = 1.5: Base0\Jy = 1.5: Base0\Kz = 1.5
Global.I DskW, DskH, DskD, DskF
Global.D OnX, OnY
Procedure DrawLine(x.D, y.D, z.D, Name.S, Color.I)
x1 = DskW / 4
y1 = DskH / 4
OnX = x * 100.0
OnY = y * 100.0
x2 = x1 + OnX
y2 = y1 - OnY ; Soustraction dûe à l'opposition du sens de l'axe Y de l'écran par rapport à l'axe Y conventionnel en géométrie
LineXY(x1, y1, x2, y2, Color)
DrawText(x2 + 4, y2 + 4, Name, Color, RGB(254, 254, 254) )
x2 = x1 - OnX
y2 = y1 + OnY
LineXY(x1, y1, x2, y2, Color)
EndProcedure
Procedure RotationOrtho(*r.DOUBLE, *i.DOUBLE, w.D)
Protected.D x, y, Cos, Sin
x = *r\D
y = *i\D
Cos = Cos(w)
Sin = Sin(w)
*r\D = x * Cos - y * Sin
*i\D = y * Cos + x * Sin
EndProcedure
Macro Rotation(a, b, c)
RotationOrtho(@Base\I#a, @Base\I#b, c)
RotationOrtho(@Base\J#a, @Base\J#b, c)
RotationOrtho(@Base\K#a, @Base\K#b, c)
EndMacro
Macro Pivot(a, b, c)
Cos = Cos(c)
Sin = Sin(c)
x = Base\a#x
y = Base\a#y
z = Base\a#z
Base\a#x = x * Cos - Base\b#x * Sin
Base\a#y = y * Cos - Base\b#y * Sin
Base\a#z = z * Cos - Base\b#z * Sin
Base\b#x = x * Sin + Base\b#x * Cos
Base\b#y = y * Sin + Base\b#y * Cos
Base\b#z = z * Sin + Base\b#z * Cos
EndMacro
Define.D x, y, z, Cos, Sin, v = 0.05
InitSprite()
InitSprite3D()
InitKeyboard()
ExamineDesktops()
DskW = DesktopWidth(0)
DskH = DesktopHeight(0)
DskD = DesktopDepth(0)
DskF = DesktopFrequency(0)
WinN = OpenWindow(#PB_Any, 0, 0, DskW / 2, DskH / 2, "Rotations 3D", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(WinN), 0, 0, DskW / 2, DskH / 2, 0, 0, 0)
KeyboardMode(#PB_Keyboard_International)
Repeat
Delay(1)
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Up) : Rotation(y, z, v) : EndIf
If KeyboardPushed(#PB_Key_Down) : Rotation(y, z, -v): EndIf
If KeyboardPushed(#PB_Key_Tab) : Rotation(x, z, v) : EndIf
If KeyboardPushed(#PB_Key_A) : Rotation(x, z, -v): EndIf
If KeyboardPushed(#PB_Key_Left) : Rotation(x, y, v) : EndIf
If KeyboardPushed(#PB_Key_Right): Rotation(x, y, -v): EndIf
If KeyboardPushed(#PB_Key_Pad8) : Pivot(J, K, v): EndIf
If KeyboardPushed(#PB_Key_Pad2) : Pivot(J, K, -v): EndIf
If KeyboardPushed(#PB_Key_Pad4) : Pivot(I, J, v): EndIf
If KeyboardPushed(#PB_Key_Pad6) : Pivot(I, J, -v): EndIf
If KeyboardPushed(#PB_Key_Pad9) : Pivot(K, I, v): EndIf
If KeyboardPushed(#PB_Key_Pad3) : Pivot(K, I, -v): EndIf
ClearScreen(RGB(254, 254, 254) )
StartDrawing(ScreenOutput() )
DrawLine(Base0\Ix, Base0\Iy, Base0\Iz, "X", RGB(1, 128, 1) )
DrawLine(Base0\Jx, Base0\Jy, Base0\Jz, "Y", RGB(1, 1, 128) )
DrawLine(Base0\Kx, Base0\Ky, Base0\Kz, "Z", RGB(128, 1, 1) )
DrawLine(Base \Ix, Base \Iy, Base \Iz, "i", RGB(1, 254, 1) )
DrawLine(Base \Jx, Base \Jy, Base \Jz, "j", RGB(1, 1, 254) )
DrawLine(Base \Kx, Base \Ky, Base \Kz, "k", RGB(254, 1, 1) )
StopDrawing()
FlipBuffers()
Until WindowEvent() = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
-
- Messages : 4312
- Inscription : mer. 28/janv./2004 20:58
- Localisation : Clermont ferrand OU Olsztyn
- Contact :
Re: 3D vers 2D avec perspective
en fait, tu utilises 2 repères. un ortho et un orienté. C'est bien vu 
Question ?
Pour ajouter un point de coordonné x=3, y=2, z=1 et l'afficher, je dois rentrer quelle coordonnée dans ce repère "double" ? (Repère IJK)

Question ?
Pour ajouter un point de coordonné x=3, y=2, z=1 et l'afficher, je dois rentrer quelle coordonnée dans ce repère "double" ? (Repère IJK)
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)]
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Re: 3D vers 2D avec perspective
Il y a plus ou moins deux sortes de possibilités d'ajouter un point.
La première consiste à créer autant de base que de points.
La seconde consiste à créer des points relatifs à une base.
J'ai déjà posté la première possibilité sur ce forum (« Vol libre dans un champ d'étoiles » dans la section 3D).
Voici donc la seconde possibilité dans le code qui suit.
La première consiste à créer autant de base que de points.
La seconde consiste à créer des points relatifs à une base.
J'ai déjà posté la première possibilité sur ce forum (« Vol libre dans un champ d'étoiles » dans la section 3D).
Voici donc la seconde possibilité dans le code qui suit.
Code : Tout sélectionner
;_______________________________________________________
; Titre : ROTATIONS 3D ABSOLUES ET RELATIVES (PIVOT)
; Auteur : OLLIVIER
; Date : 08/01/2011
; Outil numérique utilisé : MATRICE 2x2
; Sens de la base : INDIRECT
; Perspective ISOMETRIQUE
; Interface CLAVIER
;¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
; Ajout d'un nuage de points relatif à IJK (MAJ#1)
;¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Structure IJK
Ix.D: Iy.D: Iz.D
Jx.D: Jy.D: Jz.D
Kx.D: Ky.D: Kz.D
EndStructure
Base .IJK: Base \Ix = 1. : Base \Jy = 1. : Base \Kz = 1.
Base0.IJK: Base0\Ix = 1.5: Base0\Jy = 1.5: Base0\Kz = 1.5
Global.I DskW, DskH, DskD, DskF
Global.D OnX, OnY
;{ MAJ#1 }
#PQty = 1024
Structure V3
x.D: y.D: z.D
EndStructure
Global Dim Cloud.V3(#PQty)
For I = 0 To #PQty
Cloud(I)\x = Random(200) / 200. - 0.5
Cloud(I)\y = Random(200) / 200. - 0.5
Cloud(I)\z = Random(200) / 200. - 0.5
Next
Procedure DrawPoint(x.D, y.D, z.D)
x1 = DskW / 4
y1 = DskH / 4
OnX = x * 100.0
OnY = y * 100.0
x2 = x1 + OnX
y2 = y1 - OnY ; Soustraction dûe à l'opposition du sens de l'axe Y de l'écran par rapport à l'axe Y conventionnel en géométrie
Circle(x2, y2, 2, RGB(1, 1, 1) )
EndProcedure
Procedure DrawCloud(*Base.IJK)
Protected.D x, y, z
For I = 0 To #PQty
With Cloud(I)
x = \x * *Base\Ix + \y * *Base\Jx + \z * *Base\Kx
y = \x * *Base\Iy + \y * *Base\Jy + \z * *Base\Ky
z = \x * *Base\Iz + \y * *Base\Jz + \z * *Base\Kz
DrawPoint(x, y, z)
EndWith
Next
EndProcedure
;}
Procedure DrawLine(x.D, y.D, z.D, Name.S, Color.I)
x1 = DskW / 4
y1 = DskH / 4
OnX = x * 100.0
OnY = y * 100.0
x2 = x1 + OnX
y2 = y1 - OnY ; Soustraction dûe à l'opposition du sens de l'axe Y de l'écran par rapport à l'axe Y conventionnel en géométrie
LineXY(x1, y1, x2, y2, Color)
DrawText(x2 + 4, y2 + 4, Name, Color, RGB(254, 254, 254) )
x2 = x1 - OnX
y2 = y1 + OnY
LineXY(x1, y1, x2, y2, Color)
EndProcedure
Procedure RotationOrtho(*r.DOUBLE, *i.DOUBLE, w.D)
Protected.D x, y, Cos, Sin
x = *r\D
y = *i\D
Cos = Cos(w)
Sin = Sin(w)
*r\D = x * Cos - y * Sin
*i\D = y * Cos + x * Sin
EndProcedure
Macro Rotation(a, b, c)
RotationOrtho(@Base\I#a, @Base\I#b, c)
RotationOrtho(@Base\J#a, @Base\J#b, c)
RotationOrtho(@Base\K#a, @Base\K#b, c)
EndMacro
Macro Pivot(a, b, c)
Cos = Cos(c)
Sin = Sin(c)
x = Base\a#x
y = Base\a#y
z = Base\a#z
Base\a#x = x * Cos - Base\b#x * Sin
Base\a#y = y * Cos - Base\b#y * Sin
Base\a#z = z * Cos - Base\b#z * Sin
Base\b#x = x * Sin + Base\b#x * Cos
Base\b#y = y * Sin + Base\b#y * Cos
Base\b#z = z * Sin + Base\b#z * Cos
EndMacro
Define.D x, y, z, Cos, Sin, v = 0.05
InitSprite()
InitSprite3D()
InitKeyboard()
ExamineDesktops()
DskW = DesktopWidth(0)
DskH = DesktopHeight(0)
DskD = DesktopDepth(0)
DskF = DesktopFrequency(0)
WinN = OpenWindow(#PB_Any, 0, 0, DskW / 2, DskH / 2, "Rotations 3D", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(WinN), 0, 0, DskW / 2, DskH / 2, 0, 0, 0)
KeyboardMode(#PB_Keyboard_International)
Repeat
Delay(1)
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Up) : Rotation(y, z, v) : EndIf
If KeyboardPushed(#PB_Key_Down) : Rotation(y, z, -v): EndIf
If KeyboardPushed(#PB_Key_Tab) : Rotation(x, z, v) : EndIf
If KeyboardPushed(#PB_Key_A) : Rotation(x, z, -v): EndIf
If KeyboardPushed(#PB_Key_Left) : Rotation(x, y, v) : EndIf
If KeyboardPushed(#PB_Key_Right): Rotation(x, y, -v): EndIf
If KeyboardPushed(#PB_Key_Pad8) : Pivot(J, K, v): EndIf
If KeyboardPushed(#PB_Key_Pad2) : Pivot(J, K, -v): EndIf
If KeyboardPushed(#PB_Key_Pad4) : Pivot(I, J, v): EndIf
If KeyboardPushed(#PB_Key_Pad6) : Pivot(I, J, -v): EndIf
If KeyboardPushed(#PB_Key_Pad9) : Pivot(K, I, v): EndIf
If KeyboardPushed(#PB_Key_Pad3) : Pivot(K, I, -v): EndIf
ClearScreen(RGB(254, 254, 254) )
StartDrawing(ScreenOutput() )
DrawLine(Base0\Ix, Base0\Iy, Base0\Iz, "X", RGB(1, 128, 1) )
DrawLine(Base0\Jx, Base0\Jy, Base0\Jz, "Y", RGB(1, 1, 128) )
DrawLine(Base0\Kx, Base0\Ky, Base0\Kz, "Z", RGB(128, 1, 1) )
DrawLine(Base \Ix, Base \Iy, Base \Iz, "i", RGB(1, 254, 1) )
DrawLine(Base \Jx, Base \Jy, Base \Jz, "j", RGB(1, 1, 254) )
DrawLine(Base \Kx, Base \Ky, Base \Kz, "k", RGB(254, 1, 1) )
DrawCloud(Base) ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< MAJ#1
StopDrawing()
FlipBuffers()
Until WindowEvent() = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
-
- Messages : 4312
- Inscription : mer. 28/janv./2004 20:58
- Localisation : Clermont ferrand OU Olsztyn
- Contact :
Re: 3D vers 2D avec perspective
Ah oui, super simple, je n'avais pas pris le problème dans le bon sens 
Merci

Merci
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)]
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Re: 3D vers 2D avec perspective
Dans ton entête, tu dis utiliser une matrice. Elle est où dans le code? C'est la structure? Car je ne connais pas de façon réservée d'en faire en PB.
Re: 3D vers 2D avec perspective
Bonjour Warkering,
J'ai isolé toutes les opérations sur les matrices 2x2 dans la macro Rotation() avec des commentaires lignes 39 et 40 pour imaginer comment chacune de ces matrices se compose. Du point de vue de l'utilisateur, il y a 6 utilisations de la macro donc 6 matrices 2x2. Mais l'interface clavier étant, le sens de rotation de chacune d'entre elle est propre à la touche concernée. Donc, du point de vue du programmeur, il y a 12 utilisations, donc 12 matrices 2x2.
J'ai isolé toutes les opérations sur les matrices 2x2 dans la macro Rotation() avec des commentaires lignes 39 et 40 pour imaginer comment chacune de ces matrices se compose. Du point de vue de l'utilisateur, il y a 6 utilisations de la macro donc 6 matrices 2x2. Mais l'interface clavier étant, le sens de rotation de chacune d'entre elle est propre à la touche concernée. Donc, du point de vue du programmeur, il y a 12 utilisations, donc 12 matrices 2x2.
Code : Tout sélectionner
;_______________________________________________________
; Titre : ROTATIONS 3D ABSOLUES ET RELATIVES (PIVOT)
; Auteur : OLLIVIER
; Date : 08/01/2011
; Outil numérique utilisé : MATRICE 2x2
; Sens de la base : INDIRECT
; Perspective ISOMETRIQUE
; Interface CLAVIER
;¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Structure IJK
Ix.D: Iy.D: Iz.D
Jx.D: Jy.D: Jz.D
Kx.D: Ky.D: Kz.D
EndStructure
Base .IJK: Base \Ix = 1. : Base \Jy = 1. : Base \Kz = 1.
Base0.IJK: Base0\Ix = 1.5: Base0\Jy = 1.5: Base0\Kz = 1.5
Global.I DskW, DskH, DskD, DskF, AffW, AffH
Global.D OnX, OnY
Procedure DrawLine(x.D, y.D, z.D, Name.S, Color.I)
x1 = AffW / 2
y1 = AffH / 2
OnX = x * 100.0
OnY = y * 100.0
x2 = x1 + OnX
y2 = y1 - OnY ; Soustraction dûe à l'opposition du sens de l'axe Y de l'écran par rapport à l'axe Y conventionnel en géométrie
LineXY(x1, y1, x2, y2, Color)
DrawText(x2 + 4, y2 + 4, Name, Color, RGB(254, 254, 254) )
x2 = x1 - OnX
y2 = y1 + OnY
LineXY(x1, y1, x2, y2, Color)
EndProcedure
Macro Rotation(a, b, Cos, Sin)
x = a
y = b
a = x * Cos - y * Sin ; Matrice 2x2 : | a Cos |
b = x * Sin + y * Cos ; | b -Sin |
EndMacro
Macro RotationAbsolue(a, b, c)
Cos = Cos(c)
Sin = Sin(c)
Rotation(Base\I#a, Base\I#b, Cos, Sin)
Rotation(Base\J#a, Base\J#b, Cos, Sin)
Rotation(Base\K#a, Base\K#b, Cos, Sin)
EndMacro
Macro RotationRelative(a, b, c)
Cos = Cos(c)
Sin = Sin(c)
Rotation(Base\a#x, Base\b#x, Cos, Sin)
Rotation(Base\a#y, Base\b#y, Cos, Sin)
Rotation(Base\a#z, Base\b#z, Cos, Sin)
EndMacro
Define.D x, y, z, Cos, Sin, v = 0.05
InitSprite()
InitSprite3D()
InitKeyboard()
ExamineDesktops()
DskW = DesktopWidth(0)
DskH = DesktopHeight(0)
DskD = DesktopDepth(0)
DskF = DesktopFrequency(0)
AffW = DskW / 4 * 3
AffH = DskH / 4 * 3
WinN = OpenWindow(#PB_Any, 0, 0, AffW, AffH, "Rotations 3D", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(WinN), 0, 0, AffW, AffH, 0, 0, 0)
KeyboardMode(#PB_Keyboard_International)
Repeat
Delay(1)
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Up) : RotationAbsolue(y, z, v) : EndIf
If KeyboardPushed(#PB_Key_Down) : RotationAbsolue(y, z, -v): EndIf
If KeyboardPushed(#PB_Key_Tab) : RotationAbsolue(x, z, v) : EndIf
If KeyboardPushed(#PB_Key_A) : RotationAbsolue(x, z, -v): EndIf
If KeyboardPushed(#PB_Key_Left) : RotationAbsolue(x, y, v) : EndIf
If KeyboardPushed(#PB_Key_Right): RotationAbsolue(x, y, -v): EndIf
If KeyboardPushed(#PB_Key_Pad8) : RotationRelative(J, K, v): EndIf
If KeyboardPushed(#PB_Key_Pad2) : RotationRelative(J, K, -v): EndIf
If KeyboardPushed(#PB_Key_Pad4) : RotationRelative(I, J, v): EndIf
If KeyboardPushed(#PB_Key_Pad6) : RotationRelative(I, J, -v): EndIf
If KeyboardPushed(#PB_Key_Pad9) : RotationRelative(K, I, v): EndIf
If KeyboardPushed(#PB_Key_Pad3) : RotationRelative(K, I, -v): EndIf
ClearScreen(RGB(254, 254, 254) )
StartDrawing(ScreenOutput() )
DrawLine(Base0\Ix, Base0\Iy, Base0\Iz, "X", RGB(1, 128, 1) )
DrawLine(Base0\Jx, Base0\Jy, Base0\Jz, "Y", RGB(1, 1, 128) )
DrawLine(Base0\Kx, Base0\Ky, Base0\Kz, "Z", RGB(128, 1, 1) )
DrawLine(Base \Ix, Base \Iy, Base \Iz, "i", RGB(1, 254, 1) )
DrawLine(Base \Jx, Base \Jy, Base \Jz, "j", RGB(1, 1, 254) )
DrawLine(Base \Kx, Base \Ky, Base \Kz, "k", RGB(254, 1, 1) )
StopDrawing()
FlipBuffers()
Until WindowEvent() = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
Re: 3D vers 2D avec perspective
bonjour
Merci LSI et pour Ollivier de sa lumière.
Au début de notre ère l'olivier servait à produire l'huile des lampes
c'est pour cela que le rameau d'olivier représente symboliquement la lumière.
Quand Noé voit la colombe blanche revenir avec un rameau d'olivier,
il reçoit le signe qu'il a atteint la Lumière Divine.
il faut aussi remarquer qu'Ollivier porte deux ailes
ce qui donne pour titre " Vol libre dans un champ d'étoiles "
Cordialement
Merci LSI et pour Ollivier de sa lumière.
Au début de notre ère l'olivier servait à produire l'huile des lampes
c'est pour cela que le rameau d'olivier représente symboliquement la lumière.
Quand Noé voit la colombe blanche revenir avec un rameau d'olivier,
il reçoit le signe qu'il a atteint la Lumière Divine.
il faut aussi remarquer qu'Ollivier porte deux ailes

Cordialement
Re: 3D vers 2D avec perspective
tiens "qu'Ollivier" contient aussi 2 L O Q hum !!kernadec a écrit : il faut aussi remarquer qu'Ollivier porte deux ailesce qui donne pour titre " Vol libre dans un champ d'étoiles "
Cordialement

