#include "glos.h"
#include <math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include <stdio.h>
/*
Program uporablja kurzorske tipke za rotacijo vrtenine, "p" za pogled na XY ravnino,
ter "a" in "q" za pribljizevanje (oddaljevanje) pogleda. S tipko "s" shranimo v DXF.
Za ponovno prevajanje v C++ je potrebno v meniju
Project -> Settings... pod Linking dodati naslednje knjiznice:
opengl32.lib glaux.lib glu32.lib glut.lib
*/
struct Tocka // Struktura tipa tocka
{
float X,Y,Z;
};
Tocka T[30][300]; // polje tock
Tocka a,b; // tocki, ki podajata os vrtenja
int NoTock; // st. podanih tock
int xAngle ,yAngle ,zAngle; // Koti za pogled
int StDelitev; // Stevilo delitev po obodu
float Fi; // Kot zavrtitve
double z =1; // Zoom
double Pi = 3.1415926;
// ROTIRANJE IN ZOOM
void CALLBACK RollUp (void) //rotiranje slike navzgor
{
xAngle = (xAngle - 3) % 360;
}
void CALLBACK RollDown (void) //rotiranje slike navzdol
{
xAngle = (xAngle + 3) % 360;
}
void CALLBACK RollRight (void) //rotiranje v desno
{
zAngle = (zAngle - 3) % 360;
}
void CALLBACK RollLeft (void) //rotiranje v levo
{
zAngle = (zAngle + 3) % 360;
}
void CALLBACK Planview (void) //pogled na XY ravnino
{
xAngle =0;
zAngle =0;
}
void CALLBACK Noter (void) //pribizevanje slike
{
z = (z + 0.05);
}
void CALLBACK Ven (void) //oddaljevanje slike
{
z = (z - 0.05);
}
// BRANJE PODATKOV IZ DATOTEKE KRIVULJA.TXT
void Branje(void)
{
FILE *dat;
if( (dat=fopen("krivulja.txt","r")) == NULL )
{
printf( "Datoteka ni bila najdena!\n" );
exit(0);
}
else
// Os vrtenja
fscanf(dat,"%f %f\n",&a.X,&a.Y);
fscanf(dat,"%f %f\n",&b.X,&b.Y);
// Kot zavrtitve
fscanf(dat,"%f\n",&Fi);
// Delitev
fscanf(dat,"%d\n",&StDelitev);
// Stevilo tock
fscanf(dat,"%d\n",&NoTock);
// Krivulja podana s crtami
for (int k=0;k<NoTock;k++)
{
fscanf(dat,"%f %f\n",&T[k][0].X,&T[k][0].Y);
}
// Zakljucek datoteke:
fclose(dat);
}
// GENERIRANJE DATOTEKE VRTENINA.DXF:
void CALLBACK Pisanje(void)
{
FILE *kazdat;
kazdat=fopen("vrtenina.dxf","w");
// Definicija datoteke
fprintf(kazdat," %d\n%s\n %d\n%s\n",0,"SECTION",2,"ENTITIES");
// Navpicne crte:
for (int i=0;i<NoTock-1;i++)
{
for (int j=0;j<=StDelitev;j++)
{
fprintf(kazdat," %d\n%s\n %d\n%d\n",0,"LINE",8,0);
// 1. tocka crte:
fprintf(kazdat," %d\n %f\n %d\n %f\n %d\n %f\n",10,T[i][j].X,20,T[i][j].Y,30,T[i][j].Z);
// 2. tocka crte:
fprintf(kazdat," %d\n %f\n %d\n %f\n %d\n %f\n",11,T[i+1][j].X,21,T[i+1][j].Y,31,T[i+1][j].Z);
}
}
// Vodoravne crte:
for (i=0;i<NoTock;i++)
{
for (int j=0;j<=StDelitev-1;j++)
{
fprintf(kazdat," %d\n%s\n %d\n%d\n",0,"LINE",8,0);
// 1. tocka crte:
fprintf(kazdat," %d\n %f\n %d\n %f\n %d\n %f\n",10,T[i][j+1].X,20,T[i][j+1].Y,30,T[i][j+1].Z);
// 2. tocka crte:
fprintf(kazdat," %d\n %f\n %d\n %f\n %d\n %f\n",11,T[i][j].X,21,T[i][j].Y,31,T[i][j].Z);
}
}
// Zakljucek datoteke:
fprintf(kazdat," %d\n%s\n %d\n%s\n",0,"ENDSEC",0,"EOF");
fclose(kazdat);
}
//IZRACUN, IZRIS
void myinit(void)
{
Branje();
// IZRACUN VRTENINE IZ KRIVULJE
int i,j; //stevca
float alfa; //kot rotacije
Tocka Rt; //racunska tocka
// Primik krivulje
for (i=0;i<NoTock;i++)
{
T[i][0].X=T[i][0].X-a.X;
T[i][0].Y=T[i][0].Y-a.Y;
}
//Izracun kota zasuka
alfa=-atan2((b.X-a.X), (b.Y-a.Y));
// Zasuk krivulje k Y osi
for (i=0;i<NoTock;i++)
{
Rt.X=T[i][0].X;
Rt.Y=T[i][0].Y;
T[i][0].X=Rt.X*cos(alfa)+Rt.Y*sin(alfa);
T[i][0].Y=Rt.Y*cos(alfa)-Rt.X*sin(alfa);
}
//Izracun tock vrtenine
for (i=0;i<NoTock;i++)
{
for (j=1;j<=StDelitev;j++)
{
T[i][j].X=T[i][0].X*cos(j*Fi/StDelitev*Pi/180);
T[i][j].Y=T[i][0].Y;
T[i][j].Z=-T[i][0].X*sin(j*Fi/StDelitev*Pi/180);
}
}
// Zasuk vrtenine od Y osi
for (i=0;i<NoTock;i++)
{
for (j=0;j<=StDelitev;j++)
{
Rt.X=T[i][j].X;
Rt.Y=T[i][j].Y;
T[i][j].X=Rt.X*cos(alfa)-Rt.Y*sin(alfa);
T[i][j].Y=Rt.X*sin(alfa)+Rt.Y*cos(alfa);
}
}
// Premik vrtenine
for (i=0;i<NoTock;i++)
{
for (j=0;j<=StDelitev;j++)
{
T[i][j].X=T[i][j].X+a.X;
T[i][j].Y=T[i][j].Y+a.Y;
}
}
//GENERIRANJE LISTE st. 10
glNewList(10, GL_COMPILE);
//Linijski model vrtenine (rdece)
glLineWidth(2);
for (i=0;i<NoTock-1;i++)
{
for (int j=0;j<=StDelitev;j++)
{
glBegin(GL_LINES);
glColor3f (1.0, 0.0, 0.0);
glVertex3f(T[i][j].X, T[i][j].Y, T[i][j].Z);
glVertex3f(T[i+1][j].X, T[i+1][j].Y, T[i+1][j].Z);
glEnd();
}
}
for (i=0;i<NoTock;i++)
{
for (j=0;j<=StDelitev-1;j++)
{
glBegin(GL_LINES);
glColor3f (1.0, 0.0, 0.0);
glVertex3f(T[i][j+1].X, T[i][j+1].Y, T[i][j+1].Z);
glVertex3f(T[i][j].X, T[i][j].Y, T[i][j].Z);
glEnd();
}
}
glLineWidth(1);
//narise vhodno krivuljo (rumeno)
for (i=0;i<NoTock-1;i++)
{
glBegin(GL_LINES);
glColor3f(1.0,1.0,0.0);
glVertex3f(T[i+1][0].X, T[i+1][0].Y, T[i+1][0].Z);
glVertex3f(T[i][0].X, T[i][0].Y, T[i][0].Z);
glEnd();
}
//narise koordinatni sistem (belo)
glBegin(GL_LINES);
//x os
glColor3f (1.0, 1.0, 1.0);
glVertex3f(0,0,0);
glVertex3f(+60,0,0);
//y os
glColor3f (1.0, 1.0, 1.0);
glVertex3f(0,0,0);
glVertex3f(0,+60,0);
//z os
glColor3f (1.0, 1.0, 1.0);
glVertex3f(0,0,0);
glVertex3f(0,0,+60);
glEnd();
// Narise os vrtenja (zeleno, crta-pika)
glLineStipple(5,64250);
glEnable(GL_LINE_STIPPLE);
glBegin(GL_LINES);
glColor3f (0.0, 1.0, 0.0);
glVertex3f(a.X,a.Y,a.Z);
glVertex3f(b.X,b.Y,b.Z);
glEnd();
glDisable(GL_LINE_STIPPLE);
glEndList();
glClearColor(0.0, 0.0, 0.0, 0.0);
}
// OBNAVLJANJE SLIKE
void CALLBACK display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f (1.0, 0.0, 0.0);
glPushMatrix();
// Rotacija slike
glRotatef (xAngle, 1, 0, 0);
glRotatef (yAngle, 0, 1, 0);
glRotatef (zAngle, 0, 0, 1);
// Zoom
glScaled(z,z,z);
glCallList(10);
glPopMatrix();
glFlush();
auxSwapBuffers(); // double buffer (Izracun v spominu ->hiter izris)
}
// Resize window
void CALLBACK myReshape(GLsizei w, GLsizei h)
{
if (!h) return;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.0, 1, 0.0, 250.0); //globina izrisa
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef (0.0, 0.0, -100); //visina gledanja
}
void main(void)
{
auxInitDisplayMode (AUX_DOUBLE | AUX_RGB | AUX_DEPTH16);
auxInitPosition (10, 10, 700, 700);
auxInitWindow ("Vrtenina - izris");
myinit();
auxKeyFunc (AUX_UP, RollUp); //tipke za rotiranje slike
auxKeyFunc (AUX_DOWN, RollDown);
auxKeyFunc (AUX_LEFT, RollLeft);
auxKeyFunc (AUX_RIGHT, RollRight);
auxKeyFunc (AUX_p, Planview);
auxKeyFunc (AUX_a, Noter); // tipke za zoom
auxKeyFunc (AUX_q, Ven);
auxKeyFunc (AUX_s, Pisanje); // zapis DXF
// Obnavljanje (klicanje funkcij)
auxReshapeFunc (myReshape); // klice se ob spreminjanju okna
auxIdleFunc (display); // skrbi za osvezevanje
auxMainLoop(display);
}