/* LA: linear algebra C++ interface library graphical test program Copyright (C) 2022 Jiri Pittner or This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "la.h" #include "vecmat3.h" #include "quaternion.h" #include "permutation.h" #include "polynomial.h" #include "contfrac.h" #include "simple.h" #include #include #include #include #include #include using namespace std; using namespace LA_Vecmat3; using namespace LA_Quaternion; using namespace LA_Simple; using namespace LA; /* * function: create_simple_window. Creates a window with a white background * in the given size. * input: display, size of the window (in pixels), and location of the window * (in pixels). * output: the window's ID. * notes: window is created with a black border, 2 pixels wide. * the window is automatically mapped after its creation. */ Window create_simple_window(Display* display, int width, int height, int x, int y) { int screen_num = DefaultScreen(display); int win_border_width = 2; Window win; /* create a simple window, as a direct child of the screen's */ /* root window. Use the screen's black and white colors as */ /* the foreground and background colors of the window, */ /* respectively. Place the new window's top-left corner at */ /* the given 'x,y' coordinates. */ win = XCreateSimpleWindow(display, RootWindow(display, screen_num), x, y, width, height, win_border_width, BlackPixel(display, screen_num), WhitePixel(display, screen_num)); /* make the window actually appear on the screen. */ XMapWindow(display, win); /* flush all pending requests to the X server. */ XFlush(display); return win; } GC create_gc(Display* display, Window win) { GC gc; /* handle of newly created GC. */ unsigned long valuemask = 0; /* which values in 'values' to */ /* check when creating the GC. */ XGCValues values; /* initial values for the GC. */ unsigned int line_width = 1; /* line width for the GC. */ int line_style = LineSolid; /* style for lines drawing and */ int cap_style = CapButt; /* style of the line's edje and */ int join_style = JoinBevel; /* joined lines. */ int screen_num = DefaultScreen(display); gc = XCreateGC(display, win, valuemask, &values); if (!gc) { fprintf(stderr, "error XCreateGC: \n"); } /* define the style of lines that will be drawn using this GC. */ XSetLineAttributes(display, gc, line_width, line_style, cap_style, join_style); /* define the fill style for the GC. to be 'solid filling'. */ XSetFillStyle(display, gc, FillSolid); return gc; } typedef struct { Vec3 point0; Vec3 point1; } LINE; template<> class LA::LA_traits { public: static bool is_plaindata() {return true;}; typedef double normtype; }; void plotobject(Display* display, Pixmap pixmap, GC gc, int width,int height, const NRVec &lines, const Mat3 &rot_angle, const Vec3 &camera, const Vec3 &plane_to_camera, double xod,double xdo,double yod,double ydo) { for(int i=0; i lines(lines0); Mat3 rot_angle; double eul[3]={4.*M_PI/180.,3.*M_PI/180.,1.*M_PI/180.}; euler2rotmat(eul,rot_angle,"xyz"); double zoom=1; rot_angle *= zoom; Vec3 camera={50,60,40}; Vec3 plane_to_camera={-20,-20,-20}; XSetForeground(display,gc,mycolor.pixel); plotobject(display, pixmap, gc, width,height, lines,rot_angle,camera,plane_to_camera,xod,xdo,yod,ydo); XClearWindow(display,win); //expose the pixmap XSetForeground(display, gc, BlackPixel(display, DefaultScreen(display)));//vratit cernou XFlush(display); XSync(display, False); //prepare to receive events XSelectInput(display, win, KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|Button1MotionMask|PointerMotionMask); XEvent event; int ispressed1=0; int ispressed2=0; int ispressed3=0; int x,y,x0,y0; while(1) //LOOP .... process events { bool redraw=0; XNextEvent(display, &event); switch (event.type) { case KeyPress: { char text[16]; KeySym mykey; int n=XLookupString(&event.xkey, text,16,&mykey,0); if(n==1&&text[0]=='q') goto done; } break; case ButtonPress: if(event.xbutton.button==Button1) ispressed1=1; if(event.xbutton.button==Button2) ispressed2=1; if(event.xbutton.button==Button3) ispressed3=1; if(event.xbutton.button==Button4) { if(ispressed1) {eul[2]+=0.02; redraw=1;} else if(ispressed2) {camera[2]+=0.2; redraw=1;} else if (ispressed3) {plane_to_camera[2]+=0.5; redraw=1;} else {zoom*=1.01; redraw=1;} } if(event.xbutton.button==Button5) { if(ispressed1) {eul[2]-=0.02; redraw=1;} else if(ispressed2) {camera[2]-=0.2; redraw=1;} else if (ispressed3) {plane_to_camera[2]-=0.5; redraw=1;} else {zoom*=.99; redraw=1;} } break; case MotionNotify: x = event.xbutton.x; y = event.xbutton.y; if(ispressed1) { if(x0>x) eul[0]+=0.01; if(x0y) eul[1]+=0.01; if(y0x) camera[0]+=0.2; if(x0y) camera[1]-=0.2; if(y0x) plane_to_camera[0]-=0.5; if(x0y) plane_to_camera[1]+=0.5; if(y0