PlotWindow.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. #include "PlotWindow.h"
  2. PlotWindow::PlotWindow(int w, int h, GBCSolution* Gsln, GBCSolution* GMEM1, GBCSolution* GMEM2) : Fl_Window(w,h,"Solution Visualization Tools"){
  3. // Store a pointer to the calling solution.
  4. gsln=Gsln;
  5. mem1=GMEM1;
  6. mem2=GMEM2;
  7. x_click=0;
  8. y_click=0;
  9. begin();
  10. this->size_range(0,0,1600,1600);
  11. // Put a simple menu, for saving or closing the window.
  12. menu = new Fl_Menu_Bar(0,0,w,25,"MENU");
  13. Fl_Menu_Item items[]= {
  14. {"&File",0,0,0,FL_SUBMENU},
  15. {"Save as..",0,0,0,FL_SUBMENU | FL_MENU_INACTIVE},
  16. {"PNG (.png)",0,(Fl_Callback*)cb_nothing,this,0},
  17. {"JPEG (.jpg)",0,(Fl_Callback*)cb_nothing,this,0},
  18. {"Bitmap (.bmp)",0,(Fl_Callback*)cb_nothing,this,0},
  19. {"Adobe PDF (.pdf)",0,(Fl_Callback*)cb_nothing,this,0},
  20. {0},
  21. {"&Close",0,(Fl_Callback*)cb_Close,this,0},
  22. {0},
  23. {0}
  24. };
  25. menu->copy(items);
  26. menu->down_box(FL_NO_BOX);
  27. // Put in a range slider for selecting the chart's range.
  28. sl_x = new Fl_Value_Slider(150,40,350,30,"Range (yds)");
  29. sl_x->align(FL_ALIGN_RIGHT);
  30. sl_x->value(200);
  31. sl_x->minimum(200);
  32. sl_x->maximum(gsln->MaxRows());
  33. sl_x->type(FL_HOR_NICE_SLIDER);
  34. sl_x->callback(cb_slUpdate,this);
  35. sl_x->precision(0);
  36. sl_x->step(10);
  37. //Fl_Button* btPlot = new Fl_Button(600,40,70,30,"UPDATE");
  38. //btPlot->callback(cb_btPlot,this);
  39. btMem1 = new Fl_Check_Button(590,30,20,20,"Memory 1");
  40. btMem2 = new Fl_Check_Button(590,50,20,20,"Memory 2");
  41. btMem1->align(FL_ALIGN_RIGHT);
  42. btMem2->align(FL_ALIGN_RIGHT);
  43. btMem1->labelcolor(FL_RED);
  44. btMem2->labelcolor(FL_DARK_GREEN);
  45. btMem1->callback(cb_Mem1,this);
  46. btMem2->callback(cb_Mem2,this);
  47. if (mem1==NULL) btMem1->deactivate();
  48. if (mem2==NULL) btMem2->deactivate();
  49. if (mem1!=NULL) btMem1->tooltip(mem1->Name());
  50. if (mem2!=NULL) btMem2->tooltip(mem2->Name());
  51. rbPlotPath = new Fl_Round_Button(20,30,30,20,"Path (inches)");
  52. rbPlotVelocity = new Fl_Round_Button(20,50,30,20,"Velocity");
  53. rbPlotEnergy = new Fl_Round_Button(20,70,30,20,"Energy");
  54. rbPlotPath->type(FL_RADIO_BUTTON);
  55. rbPlotVelocity->type(FL_RADIO_BUTTON);
  56. rbPlotEnergy->type(FL_RADIO_BUTTON);
  57. rbPlotPath->callback(cb_btPlot,this);
  58. rbPlotVelocity->callback(cb_btPlot,this);
  59. rbPlotEnergy->callback(cb_btPlot,this);
  60. rbPlotPath->value(1);
  61. rbPlotPath->align(FL_ALIGN_RIGHT);
  62. rbPlotVelocity->align(FL_ALIGN_RIGHT);
  63. rbPlotEnergy->align(FL_ALIGN_RIGHT);
  64. end();
  65. show();
  66. }
  67. PlotWindow::~PlotWindow(void){
  68. delete menu;
  69. delete sl_x;
  70. delete rbPlotPath;
  71. delete rbPlotVelocity;
  72. delete rbPlotEnergy;
  73. delete btMem1;
  74. delete btMem2;
  75. }
  76. void PlotWindow::draw(void){
  77. // Let the window draw itself first.
  78. Fl_Window::draw();
  79. if (rbPlotPath->value()==1) PlotPath();
  80. else if (rbPlotEnergy->value()==1) PlotEnergy();
  81. else if (rbPlotVelocity->value()==1) PlotVelocity();
  82. }
  83. int PlotWindow::handle(int evt){
  84. if (evt==FL_PUSH && Fl::event_button1()){
  85. x_click=Fl::event_x();
  86. y_click=Fl::event_y();
  87. this->redraw();
  88. }
  89. return Fl_Window::handle(evt);
  90. }
  91. void PlotWindow::PlotPath(void){
  92. int w = this->w();
  93. int h = this->h();
  94. int xmin = 5;
  95. int xmax = w-5;
  96. int ymin = 100;
  97. int ymax = h-5;
  98. int y0 = (ymax-ymin)/2 + ymin;
  99. // The gridlines look best with 15-25 graduations in x, so we set some basic defaults here.
  100. x_ticks=25;
  101. if (sl_x->value() > 500) x_ticks=50;
  102. if (sl_x->value() > 1000) x_ticks=100;
  103. if (sl_x->value() > 2000) x_ticks=250;
  104. if (sl_x->value() > 4000) x_ticks=500;
  105. // We need to find the max and min y-values to determine our y scale and y-ticks
  106. double _miny=0;
  107. double _maxy=0;
  108. for (int e=0;e<sl_x->value();e++){
  109. if (gsln->GetPath(e) > _maxy) _maxy=gsln->GetPath(e);
  110. if (gsln->GetPath(e) < _miny) _miny=gsln->GetPath(e);
  111. }
  112. int x_range=(int)sl_x->value();
  113. double y_range=0;
  114. if (fabs(_miny) > fabs(_maxy)) y_range = fabs(2.5*_miny);
  115. else y_range = fabs(2.5*_maxy);
  116. double x_scale = (double)(xmax-xmin) / (double)x_range;
  117. double y_scale = (double)(ymax-ymin) / (double)y_range;
  118. // Now do our custom drawing.
  119. fl_draw_box(FL_FLAT_BOX,xmin,ymin,w-10,h-ymin-5,FL_WHITE);
  120. // Draw the x-axis.
  121. fl_color(FL_BLACK);
  122. fl_line_style(FL_SOLID,2);
  123. fl_line(xmin,y0,xmax,y0);
  124. // The y-axis looks best with about 7-12 ticks, so we scale it here reasonably.
  125. y_ticks=1;
  126. if (y_range > 10) y_ticks=2;
  127. if (y_range > 20) y_ticks=6;
  128. if (y_range > 40) y_ticks=12;
  129. if (y_range > 80) y_ticks=24;
  130. if (y_range > 200) y_ticks=48;
  131. if (y_range > 400) y_ticks=100;
  132. if (y_range > 800) y_ticks=250;
  133. if (y_range > 1600) y_ticks=500;
  134. double px;
  135. fl_color(FL_BLACK);
  136. fl_line_style(FL_SOLID,1);
  137. char txt[64];
  138. int r=0;
  139. double txtw=0;
  140. // Draw X gridlines every x_ticks yds and label them.
  141. for (px=xmin;px<xmax;px+=((double)x_ticks*x_scale)){
  142. //fl_line((int)px,y_bottom,(int)px,y_top);
  143. fl_line_style(FL_DOT,1);
  144. fl_line((int)px,(int)ymin,(int)px,(int)ymax);
  145. sprintf(txt,"%d",r*x_ticks);
  146. if (r%2==0 && r>0) {
  147. txtw=fl_width(txt);
  148. fl_line_style(FL_SOLID,1);
  149. fl_line((int)px,y0,(int)px,y0+8);
  150. fl_draw(txt,(int)((int)px-(txtw/2)),y0+10+fl_height());
  151. }
  152. r++;
  153. }
  154. // Draw Y hashmarks every 1 y_tick going up.
  155. double py;
  156. r=0;
  157. for (py=y0;py>=ymin;py-=((double)y_ticks*y_scale)){
  158. if (r>0){
  159. fl_line(xmin,(int)py,xmax,(int)py);
  160. sprintf(txt,"+%d\"",r*y_ticks);
  161. fl_draw(txt,xmin+10,(int)(py+fl_height()/2));
  162. }
  163. r++;
  164. }
  165. // Draw Y hashmarks every 1 y_tick going down
  166. r=0;
  167. for (py=y0;py<=ymax;py+=((double)y_ticks*y_scale)){
  168. if (r>0){
  169. fl_line(xmin,(int)py,xmax,(int)py);
  170. sprintf(txt,"-%d\"",r*y_ticks);
  171. if (py+fl_height()/2<ymax) fl_draw(txt,xmin+10,(int)(py+fl_height()/2));
  172. }
  173. r++;
  174. }
  175. int x1,x2;
  176. double y1,y2;
  177. // For the pixel locations to plot.
  178. int px1, px2, py1,py2;
  179. x1=(int)this->gsln->GetRange(0);
  180. y1=this->gsln->GetPath(0);
  181. int m=this->gsln->MaxRows();
  182. fl_color(FL_BLUE);
  183. fl_line_style(FL_SOLID,1);
  184. for (int n=1;n<x_range && n<m ;n++){
  185. x2=(int)this->gsln->GetRange(n);
  186. y2=this->gsln->GetPath(n);
  187. // Translate the x,y values into scaled pixels.
  188. px1=(int)(xmin+x_scale*(double)x1);
  189. px2=(int)(xmin+x_scale*(double)x2);
  190. py1=(int)((y0)-(double)y_scale*(double)y1);
  191. py2=(int)((y0)-(double)y_scale*(double)y2);
  192. if (py2>=ymax) break;
  193. if (px2>=xmax) break;
  194. // Plot the points.
  195. fl_line(px1,py1,px2,py2);
  196. x1=x2;
  197. y1=y2;
  198. }
  199. if (btMem1->value()==1){
  200. x1=(int)this->mem1->GetRange(0);
  201. y1=this->mem1->GetPath(0);
  202. int m=this->gsln->MaxRows();
  203. fl_color(FL_RED);
  204. fl_line_style(FL_SOLID,1);
  205. for (int n=1;n<x_range && n<m ;n++){
  206. x2=(int)this->mem1->GetRange(n);
  207. y2=this->mem1->GetPath(n);
  208. // Translate the x,y values into scaled pixels.
  209. px1=(int)(xmin+x_scale*(double)x1);
  210. px2=(int)(xmin+x_scale*(double)x2);
  211. py1=(int)((y0)-(double)y_scale*(double)y1);
  212. py2=(int)((y0)-(double)y_scale*(double)y2);
  213. if (py2>=ymax) break;
  214. if (px2>=xmax) break;
  215. // Plot the points.
  216. if (px1>xmin && px1<xmax && py1<ymax && py1>ymin)
  217. fl_line(px1,py1,px2,py2);
  218. x1=x2;
  219. y1=y2;
  220. }
  221. }
  222. if (btMem2->value()==1){
  223. x1=(int)this->mem2->GetRange(0);
  224. y1=this->mem2->GetPath(0);
  225. int m=this->gsln->MaxRows();
  226. fl_color(FL_GREEN);
  227. fl_line_style(FL_SOLID,1);
  228. for (int n=1;n<x_range && n<m ;n++){
  229. x2=(int)this->mem2->GetRange(n);
  230. y2=this->mem2->GetPath(n);
  231. // Translate the x,y values into scaled pixels.
  232. px1=(int)(xmin+x_scale*(double)x1);
  233. px2=(int)(xmin+x_scale*(double)x2);
  234. py1=(int)((y0)-(double)y_scale*(double)y1);
  235. py2=(int)((y0)-(double)y_scale*(double)y2);
  236. if (py2>=ymax) break;
  237. if (px2>=xmax) break;
  238. // Plot the points.
  239. if (px1>xmin && px1<xmax && py1<ymax && py1>ymin)
  240. fl_line(px1,py1,px2,py2);
  241. x1=x2;
  242. y1=y2;
  243. }
  244. }
  245. if (x_click>xmin && x_click<xmax && y_click>ymin && y_click<ymax){
  246. // If the user clicks, show the coordinates they clicked on.
  247. double click_label_x= (x_click-xmin)/x_scale;
  248. double click_label_y=(y0-y_click)/y_scale;
  249. char lbl_point[20];
  250. sprintf(lbl_point,"(%.0f,%.2f)",click_label_x, click_label_y);
  251. fl_color(FL_BLACK);
  252. fl_draw(lbl_point,x_click+5, y_click-5);
  253. fl_rectf(x_click-2, y_click-2,4,4);
  254. }
  255. // Draw the frame around it last to make it all pretty.
  256. fl_frame("aaaa",5,100,w-10,h-105);
  257. return;
  258. }
  259. void PlotWindow::PlotEnergy(void){
  260. int w = this->w();
  261. int h = this->h();
  262. int xmin = 5;
  263. int xmax = w-5;
  264. int ymin = 100;
  265. int ymax = h-5;
  266. int y0 = (ymax)-50;
  267. // The gridlines look best with 15-25 graduations in x, so we set some basic defaults here.
  268. x_ticks=25;
  269. if (sl_x->value() > 500) x_ticks=50;
  270. if (sl_x->value() > 1000) x_ticks=100;
  271. if (sl_x->value() > 2000) x_ticks=250;
  272. if (sl_x->value() > 4000) x_ticks=500;
  273. // We need to find the max y-value to determine our y scale and y-ticks
  274. double _maxy=0;
  275. double _miny=0;
  276. for (int e=1;e<sl_x->value();e++){
  277. if (gsln->GetPath(e) > _maxy) _maxy=gsln->GetEnergy(e);
  278. }
  279. int x_range=(int)sl_x->value();
  280. double y_range=0;
  281. if (fabs(_miny) > fabs(_maxy)) y_range = fabs(1.5*_miny);
  282. else y_range = fabs(1.5*_maxy);
  283. double x_scale = (double)(xmax-xmin) / (double)x_range;
  284. double y_scale = (double)(ymax-ymin) / (double)y_range;
  285. // Now do our custom drawing.
  286. fl_draw_box(FL_FLAT_BOX,xmin,ymin,w-10,h-ymin-5,FL_WHITE);
  287. // Draw the x-axis.
  288. fl_color(FL_BLACK);
  289. fl_line_style(FL_SOLID,2);
  290. fl_line(xmin,y0,xmax,y0);
  291. // The y-axis looks best with about 7-12 ticks, so we scale it here reasonably.
  292. y_ticks=1;
  293. if (y_range > 10) y_ticks=2;
  294. if (y_range > 20) y_ticks=6;
  295. if (y_range > 40) y_ticks=12;
  296. if (y_range > 80) y_ticks=24;
  297. if (y_range > 200) y_ticks=48;
  298. if (y_range > 400) y_ticks=100;
  299. if (y_range > 800) y_ticks=250;
  300. if (y_range > 1600) y_ticks=500;
  301. double px;
  302. fl_color(FL_BLACK);
  303. fl_line_style(FL_SOLID,1);
  304. char txt[64];
  305. int r=0;
  306. double txtw=0;
  307. // Draw X gridlines every x_ticks yds and label them.
  308. for (px=xmin;px<xmax;px+=((double)x_ticks*x_scale)){
  309. //fl_line((int)px,y_bottom,(int)px,y_top);
  310. fl_line_style(FL_DOT,1);
  311. fl_line((int)px,(int)ymin,(int)px,(int)y0);
  312. sprintf(txt,"%d",r*x_ticks);
  313. if (r%2==0 && r>0) {
  314. txtw=fl_width(txt);
  315. fl_line_style(FL_SOLID,1);
  316. fl_line((int)px,y0,(int)px,y0+8);
  317. fl_draw(txt,(int)((int)px-(txtw/2)),y0+10+fl_height());
  318. }
  319. r++;
  320. }
  321. // Draw Y hashmarks every 1 y_tick going up.
  322. double py;
  323. r=0;
  324. for (py=y0;py>=ymin;py-=((double)y_ticks*y_scale)){
  325. if (r>0){
  326. fl_line(xmin,(int)py,xmax,(int)py);
  327. sprintf(txt,"+%d ft-lb",r*y_ticks);
  328. fl_draw(txt,xmin+10,(int)(py+fl_height()/2));
  329. }
  330. r++;
  331. }
  332. int x1,x2;
  333. double y1,y2;
  334. // For the pixel locations to plot.
  335. int px1, px2, py1,py2;
  336. x1=(int)this->gsln->GetRange(0);
  337. y1=this->gsln->GetEnergy(0);
  338. int m=this->gsln->MaxRows();
  339. fl_color(FL_BLUE);
  340. fl_line_style(FL_SOLID,1);
  341. for (int n=1;n<x_range && n<m ;n++){
  342. x2=(int)this->gsln->GetRange(n);
  343. y2=this->gsln->GetEnergy(n);
  344. // Translate the x,y values into scaled pixels.
  345. px1=(int)(xmin+x_scale*(double)x1);
  346. px2=(int)(xmin+x_scale*(double)x2);
  347. py1=(int)((y0)-(double)y_scale*(double)y1);
  348. py2=(int)((y0)-(double)y_scale*(double)y2);
  349. if (py2>=ymax) break;
  350. if (px2>=xmax) break;
  351. // Plot the points.
  352. fl_line(px1,py1,px2,py2);
  353. x1=x2;
  354. y1=y2;
  355. }
  356. if (btMem1->value()==1){
  357. x1=(int)this->mem1->GetRange(0);
  358. y1=this->mem1->GetEnergy(0);
  359. int m=this->mem1->MaxRows();
  360. fl_color(FL_RED);
  361. fl_line_style(FL_SOLID,1);
  362. for (int n=1;n<x_range && n<m ;n++){
  363. x2=(int)this->mem1->GetRange(n);
  364. y2=this->mem1->GetEnergy(n);
  365. // Translate the x,y values into scaled pixels.
  366. px1=(int)(xmin+x_scale*(double)x1);
  367. px2=(int)(xmin+x_scale*(double)x2);
  368. py1=(int)((y0)-(double)y_scale*(double)y1);
  369. py2=(int)((y0)-(double)y_scale*(double)y2);
  370. if (py2>=ymax) break;
  371. if (px2>=xmax) break;
  372. // Plot the points.
  373. if (px1>xmin && px1<xmax && py1<ymax && py1>ymin) fl_line(px1,py1,px2,py2);
  374. x1=x2;
  375. y1=y2;
  376. }
  377. }
  378. if (btMem2->value()==1){
  379. x1=(int)this->mem2->GetRange(0);
  380. y1=this->mem2->GetEnergy(0);
  381. int m=this->mem2->MaxRows();
  382. fl_color(FL_GREEN);
  383. fl_line_style(FL_SOLID,1);
  384. for (int n=1;n<x_range && n<m ;n++){
  385. x2=(int)this->mem2->GetRange(n);
  386. y2=this->mem2->GetEnergy(n);
  387. // Translate the x,y values into scaled pixels.
  388. px1=(int)(xmin+x_scale*(double)x1);
  389. px2=(int)(xmin+x_scale*(double)x2);
  390. py1=(int)((y0)-(double)y_scale*(double)y1);
  391. py2=(int)((y0)-(double)y_scale*(double)y2);
  392. if (py2>=ymax) break;
  393. if (px2>=xmax) break;
  394. // Plot the points.
  395. if (px1>xmin && px1<xmax && py1<ymax && py1>ymin) fl_line(px1,py1,px2,py2);
  396. x1=x2;
  397. y1=y2;
  398. }
  399. }
  400. if (x_click>xmin && x_click<xmax && y_click>ymin && y_click<ymax){
  401. // If the user clicks, show the coordinates they clicked on.
  402. double click_label_x= (x_click-xmin)/x_scale;
  403. double click_label_y=(y0-y_click)/y_scale;
  404. char lbl_point[20];
  405. sprintf(lbl_point,"(%.0f,%.2f)",click_label_x, click_label_y);
  406. fl_color(FL_BLACK);
  407. fl_draw(lbl_point,x_click+5, y_click-5);
  408. fl_rectf(x_click-2, y_click-2,4,4);
  409. }
  410. // Draw the frame around it last to make it all pretty.
  411. fl_frame("aaaa",5,100,w-10,h-105);
  412. return;
  413. }
  414. void PlotWindow::PlotVelocity(void){
  415. int w = this->w();
  416. int h = this->h();
  417. int xmin = 5;
  418. int xmax = w-5;
  419. int ymin = 100;
  420. int ymax = h-5;
  421. int y0 = (ymax)-50;
  422. // The gridlines look best with 15-25 graduations in x, so we set some basic defaults here.
  423. x_ticks=25;
  424. if (sl_x->value() > 500) x_ticks=50;
  425. if (sl_x->value() > 1000) x_ticks=100;
  426. if (sl_x->value() > 2000) x_ticks=250;
  427. if (sl_x->value() > 4000) x_ticks=500;
  428. // We need to find the max y-value to determine our y scale and y-ticks
  429. double _maxy=0;
  430. double _miny=0;
  431. for (int e=1;e<sl_x->value();e++){
  432. if (gsln->GetPath(e) > _maxy) _maxy=gsln->GetVelocity(e);
  433. }
  434. int x_range=(int)sl_x->value();
  435. double y_range=0;
  436. if (fabs(_miny) > fabs(_maxy)) y_range = fabs(1.5*_miny);
  437. else y_range = fabs(1.5*_maxy);
  438. double x_scale = (double)(xmax-xmin) / (double)x_range;
  439. double y_scale = (double)(ymax-ymin) / (double)y_range;
  440. // Now do our custom drawing.
  441. fl_draw_box(FL_FLAT_BOX,xmin,ymin,w-10,h-ymin-5,FL_WHITE);
  442. // Draw the x-axis.
  443. fl_color(FL_BLACK);
  444. fl_line_style(FL_SOLID,2);
  445. fl_line(xmin,y0,xmax,y0);
  446. // The y-axis looks best with about 7-12 ticks, so we scale it here reasonably.
  447. y_ticks=1;
  448. if (y_range > 10) y_ticks=2;
  449. if (y_range > 20) y_ticks=6;
  450. if (y_range > 40) y_ticks=12;
  451. if (y_range > 80) y_ticks=24;
  452. if (y_range > 200) y_ticks=48;
  453. if (y_range > 400) y_ticks=100;
  454. if (y_range > 800) y_ticks=250;
  455. if (y_range > 1600) y_ticks=500;
  456. double px;
  457. fl_color(FL_BLACK);
  458. fl_line_style(FL_SOLID,1);
  459. char txt[64];
  460. int r=0;
  461. double txtw=0;
  462. // Draw X gridlines every x_ticks yds and label them.
  463. for (px=xmin;px<xmax;px+=((double)x_ticks*x_scale)){
  464. //fl_line((int)px,y_bottom,(int)px,y_top);
  465. fl_line_style(FL_DOT,1);
  466. fl_line((int)px,(int)ymin,(int)px,(int)y0);
  467. sprintf(txt,"%d",r*x_ticks);
  468. if (r%2==0 && r>0) {
  469. txtw=fl_width(txt);
  470. fl_line_style(FL_SOLID,1);
  471. fl_line((int)px,y0,(int)px,y0+8);
  472. fl_draw(txt,(int)((int)px-(txtw/2)),y0+10+fl_height());
  473. }
  474. r++;
  475. }
  476. // Draw Y hashmarks every 1 y_tick going up.
  477. double py;
  478. r=0;
  479. for (py=y0;py>=ymin;py-=((double)y_ticks*y_scale)){
  480. if (r>0){
  481. fl_line(xmin,(int)py,xmax,(int)py);
  482. sprintf(txt,"+%d ft/s",r*y_ticks);
  483. fl_draw(txt,xmin+10,(int)(py+fl_height()/2));
  484. }
  485. r++;
  486. }
  487. int x1,x2;
  488. double y1,y2;
  489. // For the pixel locations to plot.
  490. int px1, px2, py1,py2;
  491. x1=(int)this->gsln->GetRange(0);
  492. y1=this->gsln->GetVelocity(0);
  493. int m=this->gsln->MaxRows();
  494. fl_color(FL_BLUE);
  495. fl_line_style(FL_SOLID,1);
  496. for (int n=1;n<x_range && n<m ;n++){
  497. x2=(int)this->gsln->GetRange(n);
  498. y2=this->gsln->GetVelocity(n);
  499. // Translate the x,y values into scaled pixels.
  500. px1=(int)(xmin+x_scale*(double)x1);
  501. px2=(int)(xmin+x_scale*(double)x2);
  502. py1=(int)((y0)-(double)y_scale*(double)y1);
  503. py2=(int)((y0)-(double)y_scale*(double)y2);
  504. if (py2>=ymax) break;
  505. if (px2>=xmax) break;
  506. // Plot the points.
  507. fl_line(px1,py1,px2,py2);
  508. x1=x2;
  509. y1=y2;
  510. }
  511. if (btMem1->value()==1){
  512. x1=(int)this->mem1->GetRange(0);
  513. y1=this->mem1->GetVelocity(0);
  514. int m=this->mem1->MaxRows();
  515. fl_color(FL_RED);
  516. fl_line_style(FL_SOLID,1);
  517. for (int n=1;n<x_range && n<m ;n++){
  518. x2=(int)this->mem1->GetRange(n);
  519. y2=this->mem1->GetVelocity(n);
  520. // Translate the x,y values into scaled pixels.
  521. px1=(int)(xmin+x_scale*(double)x1);
  522. px2=(int)(xmin+x_scale*(double)x2);
  523. py1=(int)((y0)-(double)y_scale*(double)y1);
  524. py2=(int)((y0)-(double)y_scale*(double)y2);
  525. if (py2>=ymax) break;
  526. if (px2>=xmax) break;
  527. // Plot the points.
  528. if (px1>xmin && px1<xmax && py1<ymax && py1>ymin) fl_line(px1,py1,px2,py2);
  529. x1=x2;
  530. y1=y2;
  531. }
  532. }
  533. if (btMem2->value()==1){
  534. x1=(int)this->mem2->GetRange(0);
  535. y1=this->mem2->GetVelocity(0);
  536. int m=this->mem2->MaxRows();
  537. fl_color(FL_GREEN);
  538. fl_line_style(FL_SOLID,1);
  539. for (int n=1;n<x_range && n<m ;n++){
  540. x2=(int)this->mem2->GetRange(n);
  541. y2=this->mem2->GetVelocity(n);
  542. // Translate the x,y values into scaled pixels.
  543. px1=(int)(xmin+x_scale*(double)x1);
  544. px2=(int)(xmin+x_scale*(double)x2);
  545. py1=(int)((y0)-(double)y_scale*(double)y1);
  546. py2=(int)((y0)-(double)y_scale*(double)y2);
  547. if (py2>=ymax) break;
  548. if (px2>=xmax) break;
  549. // Plot the points.
  550. if (px1>xmin && px1<xmax && py1<ymax && py1>ymin) fl_line(px1,py1,px2,py2);
  551. x1=x2;
  552. y1=y2;
  553. }
  554. }
  555. if (x_click>xmin && x_click<xmax && y_click>ymin && y_click<ymax){
  556. // If the user clicks, show the coordinates they clicked on.
  557. double click_label_x= (x_click-xmin)/x_scale;
  558. double click_label_y=(y0-y_click)/y_scale;
  559. char lbl_point[20];
  560. sprintf(lbl_point,"(%.0f,%.2f)",click_label_x, click_label_y);
  561. fl_color(FL_BLACK);
  562. fl_draw(lbl_point,x_click+5, y_click-5);
  563. fl_rectf(x_click-2, y_click-2,4,4);
  564. }
  565. // Draw the frame around it last to make it all pretty.
  566. fl_frame("aaaa",5,100,w-10,h-105);
  567. return;
  568. }
  569. void PlotWindow::cb_btPlot(Fl_Widget* o, void* v){
  570. PlotWindow* T = (PlotWindow*)v;
  571. T->damage(255);
  572. T->draw();
  573. }
  574. void PlotWindow::cb_nothing(Fl_Widget* o, void* v){
  575. ;
  576. }
  577. void PlotWindow::cb_Close(Fl_Widget* o, void* v){
  578. PlotWindow* T = (PlotWindow*)v;
  579. T->~PlotWindow();
  580. }
  581. void PlotWindow::cb_slUpdate(Fl_Widget* o, void* v){
  582. PlotWindow* T = (PlotWindow*)v;
  583. T->damage(255);
  584. T->draw();
  585. }
  586. void PlotWindow::cb_Mem1(Fl_Widget* o, void* v){
  587. PlotWindow* T = (PlotWindow*)v;
  588. T->damage(255);
  589. T->draw();
  590. }
  591. void PlotWindow::cb_Mem2(Fl_Widget* o, void* v){
  592. PlotWindow* T = (PlotWindow*)v;
  593. T->redraw();
  594. }