CERCLE3POINTS

japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 - 12 janv. 2007 à 16:34
John Dogget Messages postés 384 Date d'inscription vendredi 18 juin 2004 Statut Membre Dernière intervention 7 mai 2009 - 16 janv. 2007 à 13:49
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/41080-cercle3points

John Dogget Messages postés 384 Date d'inscription vendredi 18 juin 2004 Statut Membre Dernière intervention 7 mai 2009
16 janv. 2007 à 13:49
Bon j'ai fini mon code :D (cf message plus haut)
Je rajoute des commentaires à mes sources et je poste tout ça dés que possible
Francky23012301 Messages postés 400 Date d'inscription samedi 6 août 2005 Statut Membre Dernière intervention 11 février 2016 1
16 janv. 2007 à 13:46
Bon je vais mettre de l'ordre :

On appelle médiatrice la droite qui coupe perpendiculairement un segment en son milieu : Debiars avec donc raison.

Moi j'aurais procédé autrement : j'aurais fais de l'analyse
L'équation d'une droite est (Xi-Xc)²+(Yi-Yc)²=R² avec C(Xc,Yc) le centre, i(Xi,Yi) un point du cercle et R le rayon. Ayant 3 inconnues Xc,Yc, et R il faut 3 équations donc 3 points (ce qui justifie les 3 points et pourquoi pas deux ou quatre ou ...). Coté chiant il faut résoudre le système : avantage
-Pas d'exceptions
-Rapidité coté execution

Monsieur Debiars : je pensais que tu faisais que des jeux. Mais là aussi tu excelles. Propre, net sans bavure. Bravo
cs_abdousoft Messages postés 100 Date d'inscription mardi 3 août 2004 Statut Membre Dernière intervention 5 novembre 2007
16 janv. 2007 à 09:26
salut

Ah pardent Mensieur Debiars

Merci bien@+
Debiars Messages postés 285 Date d'inscription lundi 16 juin 2003 Statut Membre Dernière intervention 11 février 2018
15 janv. 2007 à 10:31
Delphiprog : Tant que je me souviens du prénom de Mr Alzheimer, y a pas de problèmes.

Abdousoft : Non, mon gars, je ne suis pas Gary Darby, que je n'ai pas le plaisir de connaître. Faut-il le regretter ?
cs_abdousoft Messages postés 100 Date d'inscription mardi 3 août 2004 Statut Membre Dernière intervention 5 novembre 2007
15 janv. 2007 à 09:54
salut mr Debiars

est que vous etes Gary Darby l'administrateur du www.DelphiForFun.org?

Merci!
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
14 janv. 2007 à 22:10
Intéressant tout cela.
Mais il nous faut réviser nos notions de mathématiques un peu oubliées depuis belle lurette et le vocabulaire qui va bien avec :
http://fr.wikipedia.org/wiki/Triangle#M.C3.A9dianes_et_centre_de_gravit.C3.A9

Après cette saine lecture, le centre de gravité, l'isobarycentre et les médianes d'un triangle n'auront plus de secrets pour vous :p

Il ne restera plus "qu'à" mettre en oeuvre et tracer le magnifique cercle inscrit.

En tous cas bravo à Debiars, toujours aussi en forme au plan intellectuel.
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
14 janv. 2007 à 20:33
Non, je ne connaissais pas l'anecdote, merci de me l'avoir fait découvrir.
Très intéressant en effet.

Voici un lien qui explique bien :
http://orochoir.club.fr/Maths/napoleon.htm

La programmation mène décidément à tout, et tout nous y ramène, lol...
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
14 janv. 2007 à 18:45
tu connais pas Napoléon qui trouve le centre du cercle ?
tout çà, c'est parce que tu es resté en D4 !
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
14 janv. 2007 à 18:39
Ah oui, Cantador ?
Pour décrypter ce que tu nous dis là, faudrait au moins être Champollion (clin d'oeil à l'auteur qui comprendra...)
Moi, le seul point commun que ça m'évoque, c'est la Bérézina (à cause de l'eau, ça coule de source, lol)... ^^
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
14 janv. 2007 à 17:28
Ce source me rappelle une anecdote napoléonienne..
John Dogget Messages postés 384 Date d'inscription vendredi 18 juin 2004 Statut Membre Dernière intervention 7 mai 2009
13 janv. 2007 à 15:30
Ouarf, je melange tout !!

Pour ma méthode, c'est plus un exercice de style qu'autre chose ...

En gros :
- je calcul les equations des droites passant par P1 et P2, puis P2 et P3
- je calcul les equations des droites passant perpandiculairement par le mileu de [P1,P2] et [P2,P3] (donc les bissectrices ou mediatrice ou je les droites dontjemerappelpluslenom :D)
- je calcul le point d'intersection de ces droites (=centre du cercle)

J'ai pas dis que c'etais mieux ni plus simple que ta méthode, c'est juste différent ;)
Debiars Messages postés 285 Date d'inscription lundi 16 juin 2003 Statut Membre Dernière intervention 11 février 2018
13 janv. 2007 à 15:19
Correctif : la médiatrice n'a rien à voir avec les angles.

D'après le dico : Perpendiculaire élevée sur le milieu d'un segment de droite.

Exactement ce que je disais, ma p'tite souris...

Et mon vieux bouquin de géométrie (1948) confirme :

La médiatrice d'un segment AB est la perpendiculaire menée à ce segment en son milieu.

Si l'on considère que les 3 points sont les sommets d'un triangle, il constate que :

Les médiatrices des trois côtés d'un triangle sont concourantes.

et il remarque que le point de concourence est le centre du cercle circonscrit au triangle ABC, CQFD.

Mais tout ça ne nous explique pas la méthode de calcul.
John Dogget Messages postés 384 Date d'inscription vendredi 18 juin 2004 Statut Membre Dernière intervention 7 mai 2009
13 janv. 2007 à 13:05
Exact !
La mediatrice c'est pour les angles :p

Merci de m'avoir corrigé ;)
@ john dogget: c'est pas plutôt une médiatrice la droite dont tu parles ???

Sinon oui, le reste de la démonstration est correcte mais gare aux détails de vocabulaire !
John Dogget Messages postés 384 Date d'inscription vendredi 18 juin 2004 Statut Membre Dernière intervention 7 mai 2009
13 janv. 2007 à 12:33
Là je bosse sur une version qui utiliserait les vecteurs pour calculer le centre du cercle, mais c'est pas évident car il faut utiliser des fonction littérale (genre ax+by+c ...).

Je vous tiens au courant ;)
John Dogget Messages postés 384 Date d'inscription vendredi 18 juin 2004 Statut Membre Dernière intervention 7 mai 2009
13 janv. 2007 à 11:30
"Tu relie P1 à P2 par un segment de droite.
Idem pour P2 et P3.
Du milieu de ces droites tu traces une perpendiculaire.
L'intersection de ces perpendiculaires te donne le centre du cercle, y'a plus qu'à démontrer..."

Fastoche :)
D'abord, c'est pas vraiment une perpandiculaire, c'est une bissectrice, c'est à dire que la droite coupe le segment en son milieu, et perpandiculairement à ce segment (ça tu l'avais déjà dit ;) ).

On sait que tous point situé sur la bissectrice d'un segment se trouve à égale distance de ces extremité.

Donc les points de la 1° bissectrice sont equidistants de P1 et P2, ceux de la deuxième de P2 et P3.

=> le point d'intersection des bissectrices est équidistant de P1,P2,P3, donc c'est le centre du chercle :D
DRJEROME Messages postés 436 Date d'inscription jeudi 9 janvier 2003 Statut Membre Dernière intervention 5 février 2015
13 janv. 2007 à 10:17
le seul truc c'est que mon code coince avec ta logique des points superposés (j'ai la flemme de corriger hi! hi!)
DRJEROME Messages postés 436 Date d'inscription jeudi 9 janvier 2003 Statut Membre Dernière intervention 5 février 2015
13 janv. 2007 à 09:59
Pour simuler une ligne :
___________________________________________
procedure TForm1.Button1Click(Sender: TObject);
begin
// simulation ligne oblique
BPoint.Click;
PageMouseUp(page, mbLeft,[], 10,10);
PageMouseUp(page, mbLeft,[], 20,20);
PageMouseUp(page, mbLeft,[], 40,40);
BTrace.Click;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
// simulation ligne verticale
BPoint.Click;
PageMouseUp(page, mbLeft,[], 10,10);
PageMouseUp(page, mbLeft,[], 10,20);
PageMouseUp(page, mbLeft,[], 10,40);
BTrace.Click;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
// simulation ligne horizontale
BPoint.Click;
PageMouseUp(page, mbLeft,[], 10,10);
PageMouseUp(page, mbLeft,[], 20,10);
PageMouseUp(page, mbLeft,[], 40,10);
BTrace.Click;
end;
___________________________________________
DRJEROME Messages postés 436 Date d'inscription jeudi 9 janvier 2003 Statut Membre Dernière intervention 5 février 2015
13 janv. 2007 à 09:54
tu as oublié l'exception des points alignés verticalement à un moment donné

j'ai corrigé. Sinon comme les points alignés donnent des cercles de rayon infini, je l'ai rajouté :

_______________________________________
var
x1,y1,x2,y2,x3,y3 : extended;
np : byte;
ma,mb : extended;

procedure TForm1.BPointClick(Sender: TObject);
begin
np := 0;
Page.Canvas.Pen.Color := clBlue;
Page.Canvas.Pen.Width := 1;
page.Canvas.Brush.Color := clBlue;
Page.Canvas.Brush.Style := bsSolid;
end;

procedure TForm1.PageMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var rs : extended;
begin
inc(np);
if np > 3 then exit;
case np of
1 : begin
x1 := X;
y1 := Y;
end;
2 : begin
x2 := X;
y2 := Y;
end;
3 : begin
x3 := X;
y3 := Y;
end;
end;
Page.Canvas.Ellipse(X-2,Y-2,X+2,Y+2);
Page.Repaint;
if np < 3 then exit;

// Si la ligne entre 2 points est verticale, on provoque une division par zéro
if x1 = x2 then
begin
rs := x2;
x2 := x3;
x3 := rs;
rs := y2;
y2 := y3;
y3 := rs;
end;
if x2 = x3 then
begin
rs := x1;
x1 := x3;
x3 := rs;
rs := y1;
y1 := y3;
y3 := rs;
end;

if x2-x1<>0 then//tu avait oublié l'exception des points alignés verticalement
begin
ma := (y2-y1)/(x2-x1);
mb := (y3-y2)/(x3-x2);
end;

if (mb-ma = 0) or (x2-x1=0) then
begin
np := 4;
end;
end;

procedure TForm1.BTraceClick(Sender: TObject);
var i,cX,cY,rayon,pi2,pas,A,B : extended;
nx,ny,k: integer;
begin
if np < 3 then exit;
case np of
3:
begin
// calcul de la position X du centre
cX := Round(((ma*mb*(y1-y3))+(mb*(x1+x2))-(ma*(x2+x3)))/(2*(mb-ma)));

// calcul de la position Y du centre
cY := Round((-1.0/ma)*(cX-(x1+x2)/2.0)+((y1+y2)/2.0));
Page.Canvas.Ellipse(Round(cX-2),Round(cY-2),Round(cX+2),Round(cY+2));
Page.Repaint;
Page.Canvas.Brush.Style := bsClear;

// calcul du rayon
rayon := Sqrt(Sqr(cX-x1)+ Sqr(cY-y1));

Page.Canvas.Pen.Color := clRed;
Page.Canvas.Pen.Width := 2;

// tracé version 1
nx := Round(cX-rayon);
ny := Round(cY-rayon);
Page.Canvas.Ellipse(nx,ny,Round(cX+rayon),Round(cY+rayon));
end;
4:{cas des droites}
Begin
A:=1;//c'est juste une initialisation pour que "A" soit différent de "0"
Page.Canvas.Pen.Color := clRed;
Page.Canvas.Pen.Width := 2;
ShowMessage('3 points alignés donnent un cercle de rayon infini (càd une droite)');
{équation droite : Y=AX+B}
if X1-X2<>0 then
begin
A:=(Y1-Y2) / (X1-X2);
B:=Y1-A*X1;
end;

if (A<>0) and (X1-X2<>0) then
begin//si ligne oblique
for k:=0 to page.Width do
begin
Y1:=round(A*k+B);
if k=0 then Page.Canvas.MoveTo(0,round(Y1))
else Page.Canvas.LineTo(k,round(Y1));

end;

end
else//si points alignés vertical ou horizontal
begin
if (A=0) then //points alignés à l'horizontale
begin
Page.canvas.MoveTo(0,round(Y1));
Page.Canvas.LineTo(Page.Width,round(Y1));
end;
if X1-X2=0 then //points alignés à la verticale
begin
Page.canvas.MoveTo(round(X1),0);
Page.Canvas.LineTo(round(X1),Page.Height);
end;
end;
end;
end;
end;
end.
_______________________________________


Je n'ai pas optimisé c'est juste pour le fun...Et j'ai peut-être laissé ou créé des erreurs
Il manquera encore le cas ou les 3 points sont les mêmes (je ne l'ai pas fait... la flemme)
Debiars Messages postés 285 Date d'inscription lundi 16 juin 2003 Statut Membre Dernière intervention 11 février 2018
13 janv. 2007 à 09:43
En D7 pas de spasme oculaire, en D2, j'ai pas essayé.

Florenth : Le calcul de la position du centre, j'aurais du mal à te l'expliquer vu que mes cours de trigonométrie remonte à... + de 55 ans...

Néanmoins, le tracé sur papier ça donne ceci :

Tu relie P1 à P2 par un segment de droite.
Idem pour P2 et P3.
Du milieu de ces droites tu traces une perpendiculaire.
L'intersection de ces perpendiculaires te donne le centre du cercle, y'a plus qu'à démontrer...

'scuse, je suis plus dessineux que matheux :-)

Bon début pour 2007
DRJEROME Messages postés 436 Date d'inscription jeudi 9 janvier 2003 Statut Membre Dernière intervention 5 février 2015
13 janv. 2007 à 07:52
salut,

mmmmh!.... le clignotement est peut-être dû à un spasme de la paupière...

(hi! hi)

je plaisante
Source intéréssante, la partie calculant la position du centre aurait peut être due être expliquée un peu plus (pas facile de comprendre "brut") mais rien de sorcier à retrouver.

C'est intéréssant de montrer une autre technique de dessin, en revenant aux fondements avec les sinus et cosinus. A cela je n'aurais qu'un mot: "SinCos() est deux fois plus rapide que Sin() suivi de Cos() pour le même angle". De plus, vu la précision du calcul, il aurait largement été possible d'utiliser Double (voire Single) comme type de flottant au lieu de Extended, plus lent.

En tout cas, c'est un bon code. Ma seule suggestion serait de transformer tout cela en une procédure qui prendrait trois TPoint et qui renvorait par exemple le TRect à transmettre à Canvas.Ellipse() ou bien un TPoint représentant le centre et un flottant réprésentant le rayon.

procedure CircleFromThreePoints(const P1, P2, P3: TPoint; out Center: TPoint; out Radius: Extended);

et

function CircleRectFromThreePoints(const P1, P2, P3: TPoint): TRect;

La fonction se servant bien sûr de la procédure pour ne pas dupliquer inutilement du code.

@japee: je n'ai rencontré aucun scintillement pour ma part sous TurboDelphi. Par contre, sous D6, il y en a, étrange ...
Borland aurait-il changé un truc au niveau de l'affichage des canvas ??

Pour info: 415 Ko compilé sous D6, 412 Ko sous TD ! Ouf, la taille redescend !
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
12 janv. 2007 à 16:56
[astuce spécial débutants]
Pour ceux qui veulent des parties gratuites, il faut rajouter un bouton :

procedure TForm1.btnClearClick(Sender: TObject);
begin
Image.Picture.Bitmap := nil;
//np := 0; { ou alors...}
btnPointsClick(nil);
end;
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
12 janv. 2007 à 16:34
Salut Debiars,

J'adore ce genre de petit code intéressant, amusant et rapide à tester.
J'ai constaté une bizarrerie, non pas dans le code lui-même, mais en voici l'exposé :
- code compilé directement sous D6, des clignotements sont perceptibles au moment où l'on place les points, ainsi qu'au moment où l'on trace le cercle ;
- code recopié sans rien changer, puis compilé sous D4, plus de clignotements...
Curieux, non ?

\o/ Bonne année à toi ! \o/ ;-)

japee
Rejoignez-nous