[DEFI] Dessiner

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

[DEFI] Dessiner

Message par Mesa »

Le défi est le suivant :

Créer une procédure qui dessine un rectangle ABCD avec seulement 2 points A et B donnés et où les seuls opérateurs permis sont "+, -, *, /, sqrt, line() et lineXY()".


Donc, interdiction d'utiliser
la fonction box(), ni rectangle_(), ...
ni les api,
ni les opérateurs de trigo comme sin, cos, tan, atan, acos, etc,
pas le droit d'utiliser non plus une table de nombre, pas de tableau, ni de liste, ni de map, ni de datasection, etc,...
ni quoi que ce soit d'autre.

C'est du niveau Lycée, 1ère S.

Défi subsidiaire : Faire tourner ce rectangle.

Réponse dans 7 ou 14 jours avec le code commenté.

Mesa.


REPONSE

Code : Tout sélectionner


Procedure Rectangle(x0, y0, x1, y1, e, couleur)
  ; -----------------------------------
  ;
  ; A(x0,y0)_________________B(x1,y1)
  ;        |                 |
  ;        |                 |
  ;        |                 |
  ; C(x2,y2)_________________D(x3,y3)
  ;
  ; -----------------------------------
  
  ;Tracé de la ligne AB
  LineXY(x0, y0, x1, y1, couleur)
  
  ;Rotation à 90° du point B autour du point A
  ;Les coordonnées de ce point sont x2_90 et y2_90
  x2_90=-(y1-y0)+x0
  y2_90=x1-x0+y0
  
  ; x3_90=(y1-y0)+x0
  ; y3_90=-1*(x1-x0)+y0
  
  ;Calcul de la longueur du segment AB
  L.f=Sqr((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0))
  
  ;Calcul du coefficient de proportionnalité
  ;sans lui, on ne pourrait dessiner que des carrés ou des triangles-rectangles
  H.f=e/L
    
  ;Calcul des coordonnées du point C par homothétie (réduction)
  x2=H*(x2_90-x0)+x0
  y2=H*(y2_90-y0)+y0
  
  ;Tracé de la ligne AC
  LineXY(x0, y0, x2, y2, couleur)
  
  ;Calcul des coordonnées du point D : les vecteurs AB et CD sont colinéaires 
  x3=x1-x0+x2
  y3=y1-y0+y2
  
  ;Tracé de la ligne BD
  LineXY(x1,y1,x3, y3,couleur)
  
  ;Tracé de la ligne CD
  LineXY(x2,y2,x3, y3, couleur)
  
EndProcedure



;- openwindows
If OpenWindow(0, 100, 200, 300, 300, "Test de rotation de rectangle 2D")
  
  If CreateImage(0, 300, 300)
    
    If StartDrawing(ImageOutput(0))
      Box(0,0,300,300,RGB(0,128,128)) ; Fond vert
      Rectangle(10,10,110,10,30,RGB(255,255,255))
      Rectangle(10,60,30,60,100,RGB(255,255,0))
      Rectangle(180,20,220,60,60,RGB(0,255,0))
      Rectangle(100,60,210,160,40,RGB(0,255,0))
      Rectangle(100,260,210,180,25,RGB(0,255,255))
      Rectangle(100,260,210,180,-25,RGB(0,255,255))
      Rectangle(200,240,250,240,50,RGB(255,255,255))
      StopDrawing()
    EndIf      
    
    ; Affichage du rectangle dans un ImageGadget 
    ImageGadget(0, 0, 0, 0, 0, ImageID(0))
    ;Delay(100)
  EndIf
  
  Repeat
    Event = WaitWindowEvent() 
  Until Event = #PB_Event_CloseWindow  
  
EndIf

End 

Défi subsidiaire

Code : Tout sélectionner



Procedure Rectangle(x0, y0, x1, y1, e, couleur)
  ; -----------------------------------
  ;
  ; A(x0,y0)_________________B(x1,y1)
  ;        |                 |
  ;        |                 |
  ;        |                 |
  ; C(x2,y2)_________________D(x3,y3)
  ;
  ; -----------------------------------
  
  ;Tracé de la ligne AB
  LineXY(x0, y0, x1, y1, couleur)
  
  ;Rotation à 90° du point B autour du point A
  ;Les coordonnées de ce point sont x2_90 et y2_90
  x2_90=-(y1-y0)+x0
  y2_90=x1-x0+y0
  
  ; x3_90=(y1-y0)+x0
  ; y3_90=-1*(x1-x0)+y0
  
  ;Calcul de la longueur du segment AB
  L.f=Sqr((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0))
  
  ;Calcul du coefficient de proportionnalité
  ;sans lui, on ne pourrait dessiner que des carrés ou des triangles-rectangles
  H.f=e/L
  
  
  ;Calcul des coordonnées du point C par homothétie (réduction)
  x2=H*(x2_90-x0)+x0
  y2=H*(y2_90-y0)+y0
  
  ;Tracé de la ligne AC
  LineXY(x0, y0, x2, y2, couleur)
  
  ;Calcul des coordonnées du point D : les vecteurs AB et CD sont colinéaires 
  x3=x1-x0+x2
  y3=y1-y0+y2
  
  ;Tracé de la ligne BD
  LineXY(x1,y1,x3, y3,couleur)
  
  ;Tracé de la ligne CD
  LineXY(x2,y2,x3, y3, couleur)
  
EndProcedure



;- openwindows
If OpenWindow(0, 100, 200, 300, 300, "Test de rotation de rectangle 2D")
  
  If CreateImage(0, 300, 300)
    xc=150
    yc=150
    R=100
    For a=0 To 360
      ; Ici les sin et cos ne servent pas à dessiner le rectangle
      ; mais juste à le faire tourner autour de A
      ; ça permet de vérifier que l'on peut dessiner un rectangle dans "toutes les directions"
      x=R*Cos(Radian(a))+xc
      y=R*Sin(Radian(a))+yc
      If StartDrawing(ImageOutput(0))
        Box(0,0,300,300,0)
        Rectangle(xc,yc,x,y,30,RGB(255,255,255))
        StopDrawing()
      EndIf
      
      
      ; Affichage du rectangle dans un ImageGadget 
      ImageGadget(0, 0, 0, 0, 0, ImageID(0))
      ;Delay(100)
    Next a
  EndIf
  
  Repeat
    Event = WaitWindowEvent() 
  Until Event = #PB_Event_CloseWindow  
  
EndIf

End 

M.
Dernière modification par Mesa le sam. 01/mars/2014 11:42, modifié 1 fois.
Avatar de l’utilisateur
GallyHC
Messages : 1708
Inscription : lun. 17/déc./2007 12:44

Re: [DEFI] Dessiner

Message par GallyHC »

Bonjour,

Tu ne donnerais pas AC que AB pour dessiner le rectangle ;) si on part d'un rectangle du style

Code : Tout sélectionner

    A +------------------+ B
      |                  |
      |                  |
      |                  |
    D +------------------+ C
Cordialement,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: [DEFI] Dessiner

Message par Micoute »

Bonsoir Mesa, comme ça, est-ce que c'est permis

Code : Tout sélectionner

Procedure TraitVertical(X, Y, Hauteur, Epaisseur=1, Couleur=0) ; Trace un trait vertical avec épaisseur et couleur choisies
	Protected i = 0
	
	If Epaisseur >0
		While i < Epaisseur
			Line(x+i,y,1,Hauteur,Couleur)
			i+1
		Wend
	Else
		Line(x,y,1,Hauteur,Couleur)
	EndIf
EndProcedure

Procedure TraitHorizontal(X, Y, Longueur, Epaisseur=1, Couleur=0) ; Trace un trait horizontal avec épaisseur et couleur choisies
	Protected i = 0
	
	If Epaisseur > 0
		While i < Epaisseur
			Line(x,y+i,Longueur,1,Couleur)
			i+1
		Wend
	Else
		Line(x,y,Longueur,1,Couleur)
	EndIf
EndProcedure

Procedure Cadre(x, y, Largeur, Hauteur, Epaisseur=1, CouleurCadre=0); Trace un cadre simple de la couleur choisie
		;Ligne supérieure
		TraitHorizontal(x,y,Largeur, Epaisseur, CouleurCadre)
		;Ligne gauche
		TraitVertical(x,y,Hauteur+Epaisseur,Epaisseur,CouleurCadre)
		;Ligne droite
		TraitVertical(x+Largeur,y,Hauteur+Epaisseur,Epaisseur,CouleurCadre)
    	;Ligne inférieure
    	TraitHorizontal(x,y+Hauteur,Largeur,Epaisseur,CouleurCadre)
EndProcedure
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
majikeyric
Messages : 602
Inscription : dim. 08/déc./2013 23:19
Contact :

Re: [DEFI] Dessiner

Message par majikeyric »

Les points A et B sont des angles opposés dans le rectangle ?
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: [DEFI] Dessiner

Message par Backup »

oui parceque sinon , c'est impossible
on ne connaitrai que la largeur ... pas la hauteur .... (a moins que ça n'ai aucune importance )
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [DEFI] Dessiner

Message par falsam »

majikeyric a écrit :Les points A et B sont des angles opposés dans le rectangle ?
A mon avis non. Sinon c'est trop facile.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: [DEFI] Dessiner

Message par PAPIPP »

Bonjour à tous
Voici une étude théorique du pb
Soit A( Xa,Ya ) et B (Xb Yb) 2 points opposés du rectangle trouvez C et D
Tout rectangle se trouvant sur le cercle de diamètre AB
de centre Xc=Xa+(Xb-Xa)/2 et Yc=Ya+(Yb-Ya)/2
Répond au Pb . En effet l'angle ACB est toujours un angle droit. Le cercle est donc le lieu géométrique des points C ou D
Donc l’équation du cercle en coordonnée cartésienne est
(x − x₀)² + (y − y₀)² = c², où x₀, y₀ et c sont des constantes réelles, avec c > 0.
C'est un cercle de centre (x₀,y₀) et de rayon c.
Image

En remplacement de x₀=Xc=Xa+(Xb-Xa)/2 et y₀=Yc= Ya+(Yb-Ya)/2
Equation du cercle (X-( Xa+(Xb-Xa)/2 )) ²+ (Y-( Ya+(Yb-Ya)/2)) ²=((Xb-Xa)/2) ²+((Yb-Ya)/2) ²
On peut ainsi définir le point C(XXc,YYc) avec cette équation et trouver le point D(XXd,YYd) symétrique au point C par rapport au centre

Remarques :
Comme nous avons une seule équation et 2 inconnues il faut imposer l’une de ces inconnues
Mais on peut remarquer sur le graphique que X ne peut être compris qu’entre 2 valeurs l’une mini et l’autre max
Xmin= Xc-rayon et Xmax=Xc+rayon
Avec rayon² = ((Xb-Xa)/2) ²+((Yb-Ya)/2) ²

A+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: [DEFI] Dessiner

Message par Micoute »

Bonjour PAPIPP, voilà ce que j’appelle un très bon raisonnement !

@Mesa, peut-on considérer que les points A et B sont l’hypoténuse de 2 triangles rectangles adjacents et tête-bêche ?
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: [DEFI] Dessiner

Message par Mesa »

@Tous
Merci de donner un code fonctionnel avec openwindow() etc.
C'est plus facile à tester.

@GallyHC
C'est bien un rectangle de ce type
A +------------------+ B
| |
| |
| |
C +------------------+ D
@Micoute
C'est une bonne solution mais j'ai oublié de préciser que le rectangle doit pouvoir être dessiné dans n'importe quel position (faire tourner le rectangle autour du point A). Par exemple, le côté AB doit pouvoir faire un angle de 47° par rapport à l'horizontal.

@majikeyric
Les points A et B forment l'un des côtés, comme sur le dessin ci-dessus.

@Dobro
D'une façon ou d'une autre, il faut que le programmeur connaisse la longueur et la largeur à partir de 2 points et de quelque chose d'autre (Voir le code de Micoute) ...

@PAPIPP
Comme nous avons une seule équation et 2 inconnues il faut imposer l’une de ces inconnues
C'est vrai :D (Voir le code de Micoute)

@Micoute
peut-on considérer que les points A et B sont l’hypoténuse de 2 triangles rectangles adjacents et tête-bêche ?
Pourquoi pas, mais je n'ai pas utilisé cette voie. Reste à vérifier quand même.

M.
Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: [DEFI] Dessiner

Message par Micoute »

Bonjour à tous, voici mon code :

Code : Tout sélectionner

Procedure TraitHorizontal(X, Y, Longueur, Epaisseur=1, Couleur=0) ; Trace un trait horizontal avec épaisseur et couleur choisies
  Protected i = 0
  
  If Epaisseur > 0
    While i < Epaisseur
      Line(x,y+i,Longueur,1,Couleur)
      i+1
    Wend
  Else
    Line(x,y,Longueur,1,Couleur)
  EndIf
EndProcedure

Procedure TraitVertical(X, Y, Hauteur, Epaisseur=1, Couleur=0) ; Trace un trait vertical avec épaisseur et couleur choisies
	Protected i = 0
	
	If Epaisseur >0
		While i < Epaisseur
			Line(x+i,y,1,Hauteur,Couleur)
			i+1
		Wend
	Else
		Line(x,y,1,Hauteur,Couleur)
	EndIf
EndProcedure

Procedure Cadre(X0,Y0,X1,Y1, Epaisseur=1, CouleurCadre=0) ; Trace un cadre simple de la couleur choisie
  TraitHorizontal(X0, Y0, X1-X0,Epaisseur,CouleurCadre)
  TraitVertical(X1, Y0, Y1-Y0,Epaisseur,CouleurCadre)
  TraitHorizontal(X0, Y1, X1-X0,Epaisseur,CouleurCadre)
  TraitVertical(X0, Y0, Y1-Y0,Epaisseur,CouleurCadre)
EndProcedure

;***TEST***

Largeur=1400 - 10
Hauteur=768 - 30

If OpenWindow(0, 0, 0, Largeur, Hauteur, "Rectangle", #PB_Window_SystemMenu ) 
  If StartDrawing(WindowOutput(0))
    Cadre(240,650,991,160,3,#Blue)
  StopDrawing()    
  EndIf 
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow 
EndIf
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: [DEFI] Dessiner

Message par Backup »

...
Dernière modification par Backup le mar. 19/août/2014 9:45, modifié 4 fois.
Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: [DEFI] Dessiner

Message par Micoute »

Bonjour Dobro, tu a utilisé une fonction interdite à la ligne 23

Code : Tout sélectionner

box(x_pos,y_pos+y,epaisseur,epaisseur,couleur) : box(x_pos+largeur,y_pos+y,epaisseur,epaisseur,couleur)
Je ne voudrais pas être pointilleux, mais un défi, c'est comme un test de laboratoire, il faut jouer le jeu !

Je pense qu'il nous manque le paramètre orientation ! Je pense même qu'on pourrait faire un sprite, ce serait plus facile pour le faire tourner !
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: [DEFI] Dessiner

Message par Backup »

Micoute a écrit :Bonjour Dobro, tu a utilisé une fonction interdite à la ligne 23

Code : Tout sélectionner

box(x_pos,y_pos+y,epaisseur,epaisseur,couleur) : box(x_pos+largeur,y_pos+y,epaisseur,epaisseur,couleur)
Je ne voudrais pas être pointilleux, mais un défi, c'est comme un test de laboratoire, il faut jouer le jeu !

Je pense qu'il nous manque le paramètre orientation ! Je pense même qu'on pourrait faire un sprite, ce serait plus facile pour le faire tourner !

Dobro a écrit :note que je n'utilise pas la fonction Box pour dessiner le rectangle , mais je m'en sert de Plot()[/b]
pour le prouver, j'ai remplacé mes box par circle !!
le but c'est pas de ne pas employer Box , c'est de ne pas l'employer pour faire le Rectangle !

mais Box peut servir a dessiner un Gros point !! ; c'est ce que je faisais !

note: j'en ai profité pour corriger un petit bug ;)
Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: [DEFI] Dessiner

Message par Micoute »

Ok, ok, ne te fâches pas, je voulais juste faire remarquer qu'il était stipulé
interdiction d'utiliser
la fonction box(), ni rectangle_(), ...
ni les api,
ni les opérateurs de trigo comme sin, cos, tan, atan, acos, etc,
pas le droit d'utiliser non plus une table de nombre, pas de tableau, ni de liste, ni de map, ni de datasection, etc,...
ni quoi que ce soit d'autre.
C'est pourquoi, je ne voulais pas paraître pointilleux, ni emmerdeur, ni un boulet, etc...

Je ne me sens pas net vis-à-vis de toi !
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: [DEFI] Dessiner

Message par Mesa »

Je ne peux que vous encourager à continuer car les codes proposés ne peuvent pas dessiner un rectangle incliné comme ça :

Image

M.
Répondre