This is main.c in view mode; [Download] [Up]
/* todo: add menu with choice of groups: now icosa,octa, tetra */ #include <stdio.h> #include <geom.h> #include "vec4.h" #include "trigrp.h" #include <mg.h> #include <window.h> #include <appearance.h> #include <color.h> #include <gl/gl.h> #include <gl/device.h> extern char *getenv(); /* Barycentric: convert from 236 triangle coordinate system to barycentric coordinate system: (1,0,0,0): pi/2 (0,1,0,0): pi/3 (0,0,1,0): pi/6 Input: a point in the same coordinate system as the global variable reftri */ #define Barycentric(src,dst) PtTransform(ireftri[G_236],&src,&dst); \ fprintf(stderr,"Barycentric: %f %f %f %f\n",dst.x,dst.y,dst.z,dst.w); #define PI 3.1415926 char *progname; FILE *toviewer = stdout; char cmapfile[128] = ""; extern char *grpnames[]; extern Geom *plist; extern Geom *eucplist; extern char *group_path; static Geom *fd; extern Geom *Make2nmFD(); int dbg = 0, batch = 0, stop = 1,active_group = 0, which = 0, automatic = 0, newgroup = 1; int menu; WnPosition wp; HPoint3 ppoint = {0.15, 0.4, 0.0, 1.0}, bary; static HPoint3 vel = {.005, .008, 0, 0}; static Transform LineTri; extern Transform reftri[], ireftri[], gens[][3]; extern float t236[][4]; static int initmenu(); double MyDot(p0,p1) float *p0, *p1; { return(p0[0]*p1[0] + p0[1]*p1[1] + p0[2]*p1[2] + p0[3]*p1[3]); } void init_Lines() { int i; LineTri[0][0] = reftri[G_236][1][1] - reftri[G_236][2][1]; LineTri[0][1] = -reftri[G_236][1][0] + reftri[G_236][2][0]; LineTri[0][3] = reftri[G_236][1][0]*reftri[G_236][2][1] - reftri[G_236][2][0]*reftri[G_236][1][1]; LineTri[1][0] = reftri[G_236][2][1] - reftri[G_236][0][1]; LineTri[1][1] = -reftri[G_236][2][0] + reftri[G_236][0][0]; LineTri[1][3] = reftri[G_236][2][0]*reftri[G_236][0][1] - reftri[G_236][0][0]*reftri[G_236][2][1]; LineTri[2][0] = reftri[G_236][0][1] - reftri[G_236][1][1]; LineTri[2][1] = -reftri[G_236][0][0] + reftri[G_236][1][0]; LineTri[2][3] = reftri[G_236][0][0]*reftri[G_236][1][1] - reftri[G_236][1][0]*reftri[G_236][0][1]; LineTri[0][2] = LineTri[1][2] = LineTri[2][2] = 0.0; } int GetOrigin(pt) register HPoint3 *pt; { /* simple solution now */ int x,y; float px, py, winsize; int xsize, ysize; int xmid, ymid; int reverse = 0; xsize = (wp.xmax - wp.xmin + 1); ysize = (wp.ymax - wp.ymin + 1); winsize = xsize < ysize ? xsize : ysize; xmid = (wp.xmin + wp.xmax) / 2; ymid = (wp.ymin + wp.ymax) / 2; /* only look when the left mouse button's down */ x = getvaluator(MOUSEX); if (x > wp.xmax || x < wp.xmin) return(0); px = (XMAX - XMIN) * ((x - xmid)/winsize) + (XMIN+XMAX)/2; y = getvaluator(MOUSEY); if (y > wp.ymax || y < wp.ymin) return(0); py = (YMAX - YMIN) * ((y - ymid)/winsize) + (YMIN+YMAX)/2; if(px == pt->x && py == pt->y) return 0; pt->x = px; pt->y = py; return(1); } static SendBegin() { fprintf(toviewer, "(progn"); } static SendEnd() { fprintf(toviewer, ")"); fflush(toviewer); } static SendFD() { fprintf(toviewer, "(read geometry { define fd "); GeomFSave(plist, toviewer, "stdout"); fprintf(toviewer, "} )\n"); fflush(toviewer); } static SendGroup() { static int washyp = 0; int needhyp; static char *space[2] = { "(space euclidean) (normalization trigrp on)", "(space hyperbolic)" }; fprintf(toviewer, "(geometry trigrp { = INST tlist < %s/%s.prj unit : fd })", group_path, grpnames[active_group]); needhyp = (active_group == 4); if(washyp != needhyp) fprintf(toviewer, "%s\n", space[needhyp]); washyp = needhyp; fflush(toviewer); } main(argc, argv) char **argv; { int i, n,m, count = 1; short val, dev; char *term = getenv("TERM"); progname = argv[0]; active_group = G_236; if (!batch) if(term == NULL || strcmp(term, "iris-ansi") != 0) { fprintf(stderr,"Not on an iris-ansi terminal, unsafe to use windows\n"); batch = 1; } init_groups(); readcmap(cmapfile); /* and initialize polylist structure */ init_plist(active_group); init_Lines(); /* in interactive mode, init graphics for inputting distinguished point */ if (!batch) { static Color gray = {.8,.8,.8}; foreground(); mgdevice_GL(); mgctxcreate(MG_WnSet, WN_NAME, "trigrp", WN_END, MG_CamSet, CAM_PERSPECTIVE, 0, CAM_FOCUS, 1., CAM_HALFYFIELD, .5, CAM_END, MG_ApSet, AP_DO, APF_FACEDRAW|APF_EDGEDRAW, AP_SHADING, APF_CONSTANT, AP_END, MG_BACKGROUND, &gray, MG_END); mgreshapeviewport(); initmouse(); menu = initmenu(); PtTransform(ireftri[G_236],&ppoint,&bary); drawframe(); fprintf(stderr,"Trigrp: use left button to drag meeting point, right button for menu.\n"); } i = 0; if (!batch) { while (1) { /* if interactive, continue forever */ if(newgroup) { drawframe(); fd = Make2nmFD(bary, active_group, plist); SendBegin(); SendFD(); SendGroup(); SendEnd(); newgroup = 0; } if (automatic) { ppoint.x += vel.x; ppoint.y += vel.y; for (i=0; i<3; ++i) { /* is bouncing point outside triangle ? */ if (MyDot(&ppoint, LineTri[i]) < 0) { PtTransform(gens[G_236][i], &ppoint, &ppoint); PtTransform(gens[G_236][i], &vel, &vel); i = 3; } } drawframe(); PtTransform(ireftri[G_236],&ppoint,&bary); fd = Make2nmFD(bary, active_group, plist); SendFD(); sginap(20); } if (!automatic || qtest()) { dev = qread(&val); switch(dev) { case LEFTMOUSE: case MIDDLEMOUSE: automatic = 0; do { if(GetOrigin(&ppoint)) { PtTransform(ireftri[G_236],&ppoint,&bary); fd = Make2nmFD(bary, active_group, plist); SendFD(); drawframe(); } sginap(20); } while(getbutton(dev)); break; case KEYBD: switch(val) { case '3': case '4': case '5': case '6': case '7': active_group = val - '3'; newgroup = 2; break; case 'a': automatic = 1 - automatic; break; case 'p': fprintf(stderr,"Barycentric: %f %f %f %f\n",bary.x,bary.y,bary.z,bary.w); break; case '\033': case 'Q': gexit(); exit(1); /* Quit */ } break; case MENUBUTTON: if( val ) { switch(val = dopup(menu)) { case 0: case 1: case 2: case 3: case 4: active_group = val; newgroup = 2; break; case 5: fprintf(stderr,"Barycentric: %f %f %f %f\n",bary.x,bary.y,bary.z,bary.w); break; case 6: automatic = 1 - automatic; break; case 7: exit(1); break; /* Quit */ } } break; case REDRAW: mgreshapeviewport(); initmouse(); drawframe(); break; } } } } else { fd = Make2nmFD(bary, active_group, plist); GeomFSave(fd, stdout, "stdout"); } } initmouse() { WnWindow *w; qdevice(LEFTMOUSE); qdevice(MIDDLEMOUSE); qdevice(MENUBUTTON); qdevice(KEYBD); mgctxget(MG_WINDOW, &w); WnGet(w, WN_CURPOS, &wp); } #ifdef sgi #include <fmclient.h> labelframe() { static int fminitted = 0; static fmfonthandle font = NULL; int i; static struct label { float x, y; char str[4]; } lab[3] = { {-.05,-.05, "p/2" }, { .505, -.05, "p/3" }, { .05, .85, "p/N" } }; if(!fminitted) { fminit(); font = fmfindfont("Symbol"); if(font) fmsetfont(fmscalefont(font, 12)); } if(font) { pushattributes(); cpack(0); pushmatrix(); lab[2].str[2] = active_group + '3'; for(i=0; i<3; i++) { cmov2(lab[i].x, lab[i].y); fmprstr(lab[i].str); } popmatrix(); popattributes(); } } #endif /*sgi*/ drawframe() { Transform T; mgworldbegin(); TmTranslate(T, -.25, -.4, 0.); mgtransform(T); Make2nmFD(bary, G_236, eucplist); GeomDraw(eucplist); #ifdef sgi labelframe(); #endif mgworldend(); } static int initmenu() { int pup; long groupmenu; pup = defpup("Trigrp %t"); addtopup(pup, "233 [3]%x0|234 [4]%x1|235 [5]%x2|236 [6]%x3|237 [7]%x4|PrintBary [p]%x5|Autopilot [a]%x6|Quit [Q]%x7"); return pup; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.