#include #include "libsx.h" #include "crosshair.h" #include "geodata.h" #include "globals.h" #include "kraftwerk.h" #include "graph.h" #include "naca.h" #include "circle.bm" #include "ellips.bm" #include "wing.bm" #include "square.bm" #include "poly.bm" #include "move.bm" #include "kill.bm" #include "zoom.bm" #include "unzoom.bm" #define SYMMETRIC 0 #define NON_SYMMETRIC 1 #define TO_SCALE 0 #define STRECHED 1 typedef struct { char *text; Widget label; Widget toggle; } geoObjectUI; typedef struct { int n; int type; int drawmode; float x[100]; float y[100]; } geoObject; geoObject *thing; Widget outBNDR, innBNDR, intBNDR; Widget closeB; geoObjectUI objectsUI[] = { {"outer"}, {"inner"}, {"internal"}, {"Square"}, {"Circle"}, {"Ellips"}, {"NACA0012"}, {"Polygon"}, {"Move"}, {"Kill"}, {"Zoom"}, {"UnZoom"}}; int nObj = 12; geoObject naca0012 = {18, SYMMETRIC, TO_SCALE, { 0.0, .00351381, .01346558, .03066379, .05517089, .08673215, .12514615, .17041743, .22262233, .28171957, .34769243, .42050737, .50013381, .58655041, .67974794, .77972806, .88648617, 1.0 }, { 0.0, .00919038, .01914215, .02881318, .03721619, .04423213, .05026549, .05524749, .05855709, .06009519, .05966640, .05719906, .05277705, .04655302, .03855282, .02845609, .01568145, 0.0} }; geoObject square = {4, NON_SYMMETRIC, STRECHED, {0., 1., 1., 0.}, {0., 0., 1., 1.} }; geoObject circle; geoObject ellips; geoObject move; geoObject kill; int first = 0; int xlead, ylead; int xtrail, ytrail; Widget geowindow; void killBoundary(); void getBoundaryScale(Widget w, void *data); int clickedOnBoundary(int x, int y, int *segment, int *offset, int *nseg, int *this); GEO_NODE *new_clickedOnBoundary(int x, int y); void setAction(int doThis); void donefcn( Widget w, void *nulldata) { int hh=0, ww=0; SetButtonUpCB(drawWindow, NULL); SetButtonDownCB(drawWindow, NULL); SetMouseMotionCB(drawWindow, NULL); deleteCrossHair(); setAction(NORMAL); SetCurrentWindow(geowindow); CloseWindow(); redisplay(w, hh, ww, nulldata); } void togglefcn(Widget w, void *data) { int i, j, what[2]; int hh=0, ww=0; j = 0; for( i = 0; i < nObj; i++){ if( GetToggleState( objectsUI[i].toggle)) what[j++] = i; } SetButtonDownCB(drawWindow, nacaDown); SetButtonUpCB(drawWindow, NULL); SetMouseMotionCB(drawWindow, nacaMotion); first = 0; switch(what[0]) { case 0: boundaryType = OUTER; break; case 1: boundaryType = INNER; break; case 2: boundaryType = INTERNAL; break; } switch(what[1]) { case 3: thing = □ setAction(DRAWING); break; case 4: thing = &circle; setAction(DRAWING); break; case 5: thing = &ellips; setAction(DRAWING); break; case 6: thing = &naca0012; setAction(DRAWING); break; case 7: inputBoundary(w, data); setAction(DRAWING); break; case 8: moveBoundary( w, data); setAction(MOVING); break; case 9: killBoundary(); break; case 10: deleteCrossHair(); SetMouseMotionCB(drawWindow, NULL); setAction(ZOOMING); zoom(w, data); break; case 11: deleteCrossHair(); SetMouseMotionCB(drawWindow, NULL); SetButtonUpCB(drawWindow, NULL); SetButtonDownCB(drawWindow, NULL); unzoom(w, data); setAction(NORMAL); break; } redisplay(w, hh, ww, data); } void putUpGeoWindow() { int i; geowindow = MakeWindow("Geometry", SAME_DISPLAY, NONEXCLUSIVE_WINDOW); i = 0; objectsUI[i++].toggle = MakeToggle(" Outer " , TRUE , NULL, togglefcn, NULL); objectsUI[i++].toggle = MakeToggle(" Inner " , FALSE,objectsUI[0].toggle , togglefcn, NULL); objectsUI[i++].toggle = MakeToggle(" Internal", FALSE, objectsUI[0].toggle, togglefcn, NULL); for(i = 3; i < nObj; i++){ if(i == 3) objectsUI[i].toggle = MakeToggle(NULL, TRUE, NULL, togglefcn, NULL); else objectsUI[i].toggle = MakeToggle(NULL, FALSE, objectsUI[3].toggle, togglefcn, NULL); } closeB = MakeButton("Close", donefcn, NULL); i = 3; SetWidgetBitmap(objectsUI[i++].toggle, square_bits, square_width, square_height); SetWidgetBitmap(objectsUI[i++].toggle, circle_bits, circle_width, circle_height); SetWidgetBitmap(objectsUI[i++].toggle, ellips_bits, ellips_width, ellips_height); SetWidgetBitmap(objectsUI[i++].toggle, wing_bits, wing_width, wing_height); SetWidgetBitmap(objectsUI[i++].toggle, poly_bits, poly_width, poly_height); SetWidgetBitmap(objectsUI[i++].toggle, move_bits, move_width, move_height); SetWidgetBitmap(objectsUI[i++].toggle, kill_bits, kill_width, kill_height); SetWidgetBitmap(objectsUI[i++].toggle, zoom_bits, zoom_width, zoom_height); SetWidgetBitmap(objectsUI[i++].toggle, unzoom_bits, unzoom_width, unzoom_height); for(i = 1; i < nObj; i++){ SetWidgetPos(objectsUI[i].toggle, PLACE_UNDER, objectsUI[i-1].toggle, NO_CARE, NULL); } SetWidgetPos(closeB, PLACE_UNDER, objectsUI[nObj-1].toggle, NO_CARE, NULL); togglefcn(drawWindow, NULL); ShowDisplay(); } void initCircle(geoObject *circle, int n, int id) { int i; double fi; for(i = 0; i < n ; i++){ fi = (double) 2 * 3.141592 * i / n; circle->x[i] = (float) cos(fi); circle->y[i] = (float) sin(fi); } circle->n = n ; circle->type = NON_SYMMETRIC; if(id == 0) circle->drawmode = STRECHED; else circle->drawmode = TO_SCALE; } void naca(Widget w, void *data) { int hh=0, ww=0; first = 0; boundaryType = INNER; initCircle(&circle, 30, 1); initCircle(&ellips, 30, 0); thing = □ thing = &naca0012; putUpGeoWindow(); SetButtonDownCB(drawWindow, nacaDown); SetMouseMotionCB(drawWindow, nacaMotion); setAction(DRAWING); state = HAVE_BOUNDARY; redisplay(w, hh, ww, data); } void nacaMotion(Widget w, int xp, int yp, void *data) { crossHair(xp,yp); if(state == HAVE_NOTHING){ getBoundaryScale(w, data); } state = HAVE_BOUNDARY; if(first == 1){ SetDrawMode(SANE_XOR); drawNaca(xlead, ylead, xtrail, ytrail); drawNaca(xlead, ylead, xp, yp); SetDrawMode(GXcopy); xtrail = xp; ytrail = yp; } } double maxsize(int comp) { double max, cmp; int i; max = -1000; for( i = 0; i < thing->n; i++){ if(comp == 0) cmp = thing->x[i]; else cmp = thing->y[i]; cmp = sqrt(cmp*cmp); if( cmp > max) max = cmp; } return max; } void nacaDown(Widget w, int button, int x, int y, void *data) { double l, lx, ly, ca, sa, xx, yy; float x1, y1, x2, y2; double lp, lpx, lpy; int xp, yp; int nb, i; float xphys, yphys; PTS_NODE *p0, *p1, *p2; GEO_NODE *g; if( first == 0){ first = 1; xlead = x; ylead = y; xtrail = x; ytrail = y; } else{ first = 0; SetButtonDownCB(drawWindow, NULL); SetMouseMotionCB(drawWindow, NULL); deleteCrossHair(); g = new_bnd(); g->type = boundaryType; pix2phys(xlead, ylead, &x1, &y1); pix2phys(x, y, &x2, &y2); if(thing->drawmode == TO_SCALE){ l = sqrt((double) (xlead-x)*(xlead-x) + (ylead-y)*(ylead-y)); l = l / maxsize(0); if(l == 0.0) l = .000001; lx = l; ly = l; lp = sqrt((double) (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); lp = lp / maxsize(0); lpx = lp; lpy = lp; ca = (double) (x-xlead) / l; sa = (double) (y-ylead) / l; } else{ lx = (double) (x - xlead )/maxsize(0); ly = (double) (y - ylead )/maxsize(1); ca = 1.; sa = 0.; lpx = (x2 - x1) / (double) maxsize(0); lpy = (y2 - y1) / (double) maxsize(1); } i = 0; xx = lx * thing->x[i]; yy = ly * thing->y[i]; x2 = (float) lpx * thing->x[i]; y2 = -(float) lpy * thing->y[i]; xp = (int) (xx*ca - yy*sa + xlead); yp = (int) (xx*sa + yy*ca + ylead); xphys = (float) (x2*ca - y2*sa + x1); yphys = (float) (-x2*sa - y2*ca + y1); p0 = add_pnt(xphys, yphys); p1 = p0; for(i = 1; i < thing->n; i++){ xx = lx * thing->x[i]; yy = ly * thing->y[i]; x2 = (float) lpx * thing->x[i]; y2 = -(float) lpy * thing->y[i]; xp = (int) (xx*ca - yy*sa + xlead); yp = (int) (xx*sa + yy*ca + ylead); xphys = (float) (x2*ca - y2*sa + x1); yphys = (float) (-x2*sa - y2*ca + y1); p2 = add_pnt(xphys, yphys); add_seg(p1, p2, g); p1 = p2; } if(thing->type == SYMMETRIC){ for(i = thing->n - 2; i > 0; i--){ xx = lx * thing->x[i]; yy = - ly * thing->y[i]; x2 = (float) lpx * thing->x[i]; y2 = (float) lpy * thing->y[i]; xp = (int) (xx*ca - yy*sa + xlead); yp = (int) (xx*sa + yy*ca + ylead); xphys = (float) (x2*ca - y2*sa + x1); yphys = (float) (-x2*sa - y2*ca + y1); p2 = add_pnt(xphys, yphys); add_seg(p1, p2, g); p1 = p2; } } add_seg(p1, p0, g); state = HAVE_BOUNDARY; redisplay(w, xx, yy, data); SetButtonDownCB(drawWindow, nacaDown); SetMouseMotionCB(drawWindow, nacaMotion); } } void drawNaca(int x1, int y1, int x2, int y2) { double l, lx, ly, ca, sa; int xx1, yy1, xx2, yy2; int x, y; int i; x1++; y1++; x2--; y2--; if(thing->drawmode == TO_SCALE){ l = sqrt((double) (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); l = l / maxsize(0); lx = l; ly = l; ca = (double) (x2-x1) / l; sa = (double) (y2-y1) / l; } else{ ca = 1.; sa = 0.; lx = (double) (x2 -x1)/maxsize(0); ly = (double) (y2 -y1)/maxsize(1); } x = (int) lx * thing->x[0] ; y = (int) ly * thing->y[0] ; xx1 = (int) (x*ca - y*sa + x1); yy1 = (int) (x*sa + y*ca + y1); for(i = 0; i < thing->n; i++){ x = (int) lx * thing->x[i]; y = (int) ly * thing->y[i]; xx2 = (int) (x*ca - y*sa + x1); yy2 = (int) (x*sa + y*ca + y1); myDrawLine(xx1, yy1, xx2, yy2); xx1 = xx2; yy1 = yy2; } if(thing->type == SYMMETRIC){ x = (int) lx * thing->x[0] ; y = - (int) ly * thing->y[0] ; xx1 = (int) (x*ca - y*sa + x1); yy1 = (int) (x*sa + y*ca + y1); for(i = 0; i < thing->n; i++){ x = (int) lx * thing->x[i]; y = - (int) ly * thing->y[i]; xx2 = (int) (x*ca - y*sa + x1); yy2 = (int) (x*sa + y*ca + y1); myDrawLine(xx1, yy1, xx2, yy2); xx1 = xx2; yy1 = yy2; } } else{ x = (int) lx * thing->x[0]; y = (int) ly * thing->y[0]; xx2 = (int) (x*ca - y*sa + x1); yy2 = (int) (x*sa + y*ca + y1); myDrawLine(xx1, yy1, xx2, yy2); } } void killMouseDown(Widget w, int button, int x, int y, void *data) { int n; int ioff; int segment, this; GEO_NODE *g; g = new_clickedOnBoundary(x, y); if(g != NULL){ rm_bnd(g); if(number_of_boundaries() == 0) state = HAVE_SCALE; redisplay(w, x, y, data); } } void killBoundary() { first = 0; setAction(DELETING); SetButtonUpCB(drawWindow, NULL); SetButtonDownCB(drawWindow, killMouseDown); SetMouseMotionCB(drawWindow, nacaMotion); }