Utiliser CANVAS.arc à partir d 'un centre de cercle, rayon et angle de départ et

snipersolo Messages postés 5 Date d'inscription mardi 10 décembre 2002 Statut Membre Dernière intervention 24 avril 2006 - 24 nov. 2005 à 00:29
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 - 25 nov. 2005 à 23:06
Bonjour a tous!
J'en fais appel a vous après presque 5h de recherche.
Toujours ces problèmes avec la fonction CANVAS.arc...
Je cherche à effectuer de l'importation de fichier DXF
LE FICHIER me fournit les informations suivantes :
le centre du cercle, le rayon et l angle de départ et l'angle d'arrivée
J'ai donc créer plusieurs fonctions permettant de transformer tout cela de facon à les mettre a permettre un affichage avec CANVAS.arc
Le code est un peu lourd mais il me parait fonctionner.
Hors à l'affichage rien de bien !
J'espère que quelqu'un saura trouver la petite erreur qui fait que cela ne marche pas !


unit CArc;


interface


uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, StdCtrls, ExtCtrls, Cpoint, CCercle, Math, CHeader;


type Tpoint = record
X:real;
Y:real;
end;


Type
ClasseArc = class
private
{ Private declarations }
TypeObjet : string ;
Centre : Tpoint;
Rayon : Real;
Couleur : string;
AngleDepart : real;
AngleArrive : real;
public
constructor Create(abs,ord : real; r:real ; Angle:real ;color:integer;TypeObjet : String);overload;
procedure ProcedureSetCoordonnees(abs,ord : real);
procedure ProcedureSetRayon(r : real);
procedure ProcedureSetAngleDepart(ang:real);
procedure ProcedureSetAngleArrive(ang:real);
procedure ProcedureSetCouleur(color : string);
function functionGetRayon:real;
function functionGetCouleur:string;
procedure ProcedureDessineToi(image1:timage;header:ClasseHeader);


Function FunctionSetPointAngle1(Centre : Tpoint;rayon :real) : Tpoint;
Function FunctionSetPointAngle2(Centre : Tpoint;rayon :real) : Tpoint;
Function FunctionTransformeAnglePoint(Centre : Tpoint;rayon,angleParam :real):Tpoint;


end;

implementation


uses
Vector_delphi;


constructor ClasseArc.Create(abs,ord:real;r:real;Angle:real;color:integer;TypeObjet : String);
begin
self.TypeObjet := 'ClasseArc';
end;


procedure ClasseArc.ProcedureSetCoordonnees(abs,ord : real);
begin
self.Centre.X := abs;
Self.Centre.Y := ord;
end;


procedure ClasseArc.ProcedureSetRayon(r:real);
begin
Self.Rayon := r;
end;


procedure ClasseArc.ProcedureSetAngleDepart(ang:real);
begin
Self.AngleDepart := ang;
end;


procedure ClasseArc.ProcedureSetAngleArrive(ang:real);
begin
Self.AngleArrive := ang;
end;



procedure ClasseArc.ProcedureSetCouleur(color : string);
begin
Self.Couleur := color;
end;


function ClasseArc.functionGetRayon:real;
begin
Result := Self.Rayon;
end;



function ClasseArc.functionGetCouleur:string;
begin
Result := Self.Couleur;
end;


Function ClasseArc.FunctionSetPointAngle1(Centre : Tpoint;rayon :real) : Tpoint;
// X1,Y1 de CANVAS.arc
var
PointAngle1 : Tpoint;


begin
PointAngle1.X:=Centre.X-rayon;
PointAngle1.Y:=Centre.Y-rayon;


result:=PointAngle1;
end;

Function ClasseArc.FunctionSetPointAngle2(Centre : Tpoint;rayon :real) : Tpoint;
// X2,Y2 de CANVAS.arc
var
PointAngle2 : Tpoint;


begin
PointAngle2.X:=Centre.X+rayon;
PointAngle2.Y:=Centre.Y+rayon;


result:=PointAngle2;
end;


Function ClasseArc.FunctionTransformeAnglePoint(Centre : Tpoint;rayon,angleParam :real):Tpoint;
// Cette fonction va permettre de transformer mes angles dep et arrivee en points pour formater le tout
// au format canvas.arc => parmettre X3,Y3,X4,Y4
var
PointGenere : Tpoint;
angle : real;
begin
angle := DegToRad(angleParam);
if angle=0 then
begin
PointGenere .X:=Centre.X+rayon;
PointGenere .Y:=Centre.Y;
end
else
begin
if (angle>0) and (angle<(Pi/2)) then
begin
PointGenere.X:=Centre.X+abs(cos(angle))*rayon;
PointGenere.Y:=Centre.Y-abs(sin(angle))*rayon;
end
else
begin
if angle=Pi/2 then
begin
PointGenere.X:=Centre.X;
PointGenere.Y:=Centre.Y-rayon;
end
else
begin
if (angle>(Pi/2)) and (angle(Pi)) and (angle<(3*Pi/2)) then
begin
PointGenere.X:=Centre.X-abs(cos(angle-Pi))*rayon;
PointGenere.Y:=Centre.Y+abs(sin(angle-Pi))*rayon;
end
else
begin
if angle = (3*Pi/2) then
begin
PointGenere.X:=Centre.X;
PointGenere.Y:=Centre.Y+rayon;
end
else
begin
if (angle>(3*Pi/2)) and (angle<(2*Pi)) then
begin
PointGenere.X:=Centre.X+abs(cos(2*Pi-angle))*rayon;
PointGenere.Y:=Centre.Y+abs(sin(2*Pi-angle))*rayon;
end
end;
end;
end;
end;
end;
end;
end;


result := PointGenere;


end;



procedure ClasseArc.ProcedureDessineToi(image1:timage;header:ClasseHeader);
var
//Angle haut Gauche
X : Tpoint;
//Angle bas droite
Y : Tpoint;
//Point de depart de l arc sur le cercle
AngleDep : Tpoint;
//Point d'arrivee de l arc sur le cercle
AngleArr : Tpoint;


begin
X := FunctionSetPointAngle1(self.Centre,self.Rayon);
Y := FunctionSetPointAngle2(Self.Centre,Self.Rayon);
AngleDep := FunctionTransformeAnglePoint(Self.Centre,Self.Rayon,self.AngleDepart);
AngleArr := FunctionTransformeAnglePoint(Self.Centre,Self.Rayon,self.AngleArrive);
image1.Canvas.Pen.Color:=clRed;
image1.Canvas.Arc(round(X.X/ header.Vx),round(image1.Height - X.Y/ header.Vx),round(Y.X/ header.Vx),round(image1.Height - Y.Y/ header.Vx),round(AngleDep.X/ header.Vx),round(image1.Height - AngleDep.Y/ header.Vx),round(AngleArr.X/ header.Vx),round(image1.Height - AngleArr.Y/ header.Vx));
end;









end.

2 réponses

f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
25 nov. 2005 à 23:02
oula... ça c'est de la mise en forme ...



bon alors ...



deja pour TPoint, c'est un type existant dans delphi, donc renomage en TRealPoint

pour le noms de tes variables pareil, Abs et Ord sont des noms de fonction donc ... eviter de les utiliser donc...



ensuite pour les variables en private prefere la creation de property plutot que des GetMachin a tout vas...

dans published tu mets simplement :



published

property Identificateur : type read VariablePrivate write VariablePrivate ou Methode;



exemple dans ton cas :

private

pvRayon : single;

pvAngleDepart : single;

pvColor : single;

published

property Rayon : single Read pvRayon Write pvRayon;

property Color : string Read pvColor Write pvColor;

property AngleDepart : single Read pvAngleDepart Write pvAngleDepart;

end;



etc...



- inutile de travailler en Real (10 octets), Single (4 octets) serat bien suffisant pour ce genre de chose.

- evite les cascade de IF ELSE ... c'est lourd et pas trés lisible mais ça tu as surrement du le remarquer...

- pour les retours de fonction, pas la peine de créer une variable exprée ... tu peut ecrire directement dans Result

- pour les noms de tes procedures ou fonction, fait cours ... mettre
FunctionBlablabla ça sert a rien et surtout ça facilite en rien leur
utilisation ni les retenir...



et dernier conseil pratique, dans la declaration des tes variables, dans tes procedures ou fonctions ou autre,

tu peux "grouper" les variables de meme types donc :

plutot que :

X : TPoint;

Y : TPoint;



ect...

fait :



X,Y : TPoint;



ce seras plus rapide et moins lourd.



sinon j'ai optimiser rapidement ta fonction FunctionTransformationAnglePoint (que tu pourrais appeler AngleToRealPoint)



interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, Menus, StdCtrls, ExtCtrls, Cpoint, CCercle, CHeader, Math;



type

TRealPoint = record

X,Y : Single;

end;



TClasseArc = class(TObject)

private

pvAngleDepart : single;

pvAngleArrive : single;

pvRayon : single;

pvCentre : TRealPoint;

pvCouleur : string;

pvTypeObjet : string;



public

constructor Create;



published

procedure DessineToi(var image1: timage; const header:ClasseHeader);



Function SetPointAngle1 : TRealPoint;

Function SetPointAngle2 : TRealPoint;

Function AngleToRealPoint(angleParam: single) : TRealPoint;



property AngleDepart : Single Read pvAngleDepart Write pvAngleDepart;

property AngleArrive : Single Read pvAngleArrive Write pvAngleArrive;

property
Rayon :
Single Read
pvRayon Write pvRayon;

property Centre
: TRealPoint Read pvCentre Write pvCentre;

property Couleur :
String Read pvCouleur
Write pvCouleur;

property TypeObject : String Read pvTypeObjet;

end;



function ARange(X, XMin, XMax: single) : boolean;



procedure ClasseArcFastCreate( var ClasseArc : TClasseArc;


AngleDepart,AngleArrive,Rayon : single;


const Centre : TRealPoint; const Couleur : string);



implementation



function ARange(X, XMin, XMax: single) : boolean;

begin

if (X >= XMin) and (X < XMax) then

result := true

else

result := false;

end;



procedure ClasseArcFastCreate( var ClasseArc : TClasseArc;


AngleDepart, AngleArrive, Rayon : single;


const Centre : TRealPoint; const Couleur : string);

begin

ClasseArc := TClasseArc.Create;

ClasseArc.AngleDepart := AngleDepart;

ClasseArc.AngleArrive := AngleArrive;

ClasseArc.Rayon := Rayon;

ClasseArc.Centre := Centre;

ClasseArc.Couleur := Couleur;

end;



constructor TClasseArc.Create;

begin

inherited;

pvTypeObjet := 'TClasseArc';

pvAngleDepart := 0;

pvAngleArrive := 0;

pvRayon := 0;

pvCentre.X := 0;

pvCentre.Y := 0;

pvCouleur := 'bleu';

end;





Function TClasseArc.SetPointAngle1 : TRealPoint;

begin

result.X := Centre.X - rayon;

result.Y := Centre.Y - rayon;

end;



Function TClasseArc.SetPointAngle2 : TRealPoint;

begin

Result.X := Centre.X + rayon;

Result.Y := Centre.Y + rayon;

end;



Function TClasseArc.AngleToRealPoint(angleParam : single) : TRealPoint;

var angle : single;

begin

angle := angleParam * (Pi / 180) ;



if ARange(angle, 0, Pi/2) then begin

if angle = 0 then begin

Result.X := Centre.X + rayon;

Result.Y := Centre.Y;

end else begin

Result.X := Centre.X + abs(cos(angle)) * rayon;

Result.Y := Centre.Y - abs(sin(angle)) * rayon;

end;

end else

if ARange(angle, Pi/2, Pi) then begin

if angle = Pi/2 then begin

Result.X := Centre.X;

Result.Y := Centre.Y - rayon;

end else begin

Result.X := Centre.X - abs(cos(Pi - angle)) * rayon;

Result.Y := Centre.Y - abs(sin(Pi - angle)) * rayon;

end;

end else

if ARange(angle, Pi, 3*(Pi/2)) then begin

if angle = Pi then begin

Result.X := Centre.X - rayon;

Result.Y := Centre.Y;

end else begin

Result.X := Centre.X - abs(cos(angle - Pi)) * rayon;

Result.Y := Centre.Y + abs(sin(angle - Pi)) * rayon;

end;

end else

if ARange(angle, 3*(Pi/2), 2*Pi) then begin

if angle = 3*(Pi/2) then begin

Result.X := Centre.X;

Result.Y := Centre.Y + rayon;

end else begin

Result.X := Centre.X + abs(cos((2 * Pi) - angle)) * rayon;

Result.Y := Centre.Y + abs(sin((2 * Pi) - angle)) * rayon;

end;

end;

end;



procedure TClasseArc.DessineToi(var image1:timage; const header: ClasseHeader);

var

X, Y, AngleDep, AngleArr : TRealpoint;

begin

X := SetPointAngle1;

Y := SetPointAngle2;

AngleDep := AngletoRealPoint(AngleDepart);

AngleArr := AngleToRealPoint(AngleArrive);

with Image1 do begin

Canvas.Pen.Color:=clRed;

Canvas.Arc( round( X.X / header.Vx ),


round( Height - X.Y / header.Vx ),


round( Y.X / header.Vx ),


round( Height - Y.Y / header.Vx ),


round( AngleDep.X / header.Vx ),


round( Height - AngleDep.Y / header.Vx ),


round( AngleArr.X / header.Vx ),


round( Height - AngleArr.Y / header.Vx ));

end;

end;

end.




par contre en optimisans ta source j'ai remarquer que dans DessineToi tu divise toujours par Header.Vx ... meme les Y...

je dis ça mais bon ... moi ça me semble toujours etrange quand on a un X dans un formule Y et inversement.
0
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
25 nov. 2005 à 23:06
SelfQuote " sinon j'ai optimiser rapidement ta fonction FunctionTransformationAnglePoint (que tu pourrais appeler AngleToRealPoint) "



je me surprend moi meme a affirmé autant de connerie vus que c'est la source en entier que j'ai refait ... ^^



aller zou au dodo.
0
Rejoignez-nous