Bidon et basique je sais On sait jamais...
for(angle = 0 ; angle < 360 ; angle++) { x = cos(angle); y = sin(angle); drawpixel(x,y) }
Attention c'est pas un langage particulier
copiez/collez pas ça
Hors ligne
izguit :
On sait jamais...
bingo ! justement, je me demandais comment j'allais m'y prendre, dire que je trifouaillais dans l'api pour trouver un truc pour dessiner sous mes fourmis,
il me suffit de le dessiner a la main (donc pareil mais en 3 d)
merci
Dernière modification par Jerry Kan (15-01-2007 19:22:32)
Hors ligne
Ben... en fait, c'est faux !
Izguit, tu as oublié que les ordinateurs fonctionnent en radian !
for(angle = 0 ; angle < 360 ; angle++) { angleradian = angle/180*pi(); x = cos(angleradian); y = sin(angleradian); drawpixel(x,y) }
Jerry Kan, il y a parfois des bibliothèques de calculs trigos qui prennent directement les degrés, a vérifier. Pour l'instant, je n'ai pas encore vu a pars des fonctions spécifiques genre CosDegree().
Dernière modification par diOxy (16-01-2007 11:26:01)
Hors ligne
ah bin ça dépend de la biblio de math utilisée après
sous blitz3d par exemple c'est en degrés....
mais c'est bien de le signaler
Hors ligne
Il me semble que sous Torque aussi. Mais dans un langage de programmation (Pas un moteur de jeu) ce sont les radians qui sont utilisés.
Mais bon. Du moment que l'on est au courant, plus de blèmes !
Hors ligne
Allez j'en rajoute une couche, un cercle qui prend en paramètre un rayon et une precision (entre Epsilon, minimum et +inf, maximum), c'est du C++-pseudo mais facile facile :
function drawcircle(float r, float precision) { float step = 1f / precision; for(float angle = 0f; angle < pi * 2f; angle += step) { x = cos(angle) * r; y = sin(angle) * r; drawpixel(x, y); } }
Et maintenant, pour la sphère (qui n'est qu'une série de cercles bizarres) :
function drawcircle(float r, float precision) { float step = 1f / precision; for(float sangle = 0f; sangle < pi * 2f; sangle += step) { for(float angle = 0f; angle < pi * 2f; angle += step) { // On réduit le nombre d'opérations trigo au possible. float sinsangle = sin(sangle); x = cos(angle) * r * sinsangle; y = sin(angle) * r * sinsangle; z = r * cos(sangle); drawpixel(x, y, z); } } }
PS : Je viens d'avoir une sacré hésitation sur la sphère alors si vous voulez me rattrapper, n'hésitez pas, j'ai peut-être fait une grosse erreur.
Dernière modification par DeusXL (18-01-2007 17:15:16)
Hors ligne
Si mais souvenir sont bon (mon cours d'il y a un mois) on est pas obligé d'utiliser la trigo,
(x-a)²+(y-b)²=R² est une equation de cercle où I(a,b) est le centre du cercle et R son rayon, je ne sait pas si c'est plus intéréssant ca oblige a utiliser une racine carré mais comme la trigo doit etre calculer a partir des racine ou inversement reste a savoir le plus rapide.
Pour tracer le cercle il suffit de d'écrire la formule sous la forme y = +-sqrt(R²-(x-a)²)+b.
L'ordi doit renvoyer la racine carré positif donc il suffit de prendre l'opposé pour avoir l'autre solution (ca ne fait qu'un demi cercle autrement)
void cercle(int x,int y,int r) { for (int i=x-r;i<=x+r;i++) { pixel(i,sqrt(r*r-(i-x)*(i-x))+y); pixel(i,-sqrt(r*r-(i-x)*(i-x))+y); } }
Je prend de x-r à x+r car cela semble logique et ca se prouve grace a l'ensemble de définition de cette fonction.
Voila je ne sait pas si ca peut aider mais je suis en premiere autant que ca serve a quelque chose
Dite moi si j'ai fait une erreur c tres probable.
Pour la sphere on paut faire la même chose en rajoutant la coordonnée z : (x-a)²+(y-b)²+(z-b)²=R²
voila mais apres je vous laisse voud debrouiller ce n'est pas au programme et ce n'est pas que je ne sait pas faire mais je ne sais pas si mes methodes serait tres bonne
a+
dark calculator
Ps: n'oublier pas les carrés j'ai perdu un point pour ca au dernier controle de math
Hors ligne
exact ca peut marcher comme ca aussi mais les racines carrées sont pas mal lentes non plus.
float Q_rsqrt( float number ) { long i; float x2, y; const float threehalfs = 1.5F; x2 = number * 0.5F; y = number; i = * ( long * ) &y; // evil floating point bit level hacking i = 0x5f3759df - ( i >> 1 ); // what the fuck? y = * ( float * ) &i; y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration // y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed #ifndef Q3_VM #ifdef __linux__ assert( !isnan(y) ); // bk010122 - FPE? #endif #endif return y; }
Fonction de racine carrée utilisée par John Carmack dans Quake 3 (license GPL attention), beaucoup plus rapide que la fonction native. (Oui oui chelou hein ca utilise le nombre 0x5f3759df me demandez pas à quoi il correspond )
Hors ligne
Imaginez on a 2 points 3D, comment tracer un cercle dont le centre est l'un des deux points, le cercle passant par l'autre point?
#include <irrlicht.h> using namespace irr; using namespace core; using namespace gui; using namespace scene; using namespace video; IrrlichtDevice* creer_device() { IrrlichtDevice* device = createDevice(EDT_OPENGL, dimension2d<s32>(600,400), 16, false); if (!device) return NULL; device->getCursorControl()->setVisible(false); device->setWindowCaption(L"cercle"); // camera ISceneManager* smgr = device->getSceneManager(); ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS(0,100.0f,200.0f); cam->setPosition(vector3df(-20,20,-20)); cam->setTarget(vector3df(1,1,1)); IGUIEnvironment* guienv = device->getGUIEnvironment(); guienv->getSkin()->setFont(guienv->getFont("../../media/fontlucida.png")); IGUIFont *font = guienv->getSkin()->getFont(); smgr->addTextSceneNode(font, L"x", SColor(255,230,10,10), NULL, vector3df(10,0,0), -1); smgr->addTextSceneNode(font, L"z", SColor(255,10,10,230), NULL, vector3df(0,0,10), -1); smgr->addTextSceneNode(font, L"y", SColor(255,10,230,10), NULL, vector3df(0,10,0), -1); return device; } int main() { IrrlichtDevice* device = creer_device(); if (!device) return 1; IVideoDriver* driver = device->getVideoDriver(); ISceneManager* smgr = device->getSceneManager(); vector3df centre(0,0,0); vector3df pt1(10,10,10); f32 rayon = centre.getDistanceFrom(pt1); f32 precision=3.f, step = 1.f / precision; while(device->run()) { if (device->isWindowActive()) { driver->beginScene(true, true, SColor(255,100,100,240)); SColor couleur(255,255,255,255); //xyz driver->draw3DLine(vector3df(0,0,0), vector3df(0,8,0), couleur); driver->draw3DLine(vector3df(0,0,0), vector3df(8,0,0), couleur); driver->draw3DLine(vector3df(0,0,0), vector3df(0,0,8), couleur); //cercle for (float angle=0.f; angle<2*PI; angle+=step) { vector3df pt2(cos(angle)*rayon, sin(angle)*rayon, 0); pt2 += centre; driver->draw3DLine(pt1, pt2, couleur); pt1 = pt2; } smgr->drawAll(); driver->endScene(); } } device->drop(); return 0; }
Hors ligne
calcule la distance entre les deux points et cree un cercle sur ton centre avec le rayon que tu viens de calculer
Hors ligne
Question de "newbie" : et comment dessiner un cercle plein ?
Hors ligne
Voila pour un disque.
void drawdisc(int x,int y,int r){ for (int i=x-r;i<=x+r;i++){ drawline(i,sqrt(r*r-(i-x)*(i-x))+y,i,-sqrt(r*r-(i-x)*(i-x))+y); } }
Hors ligne
bon je suis partie de la méthode d'izguit pour faire une sphère
euh ... faut juste remplacé le "((btSphereShape*)Shape)->getRadius()" par le radius que vous voulez
il y a le principe pour les 3 axe m'enfin je trouve le dernier inutile ..... ( Y )
float precision; irr::s32 dist = position.getDistanceFrom(device->getSceneManager()->getActiveCamera()->getPosition());//position correspond .. ba a un vector3df de la position du node if(dist<99) precision = .2f; else if(dist>100&&dist<301) precision = .5f; else if(dist>300&&dist<801) precision = 1.f; else if(dist>800&&dist<1501) precision = 1.5f; else if(dist>1500&&dist<2501)precision = 2.5f; else precision = 3.f; float radius = ((btSphereShape*)Shape)->getRadius()+.5f; for(float sangle=.2f;sangle<PI; sangle += radius/8.33333325)//nombre de tour équivalent a la taille de l'obj { irr::core::vector3df start; float _sin = sin(sangle); end.X = ((cos(.0f)*radius*_sin)+position.X+rotation.X); end.Y = ((sin(.0f)*radius*_sin)+position.Y+rotation.Y); end.Z = ((radius*cos(sangle))+position.Z+rotation.Z); begin = end; for(float angle = .0f;angle<PI*2.08f; angle += precision)//X { end.X = ((cos(angle)*radius*_sin)+position.X+rotation.X); end.Y = ((sin(angle)*radius*_sin)+position.Y+rotation.Y); end.Z = ((radius*cos(sangle))+position.Z+rotation.Z); device->getVideoDriver()->draw3DLine(begin,end,debugColor); begin = end; } end.Y = ((cos(.0f)*radius*_sin)+position.Y+rotation.Y); end.Z = ((sin(.0f)*radius*_sin)+position.Z+rotation.Z); end.X = ((radius*cos(sangle))+position.X+rotation.X); begin = end; for(float angle = .0f;angle<PI*2.08f; angle += precision)//Z { end.Y = ((cos(angle)*radius*_sin)+position.Y+rotation.Y); end.Z = ((sin(angle)*radius*_sin)+position.Z+rotation.Z); end.X = ((radius*cos(sangle))+position.X+rotation.X); device->getVideoDriver()->draw3DLine(begin,end,debugColor); begin = end; } end.X = ((sin(.0f)*radius*_sin)+position.X+rotation.X); end.Y = ((radius*cos(sangle))+position.Y+rotation.Y); end.Z = ((cos(.0f)*radius*_sin)+position.Z+rotation.Z); begin = end; for(float angle = .0f;angle<PI*2.08f; angle += precision)//Y { end.X = ((sin(angle)*radius*_sin)+position.X+rotation.X); end.Y = ((radius*cos(sangle))+position.Y+rotation.Y); end.Z = ((cos(angle)*radius*_sin)+position.Z+rotation.Z); device->getVideoDriver()->draw3DLine(begin,end,debugColor); begin = end; } }
voili voilou
ps : je voudrais rajouté la rotation, mais je ne sais pas trop comment mis prendre ...
Dernière modification par Magun (28-02-2009 04:33:26)
Hors ligne
Bien sympa comme code en tous les cas
Hors ligne