Ostrosłup prawidłowy o podstawie będącej n-kątem - Open

Astronom
Użytkownik
Użytkownik
Posty: 21
Rejestracja: 7 cze 2006, o 00:58
Płeć: Mężczyzna
Lokalizacja: /dev/andromeda

Ostrosłup prawidłowy o podstawie będącej n-kątem - Open

Post autor: Astronom » 8 sty 2007, o 09:52

Jak napisać funkcję

void rysujOstroslup(void);

która narysuje ostrosłup prawidłowy o podstawie będącej n-kątem (czyli np. 83 kątem lub 1052 kątem) foremnym leżącym w płaszczynie OXZ i wpisanym w okrąg jednostkowy.

Jednym z wierzchoków tego n-kąta foremnego jest punkt (1,0,0)

Wierzchołek ostrosłupa znajduje się w punkcie (0,5,0)



Najwięsza trudność to wyznaczenie wszystkich wierzchoków n-kąta foremnego. Domylam się że należałoby zastosować, np. wzory Muavra (nie wiem czy to tak się pisze) z zastosowaniem liczb zespolonych na wyznaczenie wszystkich wierzchoków na okręgu jednostkowym.
Problem w tym, że nie wiem jak to zaprogramować choć wiem jak to się liczy na kartce papieru :D

I sposób chyba najodpowiedniejszy do tego, to:

Kod: Zaznacz cały

int n=0;
cout<<"Wczytaj ilosc wierzchokow w podstawie ostroslupa prawidlowego"<<endl;
cin>>n;
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0,5,0);                        // to byloby Vo
glVertex3f(1,0,0);                        // to byloby V1
for(int i=0; i<n; i++)
{

// no i problem jak zaprogramować wzór Muavra wyznaczający wierzchołki w n-kącie foremnym na okręgu jednostkowym 
}



P.S. Temat dałem również tutaj: http://forum.suse.pl/index.php/topic,12086.0.html oraz http://www.linux.com.pl/forum/index.php ... a97e880fa1 bo jest mi to potrzebne na zaraz !!

[ Dodano: 8 Styczeń 2007, 12:20 ]

Kod: Zaznacz cały

//gcc triangle..cpp -o triangle -I/usr/X11R6/include/ -L/usr/X11R6/lib -lX11 -lXmu -lglut -lGL -lGLU

#include <GL/glut.h>
#include <stdlib.h>
#include<iostream>
#include <math.h>
#include<ncurses.h>
/*
void init(void)
{
   GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
   GLfloat mat_shininess[] = { 50.0 };
   GLfloat light_position[] = { 0.0, 5.0, 5.0, 0.0 };

   glClearColor (0.0, 0.0, 0.0, 0.0);
   glShadeModel (GL_SMOOTH);

   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
   glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
   glLightfv(GL_LIGHT0, GL_POSITION, light_position);

   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
   glEnable(GL_DEPTH_TEST);


}
*/
void display(void)
{

   const float PI = 3.14159265358979323846f;
   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glColor3f (0.0, 1.0, 1.0);   //kolor cyan

  glPushMatrix();


//-----------------------------
glBegin(GL_TRIANGLE_FAN); 
glVertex3f(0,5,0);                        // to byloby Vo 
glVertex3f(1,0,0);                        // to byloby V1 
 glColor3f (1.0, 0.0, 1.0);   //kolor white
for (int i=7; i>=0; i--)
{
  std::cout << "(" << cos(i*2*PI/8) << ",0," << sin(2*i*PI/8) << ")\n";
//glVertex3f(cos(i*2*PI/8),0,sin(i*2*PI/8)); 
glColor3f (1.0, 0.0, 1.0);
 glVertex3f(cos((i+1)*2*PI/8),0,sin((i+1)*2*PI/8));
}
/*
for (int i=0; i<=8; i++) 
{
                std::cout << "(" << cos(i*2*PI/8) << ",0," << sin(2*i*PI/8) << ")\n"; 

}
*/
//-------------------------

   glPopMatrix();
   glutSwapBuffers();
}


/*
void reshape (int w, int h)
{
   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
*/

int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
   glutInitWindowSize (500, 500);
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);
  // init ();
   glutDisplayFunc(display);
   //glutReshapeFunc(reshape);
   glutMainLoop();
   return 0;
}

Niby się kompilue, ale ciemny ekran. Czy coś z kolorami jest nie tak ustawione?

Dostaję punkty:
(0.707107,0,-0.707107)
(1.31134e-07,0,-1)
(-0.707107,0,-0.707107)
(-1,0,-8.74228e-08)
(-0.707107,0,0.707107)
(-4.37114e-08,0,1)
(0.707107,0,0.707107)
(1,0,0)

[ Dodano: 17 Styczeń 2007, 10:04 ]
Zamieszczam działający kod na platformę linux, bo może się komuś przyda:

Kompilujemy:
//gcc glx.cpp -o triangle -I/usr/X11R6/include/ -L/usr/X11R6/lib -lX11 -lXmu -lglut -lGL -lGLU

Kod: Zaznacz cały


#include <stdio.h>
#include <GL/glx.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <X11/extensions/xf86vmode.h>
#include <X11/keysym.h>
#include<math.h>
#include<iostream>
/* stuff about our window grouped together */
typedef struct {
    Display *dpy;
    int screen;
    Window win;
    GLXContext ctx;
    XSetWindowAttributes attr;
    Bool fs;
    Bool doubleBuffered;
    XF86VidModeModeInfo deskMode;
    int x, y;
    unsigned int width, height;
    unsigned int depth;    
} GLWindow;

/* attributes for a single buffered visual in RGBA format with at least
 * 4 bits per color and a 16 bit depth buffer */
static int attrListSgl[] = {GLX_RGBA, GLX_RED_SIZE, 4, 
    GLX_GREEN_SIZE, 4, 
    GLX_BLUE_SIZE, 4, 
    GLX_DEPTH_SIZE, 16,
    None};

/* attributes for a double buffered visual in RGBA format with at least 
 * 4 bits per color and a 16 bit depth buffer */
static int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER, 
    GLX_RED_SIZE, 4, 
    GLX_GREEN_SIZE, 4, 
    GLX_BLUE_SIZE, 4, 
    GLX_DEPTH_SIZE, 16,
    None };

GLWindow GLWin;
GLfloat rotTri, rotQuad;

/* function called when our window is resized (should only happen in window mode) */
void resizeGLScene(unsigned int width, unsigned int height)
{
    if (height == 0)    /* Prevent A Divide By Zero If The Window Is Too Small */
        height = 1;
    glViewport(0, 0, width, height);    /* Reset The Current Viewport And Perspective Transformation */
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
    glMatrixMode(GL_MODELVIEW);
}

/* general OpenGL initialization function */
int initGL(GLvoid)
{
    glShadeModel(GL_SMOOTH);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    /* we use resizeGLScene once to set up our initial perspective */
    resizeGLScene(GLWin.width, GLWin.height);
    /* Reset the rotation angles of our objects */
    rotTri = 0;
    rotQuad = 0;    
    glFlush();
    return True;
}

/* Here goes our drawing code */
void display(GLvoid)
{  
const float PI = 3.141592653589f;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(0.0, -1.0, -8.0f);
    glRotatef(rotTri, 0.0, 1.0, 0.0);
    glBegin(GL_TRIANGLE_FAN);
    glVertex3f(0,4,0);
    glVertex3f(1,0,0);
     int n=10;
    for (int i=0; i<n; i++) 
    { 
         //  std::cout << "(" << cos(i*2*PI/8) << ",0," << sin(2*i*PI/8) << ")\n"; 
        glColor3f(0.0f , 0.0f , 1.0f);
        glVertex3f(cos(i*2*PI/n) , 0 , sin(i*2*PI/n));
        glColor3f(0.0f , 1.0f , 0.0f);
        glVertex3f(cos((i+1)*2*PI/n) , 0 , sin((i+1)*2*PI/n));
    }
    glEnd();
    glBegin(GL_POLYGON);
    glVertex3f(0,0,0);
for (int i=0; i<n; i++) 
    { 
         //  std::cout << "(" << cos(i*2*PI/8) << ",0," << sin(2*i*PI/8) << ")\n"; 
        glColor3f(1.0f , 0.0f , 1.0f);
        glVertex3f(cos(i*2*PI/n) , 0 , sin(i*2*PI/n));
        glColor3f(0.0f , 0.0f , 1.0f);
        glVertex3f(cos((i+1)*2*PI/n) , 0 , sin((i+1)*2*PI/n));
    }
    glEnd();
    rotTri += 0.2f;
    rotQuad -= 0.15f;
    if (GLWin.doubleBuffered)
    {
        glXSwapBuffers(GLWin.dpy, GLWin.win);
    }
    //return True;    
}

/* function to release/destroy our resources and restoring the old desktop */
GLvoid killGLWindow(GLvoid)
{
    if (GLWin.ctx)
    {
        if (!glXMakeCurrent(GLWin.dpy, None, NULL))
        {
            printf("Could not release drawing context.\n");
        }
        glXDestroyContext(GLWin.dpy, GLWin.ctx);
        GLWin.ctx = NULL;
    }
    /* switch back to original desktop resolution if we were in fs */
    if (GLWin.fs)
    {
        XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, &GLWin.deskMode);
        XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0);
    }
    XCloseDisplay(GLWin.dpy);
}

/* this function creates our window and sets it up properly */
/* FIXME: bits is currently unused */
Bool createGLWindow(char* title, int width, int height, int bits,
                    Bool fullscreenflag)
{
    XVisualInfo *vi;
    Colormap cmap;
    int dpyWidth, dpyHeight;
    int i;
    int glxMajorVersion, glxMinorVersion;
    int vidModeMajorVersion, vidModeMinorVersion;
    XF86VidModeModeInfo **modes;
    int modeNum;
    int bestMode;
    Atom wmDelete;
    Window winDummy;
    unsigned int borderDummy;
    
    GLWin.fs = fullscreenflag;
    /* set best mode to current */
    bestMode = 0;
    /* get a connection */
    GLWin.dpy = XOpenDisplay(0);
    GLWin.screen = DefaultScreen(GLWin.dpy);
    XF86VidModeQueryVersion(GLWin.dpy, &vidModeMajorVersion,
        &vidModeMinorVersion);
    printf("XF86VidModeExtension-Version %d.%d\n", vidModeMajorVersion,
        vidModeMinorVersion);
    XF86VidModeGetAllModeLines(GLWin.dpy, GLWin.screen, &modeNum, &modes);
    /* save desktop-resolution before switching modes */
    GLWin.deskMode = *modes[0];
    /* look for mode with requested resolution */
    for (i = 0; i < modeNum; i++)
    {
        if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height))
        {
            bestMode = i;
        }
    }
    /* get an appropriate visual */
    vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDbl);
    if (vi == NULL)
    {
        vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl);
        GLWin.doubleBuffered = False;
        printf("Only Singlebuffered Visual!\n");
    }
    else
    {
        GLWin.doubleBuffered = True;
        printf("Got Doublebuffered Visual!\n");
    }
    glXQueryVersion(GLWin.dpy, &glxMajorVersion, &glxMinorVersion);
    printf("glX-Version %d.%d\n", glxMajorVersion, glxMinorVersion);
    /* create a GLX context */
    GLWin.ctx = glXCreateContext(GLWin.dpy, vi, 0, GL_TRUE);
    /* create a color map */
    cmap = XCreateColormap(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
        vi->visual, AllocNone);
    GLWin.attr.colormap = cmap;
    GLWin.attr.border_pixel = 0;

    if (GLWin.fs)
    {
        XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, modes[bestMode]);
        XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0);
        dpyWidth = modes[bestMode]->hdisplay;
        dpyHeight = modes[bestMode]->vdisplay;
        printf("Resolution %dx%d\n", dpyWidth, dpyHeight);
        XFree(modes);
    
        /* create a fullscreen window */
        GLWin.attr.override_redirect = True;
        GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
            StructureNotifyMask;
        GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
            0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual,
            CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,
            &GLWin.attr);
        XWarpPointer(GLWin.dpy, None, GLWin.win, 0, 0, 0, 0, 0, 0);
		XMapRaised(GLWin.dpy, GLWin.win);
        XGrabKeyboard(GLWin.dpy, GLWin.win, True, GrabModeAsync,
            GrabModeAsync, CurrentTime);
        XGrabPointer(GLWin.dpy, GLWin.win, True, ButtonPressMask,
            GrabModeAsync, GrabModeAsync, GLWin.win, None, CurrentTime);
    }
    else
    {
        /* create a window in window mode*/
        GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
            StructureNotifyMask;
        GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
            0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
            CWBorderPixel | CWColormap | CWEventMask, &GLWin.attr);
        /* only set window title and handle wm_delete_events if in windowed mode */
        wmDelete = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True);
        XSetWMProtocols(GLWin.dpy, GLWin.win, &wmDelete, 1);
        XSetStandardProperties(GLWin.dpy, GLWin.win, title,
            title, None, NULL, 0, NULL);
        XMapRaised(GLWin.dpy, GLWin.win);
    }       
    /* connect the glx-context to the window */
    glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx);
    XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y,
        &GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth);
    printf("Depth %d\n", GLWin.depth);
    if (glXIsDirect(GLWin.dpy, GLWin.ctx)) 
        printf("Congrats, you have Direct Rendering!\n");
    else
        printf("Sorry, no Direct Rendering possible!\n");
    initGL();
    return True;    
}

int main(int argc, char **argv)
{

    XEvent event;
    Bool done;
    
    done = False;
    /* default to fullscreen */
    GLWin.fs = False;
    createGLWindow("He..he...ale program :)", 540, 340, 24, GLWin.fs);

    /* wait for events*/ 
    while (!done)
    {
        /* handle the events in the queue */
        while (XPending(GLWin.dpy) > 0)
        {
            XNextEvent(GLWin.dpy, &event);
            switch (event.type)
            {
                case Expose:
	                if (event.xexpose.count != 0)
	                    break;
                    display();
         	        break;
	            case ConfigureNotify:
	            /* call resizeGLScene only if our window-size changed */
	                if ((event.xconfigure.width != GLWin.width) || 
	                    (event.xconfigure.height != GLWin.height))
	                {
	                    GLWin.width = event.xconfigure.width;
	                    GLWin.height = event.xconfigure.height;
                        printf("Resize event\n");
	                    resizeGLScene(event.xconfigure.width,
	                        event.xconfigure.height);
	                }
	                break;
                /* exit in case of a mouse button press */
                case ButtonPress:
                    done = True;
                    break;
                case KeyPress:
                    if (XLookupKeysym(&event.xkey, 0) == XK_Escape)
                    {
                        done = True;
                    }
                    if (XLookupKeysym(&event.xkey,0) == XK_F1)
                    {
                        killGLWindow();
                        GLWin.fs = !GLWin.fs;
                        createGLWindow("NeHe's Solid Objects Tutorial",
                            640, 480, 24, GLWin.fs);
                    }
                    break;
                case ClientMessage:
                    if (*XGetAtomName(GLWin.dpy, event.xclient.message_type) == 
                        *"WM_PROTOCOLS")
                    {
                        printf("Exiting sanely...\n");
                        done = True;
                    }
                    break;
                default:
                    break;
            }
        }
        display();
    }
    killGLWindow();
    
}

ODPOWIEDZ