Voila un petit programme qui permet de montrer
la repartition de complexes dans le cercle unite selon deux methodes.
La seconde etant celle qui permet une repartition uniforme,
celle qui peut etre utile dans certains algorihtmes.
La premiere est une "mauvaise" repatition car il y a une forte
densite de complexes autour de 0.
On part du principe que l'on a un generateur de nombres aleatoires
flottants entre deux valeurs. Le premiere methode represente le
premier algorithme qui vient a l'esprit : uniforme pour l'angle
et uniforme pour le rayon (du complexe considere). celle-ci etant
evidemment erronee car elle ne tient pas compte tu fais que plus
le rayon augmente, plus la surface balayee est grande (aire~rayon²).
La vraie methode consiste a prendre l'angle uniformement, mais a
prendre pour rayon le maximum de deux uniformes, ce qui compensera
le phenomene explique ci-dessus. Pour se laisser s'en convaicre,
executer le programme ...
Source / Exemple :
#ifndef _UTIL_H_
#include "util.h"
#endif // _UTIL_H_
#ifndef _MATH_H_
#include "math.h"
#endif // _MATH_H_
#ifndef _LIST_H_
#include "list.h"
#endif // _LIST_H_
#ifndef _WINUTIL_H_
#include "winutil.h"
#endif // _WINUTIL_H_
//-------------------------------------------------
#define FUNC_RATIO myMinAspectRatio
#define MSG_USER_NEW_RANDOM 1000
#define NB_ITERATION 10000
#define NB_DIVISION_R 4
#define NB_DIVISION_ANGLE 8
//-------------------------------------------------
// WND_PROC
//-------------------------------------------------
int WndProc(P_MY_WINDOW myWindow,HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
{
static MY_GRAPH graph1,graph2;
static P_MY_HDC hdcMem,hdcParent;
switch(iMsg)
{
// creation de la fentre
case WM_CREATE:
{
RECT rcWindow;
RECTD rcView;
double frame;
myWindow->bResizedWindow = FALSE;
myWindow->bUseBackBuffer = FALSE;
myWindow->colorBackGround = COLOR_BACK_GROUND_NO_ERASE;
hdcParent = myCreateDCIndirect(hwnd,FALSE);
hdcMem = myCreateDC(GetHdc(hdcParent),TRUE);
GetClientRect(hwnd,&rcWindow);
myPushBitmap(hdcMem,hdcParent,myWidthRect(&rcWindow),myHeightRect(&rcWindow));
myDeleteDCIndirect(hdcParent);
frame = 0.1;
mySetWindowGraph(&graph1,&rcWindow);
rcView.left = -1. - frame;
rcView.top = +1. + frame;
rcView.right = +3. + 3*frame;
rcView.bottom = -1. - frame;
mySetViewGraph(&graph1,&rcView,FUNC_RATIO,NULL);
mySetWindowGraph(&graph2,&rcWindow);
rcView.left = -3. - 3*frame;
rcView.top = +1. + frame;
rcView.right = +1. + frame;
rcView.bottom = -1. - frame;
mySetViewGraph(&graph2,&rcView,FUNC_RATIO,NULL);
SendMessage(hwnd,WM_USER,MSG_USER_NEW_RANDOM,IRRELEVANT);
break;
}
// changement de la taille
case WM_SIZE:
{
RECT rcWindow;
GetClientRect(hwnd,&rcWindow);
mySetWindowGraph(&graph1,&rcWindow);
mySetViewGraph(&graph1,NULL,FUNC_RATIO,NULL);
mySetWindowGraph(&graph2,&rcWindow);
mySetViewGraph(&graph2,NULL,FUNC_RATIO,NULL);
break;
}
// bouton gauche de la souris
case WM_LBUTTONDOWN:
{
SendMessage(hwnd,WM_USER,MSG_USER_NEW_RANDOM,IRRELEVANT);
myRepaintWindow(hwnd);
break;
}
// bouton droit de la souris
// les touches
case WM_KEYDOWN:
{
switch((int)wParam)
{
default:
break;
}
break;
}
// messages utilisateurs
case WM_USER:
{
switch(LOWORD(wParam))
{
case MSG_USER_NEW_RANDOM:
{
int i;
RECT rc;
int iMax,width;
// on efface le fond par du blanc
myPushBrush(hdcMem,BS_SOLID,RGB_WHITE,IRRELEVANT);
GetClientRect(hwnd,&rc);
myFillRect(hdcMem,&rc);
myPopBrush(hdcMem);
width = 2;
iMax = NB_ITERATION;
// methode du <graph1> :
// module : uniforme entre 0 et 1
// argument : uniforme entre 0 et 2.pi
myPushPen(hdcMem,PS_SOLID,width,RGB_RED);
for(i=0;i<iMax;i++)
{
double r,t,x,y;
r = RandomDouble(0.,1.);
t = RandomDouble(0.,2.*MATH_PI);
x = r*cos(t);
y = r*sin(t);
myDrawPointGraph(hdcMem,&graph1,x,y);
}
myPopPen(hdcMem);
SetBkColor(GetHdc(hdcMem),RGB_YELLOW);
// methode du <graph2> :
// module : maximum etre deux uniformes entre 0 et 1
// argument : uniforme entre 0 et 2.pi
myPushPen(hdcMem,PS_SOLID,width,RGB_BLUE);
for(i=0;i<iMax;i++)
{
double r,r1,r2,t,x,y;
r1 = RandomDouble(0.,1.);
r2 = RandomDouble(0.,1.);
r = max(r1,r2);
t = RandomDouble(0.,2.*MATH_PI);
x = r*cos(t);
y = r*sin(t);
myDrawPointGraph(hdcMem,&graph2,x,y);
}
myPopPen(hdcMem);
// les petits commetaires
{
int cx,cy;
cx = -8;
cy = -20;
myDrawTextGraph(hdcMem,&graph1,"Courrier New",700,cx,cy,0.,0.5,1.,1.," complexes centrés ");
myDrawTextGraph(hdcMem,&graph2,"Courrier New",700,cx,cy,0.,0.5,1.,1.," complexes uniformément répartis ");
myDrawTextGraph(hdcMem,&graph1,"Courrier New",700,cx,cy,0.,0.5,-1.,0.," [r=Uniform(0,1),t=Uniform(0,2.Pi)] ");
myDrawTextGraph(hdcMem,&graph2,"Courrier New",700,cx,cy,0.,0.5,-1.,0.," [r=Max(Uniform(0,1),Uniform(0,1)),t=Uniform(0,2.Pi)] ");
}
break;
}
}
break;
}
// le commandes
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
}
break;
}
// on dessine
case WM_PAINT:
{
P_MY_HDC hdc;
int cx,cy;
RECT rc;
cx = LOWORD(lParam);
cy = HIWORD(lParam);
hdc = (P_MY_HDC)wParam;
// on dessine les points
GetClientRect(hwnd,&rc);
myStretchBlt(hdc,&rc,hdcMem,&rc,SRCCOPY);
// on dessine les axes et le cercle
myPushBrush(hdc,BS_NULL,IRRELEVANT,IRRELEVANT);
myPushPen(hdc,PS_SOLID,0,RGB_DARKGRAY);
{
RECTD rcCircle;
double r,dr;
double t,dt;
// axes
dt = 2.*MATH_PI/NB_DIVISION_ANGLE;
for(t=0.;t<MATH_PI;t+=dt)
{
myDrawLineGraph(hdc,&graph1,cos(t),sin(t),-cos(t),-sin(t));
myDrawLineGraph(hdc,&graph2,cos(t),sin(t),-cos(t),-sin(t));
}
// le cercle
myPushPen(hdc,PS_SOLID,0,RGB_BLACK);
r = 1.;
mySetRectd(&rcCircle,-r,r,r,-r);
myDrawEllipseGraph(hdc,&graph1,&rcCircle);
myDrawEllipseGraph(hdc,&graph2,&rcCircle);
myPopPen(hdc);
dr = 1./NB_DIVISION_R;
for(r=dr;r<1.;r+=dr)
{
mySetRectd(&rcCircle,-r,r,r,-r);
myDrawEllipseGraph(hdc,&graph1,&rcCircle);
myDrawEllipseGraph(hdc,&graph2,&rcCircle);
}
}
myPopPen(hdc);
myPopBrush(hdc);
break;
}
// destruction de la fenetre
case WM_DESTROY:
{
myPopBitmap(hdcMem);
myDeleteDC(hdcMem);
PostQuitMessage(0);
break;
}
}
return 0;
} // WndProc()
//-------------------------------------------------
// WINMAIN
//-------------------------------------------------
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,
int iCmdShow
)
{
InitializationLibUtil();
InitializationLibWinutil(hInstance);
{
HWND hwnd;
WNDCLASSEX wc;
RECT rc;
mySetDefaultWindowClass(&wc,hInstance);
wc.lpszClassName = "JCD_alea";
mySetRectWH(&rc,0,0,1000,500);
hwnd = myCreateWindow(&wc,
"Complexes aléatoires dans le cercle unité",
WS_OVERLAPPEDWINDOW,
&rc,
TRUE,
TRUE,
NULL,
NULL,
0,
NULL,
WndProc
);
myRunWindow(hwnd,SW_SHOW);
}
CloseLibUtil();
CloseLibWinutil();
CheckingClosingLibUtil();
CheckingClosingLibWinutil();
return 0 ;
} // WinMain()
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.