begin process at 2012 05 27 19:57:07
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Maths & Algorithmes

 > HYPERCUBE EN 3,4,...,10 DIMENSIONS !!

HYPERCUBE EN 3,4,...,10 DIMENSIONS !!


 Information sur la source

Note :
9,25 / 10 - par 4 personnes
9,25 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Maths & Algorithmes Niveau :Débutant Date de création :26/08/2004 Vu / téléchargé :4 958 / 434

Auteur : JCDjcd

Ecrire un message privé
Ce membre participe au partage de revenus publicitaires
Commentaire sur cette source (13)
Ajouter un commentaire et/ou une note


 Description

Cliquez pour voir la capture en taille normale
Voila un programme marrant qui fait reflechir.
Qu'est ce qu'une hypercube en 4 dimensions ? comment le construire ? et bien pareil que le cube avec des carres (patron d'un cube) ... mais en dimension 4 !

Ce programme montre la projection d'hypercube sur le plan-ecran de votre ordinateur.
Pour avoir des informations sur les hypercubes cliquer avec la souris sur la fenetre (sur le blanc ou le noir), mais il faut attendre l'ouverture de la boite de message ( c'est un peu long).

Si vous avez des questions ... n'hesitez pas.

Source

  • #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_
  • //-------------------------------------------------
  • // VERTEX
  • //-------------------------------------------------
  • typedef struct tagVERTEX
  • {
  • DBL_LIST other;
  • P_VECTND p0;
  • P_VECTND p1;
  • COLORREF color;
  • }VERTEX,*P_VERTEX,**PP_VERTEX;
  • //-------------------------------------------------
  • void PushVertex(P_VERTEX first,P_VECTND p0,P_VECTND p1,COLORREF color)
  • {
  • P_VERTEX p;
  • AssertPointer(first);
  • AssertGoodVectND(p0);
  • AssertGoodVectND(p1);
  • p = Malloc(VERTEX,1);
  • p->color = color;
  • p->p0 = p0;
  • p->p1 = p1;
  • InsertItemDblList(&first->other,&p->other);
  • } // PushVertex()
  • //-------------------------------------------------
  • BOOL DrawVertex(P_MY_HDC hdc,P_MY_GRAPH graph,P_VERTEX vertex,P_VECTND u,P_VECTND v)
  • {
  • P_DBL_LIST L;
  • L = &vertex->other;
  • AssertPointer(hdc);
  • AssertPointer(graph);
  • AssertPointer(vertex);
  • AssertGoodVectND(u);
  • AssertGoodVectND(v);
  • while(&vertex->other != (L = GetNextItemDblList(L)))
  • {
  • double x0,y0,x1,y1;
  • P_VERTEX cur;
  • cur = FROM_TO(VERTEX,other,L);
  • x0 = DotProductVectND(u,cur->p0);
  • y0 = DotProductVectND(v,cur->p0);
  • x1 = DotProductVectND(u,cur->p1);
  • y1 = DotProductVectND(v,cur->p1);
  • myPushPen(hdc,PS_SOLID,0,cur->color);
  • MoveToEx(GetHdc(hdc),myConvXFromViewToWindowGraph(graph,x0),myConvYFromViewToWindowGraph(graph,y0),FALSE);
  • LineTo(GetHdc(hdc),myConvXFromViewToWindowGraph(graph,x1),myConvYFromViewToWindowGraph(graph,y1));
  • myPopPen(hdc);
  • }
  • return TRUE;
  • } // DrawVertex()
  • //-------------------------------------------------
  • BOOL PopVertex(P_VERTEX first)
  • {
  • P_DBL_LIST L;
  • L = GetNextItemDblList(&first->other);
  • if(L == &first->other)
  • {
  • return FALSE;
  • }
  • else
  • {
  • BOOL r;
  • P_VERTEX p;
  • p = FROM_TO(VERTEX,other,L);
  • r = RemoveItemDblList(&first->other,L);
  • Free(p->p0);
  • Free(p->p1);
  • Free(p);
  • return r;
  • }
  • } // PopVertex()
  • //-------------------------------------------------
  • // HYPER_CUBE
  • //-------------------------------------------------
  • typedef struct tagHYPER_CUBE
  • {
  • int dim; // dimension de l'hypercube
  • MY_GRAPH graph; // graphique
  • VERTEX vertex; // les lignes formants l'hypercube
  • HRGN region; // region GDI (correspond au <rcWindow> de <graph>
  • P_VECTND u,v; // deux vecteurs formant un plan (ce sont les "yeux")
  • P_VECTND du,dv;
  • }HYPER_CUBE,*P_HYPER_CUBE,**PP_HYPER_CUBE;
  • //-------------------------------------------------
  • void FillVectND(P_VECTND u,double d)
  • {
  • int dim,i;
  • double *p;
  • dim = u->dim;
  • p = u->coord;
  • for(i=0;i<dim;i++)
  • {
  • *p = d;
  • p ++;
  • }
  • } // FillVectND()
  • //-------------------------------------------------
  • void RandomVectND(P_VECTND u,double min,double max)
  • {
  • int dim,i;
  • double *p;
  • dim = u->dim;
  • p = u->coord;
  • for(i=0;i<dim;i++)
  • {
  • *p = RandomDouble(min,max);
  • p ++;
  • }
  • } // RandomVectND()
  • //-------------------------------------------------
  • COLORREF getColor(int n)
  • {
  • static COLORREF tab[] =
  • {
  • RGB(255,0,0),
  • RGB(0,255,0),
  • RGB(0,0,255),
  • RGB(255,255,0),
  • RGB(255,0,255),
  • RGB(0,255,255),
  • RGB(255,125,125),
  • RGB(125,255,125),
  • RGB(125,125,255),
  • RGB(255,255,255)
  • };
  • Assert(n >= 0);
  • if(n >= COUNT(tab))
  • {
  • return RGB_WHITE;
  • }
  • else
  • {
  • return tab[n];
  • }
  • } // getColor()
  • //-------------------------------------------------
  • void BuildHyperCube(P_HYPER_CUBE p)
  • {
  • int dim,nVertex,i;
  • dim = p->dim;
  • nVertex = 1 << (dim - 1);
  • for(i=0;i<dim;i++) // balaye tous les groupes d'aretes paralleles a un1 vecteur de base
  • {
  • int j;
  • for(j=0;j<nVertex;j++) // balaye toutes les aretes paralleles a un vecteur de base
  • {
  • int k,mask;
  • P_VECTND p0,p1; // point de depart et d'arriver de l'arete
  • double *pP0,*pP1;
  • p0 = CreateVectND(dim);
  • p1 = CreateVectND(dim);
  • pP0 = p0->coord;
  • pP1 = p1->coord;
  • mask = 1;
  • for(k=0;k<dim;k++) // initialise l'arete en question
  • {
  • if(k != i)
  • {
  • *pP0 = *pP1 = (j & mask) ? -1. : +1.;
  • mask <<= 1;
  • }
  • else
  • {
  • *pP0 = -1.;
  • *pP1 = +1.;
  • }
  • pP0 ++;
  • pP1 ++;
  • }
  • PushVertex(&p->vertex,p0,p1,getColor(i));
  • }
  • }
  • } // BuildHyperCube()
  • //-------------------------------------------------
  • // re-arrange les vecteurs <u> et <v> de la bonne facon (en changeant <v>)
  • void Ortho(P_VECTND u,P_VECTND v)
  • {
  • double k;
  • k = DotProductVectND(u,v);
  • AddVectND(v,v,u,1.,-k); // on rend les deux vecteurs orthogonaux
  • } // Ortho()
  • //-------------------------------------------------
  • void ValidateUVHyperCube(P_HYPER_CUBE p)
  • {
  • UnitVectND(p->u);
  • Ortho(p->u,p->v);
  • UnitVectND(p->v);
  • } // ValidateUVHyperCube()
  • //-------------------------------------------------
  • #define MAX_DIM 20
  • P_HYPER_CUBE CreateHyperCube(int dim)
  • {
  • P_HYPER_CUBE p;
  • P_VERTEX vertex;
  • Assert(dim >= 2 && dim <= MAX_DIM); // on se limite a MAX_DIM dimensions
  • p = Malloc(HYPER_CUBE,1);
  • p->dim = dim;
  • p->region = myCreateEmptyRegion();
  • p->u = CreateVectND(dim);
  • p->v = CreateVectND(dim);
  • p->du = CreateVectND(dim);
  • p->dv = CreateVectND(dim);
  • InitDblList(&p->vertex.other);
  • vertex = &p->vertex;
  • RandomVectND(p->u,-1.,+1.);
  • SetCoordVectND(p->u,0,1.); // pour s'assuer que le vecteur ne sera pas nul
  • RandomVectND(p->v,-1.,+1.);
  • SetCoordVectND(p->v,1,1.); // pour s'assuer que le vecteur ne sera pas nul
  • ValidateUVHyperCube(p);
  • FillVectND(p->du,0.);
  • FillVectND(p->dv,0.);
  • BuildHyperCube(p);
  • return p;
  • } // CreateHyperCube()
  • //-------------------------------------------------
  • P_HYPER_CUBE ResizeHyperCube(P_HYPER_CUBE p,RECT *pRect)
  • {
  • RECTD rc;
  • double k;
  • AssertPointer(p);
  • AssertPointer(pRect);
  • AssertGDIObject(p->region);
  • DeleteObject(p->region);
  • p->region = myCreateRectRegion(pRect);
  • // longueur de la grande arete d'un hypercube de dimension N : sqrt(N)
  • // pour le carre c'est sqrt(2)
  • // pour le cube c'est sqrt(3)
  • // pour trouver la formule ... utilisez N-1 fois le theoreme de Pythagore
  • k = 1.01*sqrt((double)p->dim); // on rajoute 1% de marge
  • rc.left = -k;
  • rc.top = +k;
  • rc.right = +k;
  • rc.bottom = -k;
  • mySetWindowGraph(&p->graph,pRect);
  • mySetViewGraph(&p->graph,&rc,myMinAspectRatio,NULL);
  • return p;
  • } // ResizeHyperCube()
  • //-------------------------------------------------
  • BOOL DrawHyperCube(P_MY_HDC hdc,P_HYPER_CUBE p)
  • {
  • AssertPointer(p);
  • AssertPointer(hdc);
  • AssertGDIObject(p->region);
  • myPushRegionIndirect(hdc,p->region);
  • DrawVertex(hdc,&p->graph,&p->vertex,p->u,p->v);
  • myPopRegionIndirect(hdc,FALSE);
  • return TRUE;
  • } // DrawHyperCube()
  • //-------------------------------------------------
  • // change l'angle de vu
  • void MoveEyesHyperCube(P_HYPER_CUBE p)
  • {
  • P_VECTND du,dv;
  • int dim;
  • double k,d;
  • AssertPointer(p);
  • dim = p->dim;
  • du = CreateVectND(dim);
  • dv = CreateVectND(dim);
  • RandomVectND(du,-1.,+1.);
  • RandomVectND(dv,-1.,+1.);
  • // coefficient de l'influence du nouveau <du> (ou <dv>)
  • k = 0.05;
  • // longeur du deplacement
  • d = 0.1;
  • //Ortho(p->u,du);
  • //Ortho(p->v,dv);
  • AddVectND(p->du,p->du,du,1.-k,k*d);
  • AddVectND(p->dv,p->dv,dv,1.-k,k*d);
  • AddVectND(p->u,p->u,p->du,1.,1.);
  • AddVectND(p->v,p->v,p->dv,1.,1.);
  • ValidateUVHyperCube(p);
  • Free(du);
  • Free(dv);
  • } // MoveEyesHyperCube()
  • //-------------------------------------------------
  • void DeleteHyperCube(P_HYPER_CUBE p)
  • {
  • AssertPointer(p);
  • AssertGDIObject(p->region);
  • while(PopVertex(&p->vertex));
  • DeleteObject(p->region);
  • Free(p->du);
  • Free(p->dv);
  • Free(p->u);
  • Free(p->v);
  • Free(p);
  • } // DeleteHyperCube()
  • //-------------------------------------------------
  • // WND_PROC
  • //-------------------------------------------------
  • #define ID_MOVE_EYES 1000
  • #define FRAME 20
  • //-------------------------------------------------
  • void Info(HWND hwnd,P_HYPER_CUBE p)
  • {
  • if(NULL == p)
  • {
  • myWarning(hwnd,"Informations sur le programme ...",
  • "HyperCube\r\n"
  • "\r\n"
  • "Un carré c'est en 2 dimensions\r\n"
  • "Un cube c'est en 3 dimensions\r\n"
  • "Un hypercube c'est en N dimensions\r\n"
  • "\r\n"
  • "Cliquez sur les hypercubes pour avoir des informations\r\n"
  • "\r\n"
  • "Programmé par JCDjcd\r\n"
  • );
  • }
  • else
  • {
  • AssertPointer(p);
  • myWarning(hwnd,"Informations sur l'hypercube ...",
  • "HyperCube de dimension %d\r\n"
  • "\r\n"
  • "Nombre de sommets (2^n) : %d\r\n"
  • "Nombre d' arêtes (n.2^(n-1)) : %d\r\n"
  • "\r\n",
  • p->dim,
  • 1 << p->dim,
  • p->dim * (1 << (p->dim - 1))
  • );
  • }
  • } // Info()
  • //-------------------------------------------------
  • int WndProc(P_MY_WINDOW myWindow,HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
  • {
  • static HWND hwndStatusBar;
  • static P_HYPER_CUBE hyperCube1,hyperCube2,hyperCube3,hyperCube4;
  • static RECT rcHyperCube1,rcHyperCube2,rcHyperCube3,rcHyperCube4;
  • switch(iMsg)
  • {
  • case WM_CREATE:
  • {
  • int allWidth[5];
  • // style de fenetre
  • myWindow->bResizedWindow = TRUE;
  • myWindow->bUseBackBuffer = TRUE;
  • myWindow->colorBackGround = RGB_WHITE;
  • // la bar
  • hwndStatusBar = CreateStatusWindow(WS_VISIBLE | WS_CHILD,"",hwnd,100);
  • allWidth[0] = 100;
  • allWidth[1] = 200;
  • allWidth[2] = 300;
  • allWidth[3] = 400;
  • allWidth[4] = -1;
  • SendMessage(hwndStatusBar,SB_SETPARTS,(WPARAM)COUNT(allWidth),(LPARAM)allWidth);
  • SendMessage(hwndStatusBar,SB_SETTEXT,(WPARAM)0,(LPARAM)"\tDimension 3");
  • SendMessage(hwndStatusBar,SB_SETTEXT,(WPARAM)1,(LPARAM)"\tDimension 4");
  • SendMessage(hwndStatusBar,SB_SETTEXT,(WPARAM)2,(LPARAM)"\tDimension 5");
  • SendMessage(hwndStatusBar,SB_SETTEXT,(WPARAM)3,(LPARAM)"\tDimension 10");
  • SendMessage(hwndStatusBar,SB_SETTEXT,(WPARAM)4,(LPARAM)"\tProgrammé par JCDjcd");
  • hyperCube1 = CreateHyperCube(3);
  • hyperCube2 = CreateHyperCube(4);
  • hyperCube3 = CreateHyperCube(5);
  • hyperCube4 = CreateHyperCube(10);
  • SetTimer(hwnd,ID_MOVE_EYES,0,NULL);
  • break;
  • }
  • case WM_SIZE:
  • {
  • int cx,cy,cxRect,cyRect;
  • double dx,dy;
  • RECT rcStatusBar,rc;
  • GetWindowRect(hwndStatusBar,&rcStatusBar);
  • cx = LOWORD(lParam);
  • cy = HIWORD(lParam) - myHeightRect(&rcStatusBar);
  • mySetRectWH(&rc,0,0,cx,cy);
  • cxRect = (cx - 3 * FRAME)/2;
  • cyRect = (cy - 3 * FRAME)/2;
  • dx = (1.+((double)cxRect)/((double)cx))/3.;
  • dy = (1.+((double)cyRect)/((double)cy))/3.;
  • mySetRectWH(&rcHyperCube1,0,0,cxRect,cyRect);
  • mySetRectWH(&rcHyperCube2,0,0,cxRect,cyRect);
  • mySetRectWH(&rcHyperCube3,0,0,cxRect,cyRect);
  • mySetRectWH(&rcHyperCube4,0,0,cxRect,cyRect);
  • myCenterRect(&rcHyperCube1,1.,1.,&rc,1.*dx,1.*dy);
  • myCenterRect(&rcHyperCube2,1.,1.,&rc,2.*dx,1.*dy);
  • myCenterRect(&rcHyperCube3,1.,1.,&rc,1.*dx,2.*dy);
  • myCenterRect(&rcHyperCube4,1.,1.,&rc,2.*dx,2.*dy);
  • ResizeHyperCube(hyperCube1,&rcHyperCube1);
  • ResizeHyperCube(hyperCube2,&rcHyperCube2);
  • ResizeHyperCube(hyperCube3,&rcHyperCube3);
  • ResizeHyperCube(hyperCube4,&rcHyperCube4);
  • SendMessage(hwndStatusBar,iMsg,0,lParam);
  • break;
  • }
  • case WM_TIMER:
  • {
  • switch(LOWORD(wParam))
  • {
  • case ID_MOVE_EYES:
  • {
  • MoveEyesHyperCube(hyperCube1);
  • MoveEyesHyperCube(hyperCube2);
  • MoveEyesHyperCube(hyperCube3);
  • MoveEyesHyperCube(hyperCube4);
  • myRepaintWindow(hwnd);
  • break;
  • }
  • }
  • break;
  • }
  • case WM_LBUTTONDOWN:
  • case WM_RBUTTONDOWN:
  • {
  • POINT pt;
  • pt.x = LOWORD(lParam);
  • pt.y = HIWORD(lParam);
  • if(PtInRect(&rcHyperCube1,pt)) Info(hwnd,hyperCube1);
  • else if(PtInRect(&rcHyperCube2,pt)) Info(hwnd,hyperCube2);
  • else if(PtInRect(&rcHyperCube3,pt)) Info(hwnd,hyperCube3);
  • else if(PtInRect(&rcHyperCube4,pt)) Info(hwnd,hyperCube4);
  • else Info(hwnd,NULL);
  • break;
  • }
  • // on dessine
  • case WM_PAINT:
  • {
  • P_MY_HDC hdc;
  • int cx,cy;
  • cx = LOWORD(lParam);
  • cy = HIWORD(lParam);
  • hdc = (P_MY_HDC)wParam;
  • myPushPen(hdc,PS_NULL,0,0);
  • myPushBrush(hdc,BS_SOLID,RGB_BLACK,0);
  • {
  • myRectangle(hdc,&rcHyperCube1);
  • myRectangle(hdc,&rcHyperCube2);
  • myRectangle(hdc,&rcHyperCube3);
  • myRectangle(hdc,&rcHyperCube4);
  • }
  • myPopBrush(hdc);
  • myPopPen(hdc);
  • DrawHyperCube(hdc,hyperCube1);
  • DrawHyperCube(hdc,hyperCube2);
  • DrawHyperCube(hdc,hyperCube3);
  • DrawHyperCube(hdc,hyperCube4);
  • myRepaintWindow(hwndStatusBar);
  • break;
  • }
  • // destruction de la fenetre
  • case WM_DESTROY:
  • {
  • KillTimer(hwnd,ID_MOVE_EYES);
  • DeleteHyperCube(hyperCube1);
  • DeleteHyperCube(hyperCube2);
  • DeleteHyperCube(hyperCube3);
  • DeleteHyperCube(hyperCube4);
  • // on quitte le programme
  • PostQuitMessage(0);
  • break;
  • }
  • }
  • return 0;
  • } // WndProc()
  • //-------------------------------------------------
  • // WIN MAIN
  • //-------------------------------------------------
  • int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdLine,int iCmdShow)
  • {
  • WNDCLASSEX wc;
  • RECT rc;
  • HWND hwnd;
  • int wParamResult;
  • // le programme vient de commencer, on initialise les librairies
  • InitializationLibUtil();
  • InitializationLibWinutil(hInstance);
  • SetRandom(GetTickCount());
  • mySetDefaultWindowClass(&wc,hInstance);
  • wc.lpszClassName = "JCD_HyperCube";
  • SetRect(&rc,0,0,800,600);
  • hwnd = myCreateWindow(&wc,
  • "HyperCube (JCD)",
  • WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN,
  • &rc,
  • TRUE,
  • NULL,
  • NULL,
  • 0,
  • NULL,
  • WndProc
  • );
  • // on commence la boucle de messages
  • SetDefaultHwnd(hwnd);
  • wParamResult = myRunWindow(hwnd,SW_SHOW);
  • SetDefaultHwnd(NULL);
  • // on a fini le programme, on ferme les librairies
  • CloseLibUtil();
  • CloseLibWinutil();
  • CheckingClosingLibUtil();
  • CheckingClosingLibWinutil();
  • return wParamResult;
  • } // WinMain()
#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_

//-------------------------------------------------
// VERTEX
//-------------------------------------------------
typedef struct tagVERTEX
  {
  DBL_LIST  other;

  P_VECTND  p0;
  P_VECTND  p1;

  COLORREF  color;
  }VERTEX,*P_VERTEX,**PP_VERTEX;


//-------------------------------------------------
void PushVertex(P_VERTEX first,P_VECTND p0,P_VECTND p1,COLORREF color)
{
P_VERTEX p;

AssertPointer(first);
AssertGoodVectND(p0);
AssertGoodVectND(p1);

p         = Malloc(VERTEX,1);
p->color  = color;
p->p0     = p0;
p->p1     = p1;

InsertItemDblList(&first->other,&p->other);
} // PushVertex()


//-------------------------------------------------
BOOL DrawVertex(P_MY_HDC hdc,P_MY_GRAPH graph,P_VERTEX vertex,P_VECTND u,P_VECTND v)
{
P_DBL_LIST L;

L = &vertex->other;

AssertPointer(hdc);
AssertPointer(graph);
AssertPointer(vertex);
AssertGoodVectND(u);
AssertGoodVectND(v);

while(&vertex->other != (L = GetNextItemDblList(L)))
  {
  double    x0,y0,x1,y1;
  P_VERTEX  cur;

  cur = FROM_TO(VERTEX,other,L);

  x0 = DotProductVectND(u,cur->p0);
  y0 = DotProductVectND(v,cur->p0);

  x1 = DotProductVectND(u,cur->p1);
  y1 = DotProductVectND(v,cur->p1);

  myPushPen(hdc,PS_SOLID,0,cur->color);
  MoveToEx(GetHdc(hdc),myConvXFromViewToWindowGraph(graph,x0),myConvYFromViewToWindowGraph(graph,y0),FALSE);
  LineTo(GetHdc(hdc),myConvXFromViewToWindowGraph(graph,x1),myConvYFromViewToWindowGraph(graph,y1));
  myPopPen(hdc);
  }

return TRUE;
} // DrawVertex()


//-------------------------------------------------
BOOL PopVertex(P_VERTEX first)
{
P_DBL_LIST  L;

L = GetNextItemDblList(&first->other);
if(L == &first->other)
  {
  return FALSE;
  }
else
  {
  BOOL      r;
  P_VERTEX  p;
  
  p = FROM_TO(VERTEX,other,L);
  r = RemoveItemDblList(&first->other,L);
  Free(p->p0);
  Free(p->p1);
  Free(p);
  return r;
  }
} // PopVertex()


//-------------------------------------------------
// HYPER_CUBE
//-------------------------------------------------
typedef struct tagHYPER_CUBE
  {
  int         dim;        // dimension de l'hypercube
  MY_GRAPH    graph;      // graphique
  VERTEX      vertex;     // les lignes formants l'hypercube
  HRGN        region;     // region GDI (correspond au <rcWindow> de <graph>
  P_VECTND    u,v;        // deux vecteurs formant un plan (ce sont les "yeux")
  P_VECTND    du,dv;
  }HYPER_CUBE,*P_HYPER_CUBE,**PP_HYPER_CUBE;


//-------------------------------------------------
void FillVectND(P_VECTND u,double d)
{
int     dim,i;
double  *p;

dim = u->dim;
p   = u->coord;

for(i=0;i<dim;i++)
  {
  *p = d;
  p ++;
  }

} // FillVectND()


//-------------------------------------------------
void RandomVectND(P_VECTND u,double min,double max)
{
int     dim,i;
double  *p;

dim = u->dim;
p   = u->coord;

for(i=0;i<dim;i++)
  {
  *p = RandomDouble(min,max);
  p ++;
  }

} // RandomVectND()


//-------------------------------------------------
COLORREF getColor(int n)
{
static COLORREF tab[] =
  {
  RGB(255,0,0),
  RGB(0,255,0),
  RGB(0,0,255),
  RGB(255,255,0),
  RGB(255,0,255),
  RGB(0,255,255),
  RGB(255,125,125),
  RGB(125,255,125),
  RGB(125,125,255),
  RGB(255,255,255)
  };

Assert(n >= 0);
if(n >= COUNT(tab))
  {
  return RGB_WHITE;
  }
else
  {
  return tab[n];
  }
} // getColor()


//-------------------------------------------------
void BuildHyperCube(P_HYPER_CUBE p)
{
int       dim,nVertex,i;

dim     = p->dim;
nVertex = 1 << (dim - 1);

for(i=0;i<dim;i++) // balaye tous les groupes d'aretes paralleles a un1 vecteur de base
  {
  int j;

  for(j=0;j<nVertex;j++) // balaye toutes les aretes paralleles a un vecteur de base
    {
    int       k,mask;
    P_VECTND  p0,p1; // point de depart et d'arriver de l'arete
    double    *pP0,*pP1;

    p0  = CreateVectND(dim);
    p1  = CreateVectND(dim);

    pP0 = p0->coord;
    pP1 = p1->coord;
    
    mask = 1;
    for(k=0;k<dim;k++) // initialise l'arete en question
      {
      if(k != i)
        {
        *pP0 = *pP1 = (j & mask) ? -1. : +1.;
        mask <<= 1;
        }
      else
        {
        *pP0 = -1.;
        *pP1 = +1.;
        }

      pP0 ++;
      pP1 ++;
      }

    PushVertex(&p->vertex,p0,p1,getColor(i));
    }
  }
} // BuildHyperCube()

//-------------------------------------------------
// re-arrange les vecteurs <u> et <v> de la bonne facon (en changeant <v>)
void Ortho(P_VECTND u,P_VECTND v)
{
double k;
k = DotProductVectND(u,v);
AddVectND(v,v,u,1.,-k); // on rend les deux vecteurs orthogonaux
} // Ortho()


//-------------------------------------------------
void ValidateUVHyperCube(P_HYPER_CUBE p)
{
UnitVectND(p->u);
Ortho(p->u,p->v);
UnitVectND(p->v);
} // ValidateUVHyperCube()


//-------------------------------------------------
#define MAX_DIM 20
P_HYPER_CUBE CreateHyperCube(int dim)
{
P_HYPER_CUBE  p;
P_VERTEX      vertex;

Assert(dim >= 2 && dim <= MAX_DIM); // on se limite a MAX_DIM dimensions

p = Malloc(HYPER_CUBE,1);
p->dim      = dim;
p->region   = myCreateEmptyRegion();
p->u        = CreateVectND(dim);
p->v        = CreateVectND(dim);
p->du       = CreateVectND(dim);
p->dv       = CreateVectND(dim);
InitDblList(&p->vertex.other);

vertex = &p->vertex;
RandomVectND(p->u,-1.,+1.);
SetCoordVectND(p->u,0,1.); // pour s'assuer que le vecteur ne sera pas nul
RandomVectND(p->v,-1.,+1.);
SetCoordVectND(p->v,1,1.); // pour s'assuer que le vecteur ne sera pas nul
ValidateUVHyperCube(p);

FillVectND(p->du,0.);
FillVectND(p->dv,0.);

BuildHyperCube(p);

return p;
} // CreateHyperCube()


//-------------------------------------------------
P_HYPER_CUBE ResizeHyperCube(P_HYPER_CUBE p,RECT *pRect)
{
RECTD   rc;
double  k;

AssertPointer(p);
AssertPointer(pRect);
AssertGDIObject(p->region);

DeleteObject(p->region);
p->region = myCreateRectRegion(pRect);

// longueur de la grande arete d'un hypercube de dimension N : sqrt(N)
// pour le carre c'est sqrt(2)
// pour le cube c'est sqrt(3)
// pour trouver la formule ... utilisez N-1 fois le theoreme de Pythagore
k     = 1.01*sqrt((double)p->dim); // on rajoute 1% de marge

rc.left   = -k;
rc.top    = +k;
rc.right  = +k;
rc.bottom = -k;
mySetWindowGraph(&p->graph,pRect);
mySetViewGraph(&p->graph,&rc,myMinAspectRatio,NULL);

return p;
} // ResizeHyperCube()


//-------------------------------------------------
BOOL DrawHyperCube(P_MY_HDC hdc,P_HYPER_CUBE p)
{
AssertPointer(p);
AssertPointer(hdc);
AssertGDIObject(p->region);

myPushRegionIndirect(hdc,p->region);
DrawVertex(hdc,&p->graph,&p->vertex,p->u,p->v);
myPopRegionIndirect(hdc,FALSE);

return TRUE;
} // DrawHyperCube()


//-------------------------------------------------
// change l'angle de vu
void MoveEyesHyperCube(P_HYPER_CUBE p)
{
P_VECTND  du,dv;
int       dim;
double    k,d;

AssertPointer(p);

dim = p->dim;
du  = CreateVectND(dim);
dv  = CreateVectND(dim);

RandomVectND(du,-1.,+1.);
RandomVectND(dv,-1.,+1.);

// coefficient de l'influence du nouveau <du> (ou <dv>)
k = 0.05;
// longeur du deplacement
d = 0.1;

//Ortho(p->u,du);
//Ortho(p->v,dv);

AddVectND(p->du,p->du,du,1.-k,k*d);
AddVectND(p->dv,p->dv,dv,1.-k,k*d);

AddVectND(p->u,p->u,p->du,1.,1.);
AddVectND(p->v,p->v,p->dv,1.,1.);

ValidateUVHyperCube(p);

Free(du);
Free(dv);
} // MoveEyesHyperCube()

//-------------------------------------------------
void DeleteHyperCube(P_HYPER_CUBE p)
{
AssertPointer(p);
AssertGDIObject(p->region);

while(PopVertex(&p->vertex));
DeleteObject(p->region);
Free(p->du);
Free(p->dv);
Free(p->u);
Free(p->v);

Free(p);
} // DeleteHyperCube()


//-------------------------------------------------
// WND_PROC
//-------------------------------------------------
#define ID_MOVE_EYES  1000

#define FRAME         20
//-------------------------------------------------
void Info(HWND hwnd,P_HYPER_CUBE p)
{
if(NULL == p)
  {
  myWarning(hwnd,"Informations sur le programme ...",
            "HyperCube\r\n"
            "\r\n"
            "Un carré c'est en 2 dimensions\r\n"
            "Un cube c'est en 3 dimensions\r\n"
            "Un hypercube c'est en N dimensions\r\n"
            "\r\n"
            "Cliquez sur les hypercubes pour avoir des informations\r\n"
            "\r\n"
            "Programmé par JCDjcd\r\n"
            );
  }
else
  {
  AssertPointer(p);
  myWarning(hwnd,"Informations sur l'hypercube ...",
            "HyperCube de dimension %d\r\n"
            "\r\n"
            "Nombre de sommets (2^n) : %d\r\n"
            "Nombre d' arêtes (n.2^(n-1)) : %d\r\n"
            "\r\n",
            p->dim,
            1 << p->dim,
            p->dim * (1 << (p->dim - 1))
            );
  }
} // Info()


//-------------------------------------------------
int WndProc(P_MY_WINDOW myWindow,HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
{
static HWND           hwndStatusBar;
static P_HYPER_CUBE   hyperCube1,hyperCube2,hyperCube3,hyperCube4;
static RECT           rcHyperCube1,rcHyperCube2,rcHyperCube3,rcHyperCube4;

switch(iMsg)
  {
	case WM_CREATE:
    {
    int allWidth[5];

    // style de fenetre
    myWindow->bResizedWindow   = TRUE;
    myWindow->bUseBackBuffer   = TRUE;
    myWindow->colorBackGround  = RGB_WHITE;
    
    // la bar
    hwndStatusBar = CreateStatusWindow(WS_VISIBLE | WS_CHILD,"",hwnd,100);
    allWidth[0] = 100;
    allWidth[1] = 200;
    allWidth[2] = 300;
    allWidth[3] = 400;
    allWidth[4] = -1;
    SendMessage(hwndStatusBar,SB_SETPARTS,(WPARAM)COUNT(allWidth),(LPARAM)allWidth);

    SendMessage(hwndStatusBar,SB_SETTEXT,(WPARAM)0,(LPARAM)"\tDimension 3");
    SendMessage(hwndStatusBar,SB_SETTEXT,(WPARAM)1,(LPARAM)"\tDimension 4");
    SendMessage(hwndStatusBar,SB_SETTEXT,(WPARAM)2,(LPARAM)"\tDimension 5");
    SendMessage(hwndStatusBar,SB_SETTEXT,(WPARAM)3,(LPARAM)"\tDimension 10");
    SendMessage(hwndStatusBar,SB_SETTEXT,(WPARAM)4,(LPARAM)"\tProgrammé par JCDjcd");

    hyperCube1 = CreateHyperCube(3);
    hyperCube2 = CreateHyperCube(4);
    hyperCube3 = CreateHyperCube(5);
    hyperCube4 = CreateHyperCube(10);

    SetTimer(hwnd,ID_MOVE_EYES,0,NULL);
    break;
    }
  case WM_SIZE:
    {
    int     cx,cy,cxRect,cyRect;
    double  dx,dy;
    RECT    rcStatusBar,rc;


    GetWindowRect(hwndStatusBar,&rcStatusBar);
    cx      = LOWORD(lParam);
    cy      = HIWORD(lParam) - myHeightRect(&rcStatusBar);
    mySetRectWH(&rc,0,0,cx,cy);

    cxRect  = (cx - 3 * FRAME)/2;
    cyRect  = (cy - 3 * FRAME)/2;

    dx      = (1.+((double)cxRect)/((double)cx))/3.;
    dy      = (1.+((double)cyRect)/((double)cy))/3.;

    mySetRectWH(&rcHyperCube1,0,0,cxRect,cyRect);    
    mySetRectWH(&rcHyperCube2,0,0,cxRect,cyRect);    
    mySetRectWH(&rcHyperCube3,0,0,cxRect,cyRect);    
    mySetRectWH(&rcHyperCube4,0,0,cxRect,cyRect);    

    myCenterRect(&rcHyperCube1,1.,1.,&rc,1.*dx,1.*dy);
    myCenterRect(&rcHyperCube2,1.,1.,&rc,2.*dx,1.*dy);
    myCenterRect(&rcHyperCube3,1.,1.,&rc,1.*dx,2.*dy);
    myCenterRect(&rcHyperCube4,1.,1.,&rc,2.*dx,2.*dy);

    ResizeHyperCube(hyperCube1,&rcHyperCube1);
    ResizeHyperCube(hyperCube2,&rcHyperCube2);
    ResizeHyperCube(hyperCube3,&rcHyperCube3);
    ResizeHyperCube(hyperCube4,&rcHyperCube4);

    SendMessage(hwndStatusBar,iMsg,0,lParam);
    break;
    }
  case WM_TIMER:
    {
    switch(LOWORD(wParam))
      {
      case ID_MOVE_EYES:
        {
        MoveEyesHyperCube(hyperCube1);
        MoveEyesHyperCube(hyperCube2);
        MoveEyesHyperCube(hyperCube3);
        MoveEyesHyperCube(hyperCube4);
        myRepaintWindow(hwnd);
        break;
        }
      }    
    break;
    }
  case WM_LBUTTONDOWN:
  case WM_RBUTTONDOWN:
    {
    POINT pt;

    pt.x = LOWORD(lParam);
    pt.y = HIWORD(lParam);

    if(PtInRect(&rcHyperCube1,pt))        Info(hwnd,hyperCube1);
    else if(PtInRect(&rcHyperCube2,pt))   Info(hwnd,hyperCube2);
    else if(PtInRect(&rcHyperCube3,pt))   Info(hwnd,hyperCube3);
    else if(PtInRect(&rcHyperCube4,pt))   Info(hwnd,hyperCube4);
    else                                  Info(hwnd,NULL);
    
    break;
    }
  // on dessine
	case WM_PAINT:
    {
    P_MY_HDC  hdc;
    int       cx,cy;

    cx  = LOWORD(lParam);
    cy  = HIWORD(lParam);
    hdc = (P_MY_HDC)wParam;

    myPushPen(hdc,PS_NULL,0,0);
    myPushBrush(hdc,BS_SOLID,RGB_BLACK,0);
      {
      myRectangle(hdc,&rcHyperCube1);
      myRectangle(hdc,&rcHyperCube2);
      myRectangle(hdc,&rcHyperCube3);
      myRectangle(hdc,&rcHyperCube4);
      }
    myPopBrush(hdc);
    myPopPen(hdc);

    DrawHyperCube(hdc,hyperCube1);
    DrawHyperCube(hdc,hyperCube2);
    DrawHyperCube(hdc,hyperCube3);
    DrawHyperCube(hdc,hyperCube4);

    myRepaintWindow(hwndStatusBar);
		break;
    }
  // destruction de la fenetre
	case WM_DESTROY:
    {
    KillTimer(hwnd,ID_MOVE_EYES);
    DeleteHyperCube(hyperCube1);
    DeleteHyperCube(hyperCube2);
    DeleteHyperCube(hyperCube3);
    DeleteHyperCube(hyperCube4);
    // on quitte le programme
    PostQuitMessage(0);
		break;
    }
  }

return 0;
} // WndProc()


//-------------------------------------------------
// WIN MAIN
//-------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdLine,int iCmdShow)
{
WNDCLASSEX  wc;
RECT        rc;
HWND        hwnd;
int         wParamResult;

// le programme vient de commencer, on initialise les librairies
InitializationLibUtil();
InitializationLibWinutil(hInstance);

SetRandom(GetTickCount());

mySetDefaultWindowClass(&wc,hInstance);
wc.lpszClassName  = "JCD_HyperCube";

SetRect(&rc,0,0,800,600);

hwnd = myCreateWindow(&wc,
	                    "HyperCube (JCD)",
                      WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN,
                      &rc,
                      TRUE,
	                    NULL,
                      NULL,
	                    0,
                      NULL,
	                    WndProc
                      );

// on commence la boucle de messages
SetDefaultHwnd(hwnd);
wParamResult = myRunWindow(hwnd,SW_SHOW);
SetDefaultHwnd(NULL);

// on a fini le programme, on ferme les librairies
CloseLibUtil();
CloseLibWinutil();

CheckingClosingLibUtil();
CheckingClosingLibWinutil();
return wParamResult;
} // WinMain()



 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture COLORATION SYNTAXIQUE
Source avec Zip Source avec une capture ORBITES DES SATELLITES GPS
Source avec Zip Source avec une capture DESSIN D'ARBRES
Source avec Zip Source avec une capture PROGRAMMATION LINEAIRE
Source avec Zip EXTENSION DE CORPS (MATH)

 Sources de la même categorie

Source avec Zip UN EXAMPLE D'APPLICATION EN CUDA DE L'ALGORITHME DE SCAN POU... par oguzaras
Source avec Zip Source avec une capture CHIFFREMENT DE VIGENERE par lajouad
Source avec Zip Source avec une capture ANALYSE SYNTAXIQUE par lajouad
Source avec Zip Source avec une capture STRUCTURE D'UNE MATRICE PAR LES LISTE LINÉAIRE (NON CONTUGUS... par benzarabel
Source avec Zip Source avec une capture DESSINER UNE ARBRE BINAIRE( MODE CONSOLE): par benzarabel

Commentaires et avis

Commentaire de AlexMAN le 26/08/2004 12:56:00

Jme trompe ptet mais pour moi, les dimensions representent en fait le nombre d'axes, or ici, jvois pas les 10 axes differents ds ton hypercube a 10Dimensions.
Je pars surement sur de mauvaises connaissances, donc n'hesitez pas a me contredire .

++

Commentaire de JCDjcd le 26/08/2004 13:45:56

Mais oui les dimensions c'est des axes suplementaires, il n'y a pas de doute. Mais  je n'affiche pas les axe, pour le cube, tu arrives a bien le voir, pourtant il n'y a pas les 3 axes. je dessine juste le cube. Mais si je pourrais afficher les axes, ce qui surchargerait les graphiques qui sont deja lourd (voir le monstre de la 10eme dimension).

Commentaire de TeLeTUbIz le 26/08/2004 18:22:00

Assez intéressant, mais sur quelle représentation t'appuis tu ? Car parfois en dim 4 "deux cubes" se réunissent pour n'en former qu'un comme si c'était un cube de dim 3.

Commentaire de JCDjcd le 26/08/2004 18:38:35

Ben le probleme se pose aussi en dimension 3, si tu regarde de face le cube, alors 'est un carre. Donc si l'yeux est sur un des axes, alors c'est un hypercube de dimension N-1.

La representation est la suivante : je prend deux vecteurs u et v dans l'espace de dim N, u et v normalises et orthgonaux. et u et v definise les axes de ton ecran.

Commentaire de TeLeTUbIz le 26/08/2004 19:05:30

En gros une projection orthogonale ?
Pourtant déjà en dimension 3 c'est assez inexact (en fait on ne devrait pas voir les arretes de derrière de la même taille que celles de devant, donc normalement on utilise la perspective cavalière).
Seulement sur un cube, je reconnais que la différence se voit pas, mais comment sait t-on que ca reste négligeable pour la 4eme dimension ?
Existe t-il une analogie (ou généralisation) de la perspective cavalière aux autres dimensions.

...intéressant, un moteur 4D...

Pardon si mes questions sont un peu chiantes mais je travail dans les maths et même si les espaces vectoriels sont monnaie courante, on étudie pas les concepts liés à la représentation matérielle et/ou graphique.

Mais sinon ca reste très très beau :-)
Une heure que je le matte; on pourrait pas en faire un screensaver ?

Commentaire de AlexMAN le 26/08/2004 19:20:30

TeLeTUbIz >> Pour mettre en screensaver, tu renommes en *.scr, et tu te demerdes pour enlever la barre de titre, c'est une bonne idée ! Allez JCDjcd, au boulot...:)

++

Commentaire de JCDjcd le 26/08/2004 19:48:22

Pour enlever la barre de titre, c'est tres simple : tu va dans le CreateWindow, et tu l'enleve dans les styles.

Il n'y a pas de perpective, l'oeil est suppose a l'infini avec des lunettes groissisantes infinies elles aussi.

Sinon vous pouvez vous meme programmer des figure en N dimensions, par exemple des HyperSimplex (triangle en 2D, et tetraedre en 3D) et voire ce que cela fais en N dim.

Commentaire de blancoman le 17/05/2005 14:55:37

Je me pose pas mal de questions a propos de ce progamme!
En effet, il faut savoir que celui n'a qu'une utilité visuelle!
Je m'explique : si l'on part de l'idée que la représentation d' un cube de dimension 3(un dé) se fait sur une surface de dimention 2 ce qui est très bien fait sur le programme, alors, en raisonnant par analogie, on en conclu que l'hypercube de dimension 4 doit trouver une projection sur une base de dimension 4( on peu aussi imaginer que cela est representé sur le programme, je vous l'accorde) mais le probleme arrive avec la projection de cubes de dimension supérieur ou égale à 5. Là il nous faut une base de dimension (minimum!) 4 dimension(j'espere que vous suivez la logique)or il nous est impossible de nous représenter les dimensions strictement supérieur à 3 dimension(je pense que vous en êtes tous convaincu). Dans ce cas il faudrai utiliser des projections de projection(ce qui est utilisé dans le programme)
Pour ceux qui veulent en savoir plus sur la 4èmé dimension et plus, beaucoup d'ouvrages citent 'Flatland' de Edwin Abbott qui fait de nombreuses analogies avec les dimensions que nous pouvons appréhender afin de nous familiariser avec le sujet.

Commentaire de assalam le 03/06/2005 13:14:34

bonjour,moi je voudrai si quelqu'un a un algorithme pour la construction de tous les possibilitées d'hypercubes qu'on peut construire a partir de n point telque n s'ecrit n=2^p merci

Commentaire de imanedaoudi le 07/10/2005 00:38:42

moi par contre , je voudrais savoir comment calculer la distance minimale est maximale qui sépare l'ypercube de dimension 10 à un point dans l'espace 10D?

Commentaire de TeLeTUbIz le 07/10/2005 10:50:58

Hey les gars, vous posez vos exos de maths sur la source ?

Commentaire de Tearsofdestiny le 11/11/2009 20:45:18

Bonjour,

je suis désolé si la remarque n'apporte pas grand-chose, mais c'est vraiment du code de débutant? :s

merci

Commentaire de JCDjcd le 12/11/2009 10:20:09

Je n'en sais trop rien, je mets toutes mes sources en débutant. De toute maniere ici il ne faut pas se fier a la categorie, quand je vois certaine source "experte" je me marre...

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,764 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales