Compare commits

...

2 Commits

  1. 88
      ChangeLog
  2. 9
      GBCSolution.cpp
  3. 1
      GBCSolution.h
  4. 5
      GNU_Ballistics.cpp
  5. 195
      InputWindow.cpp
  6. 8
      InputWindow.h
  7. 2
      Makefile.am
  8. 1005
      PlotWindow.cpp
  9. 29
      PlotWindow.h
  10. 605
      RangeWindow.cpp
  11. 13
      RangeWindow.h
  12. 723
      TargetWindow.cpp
  13. 80
      TargetWindow.h
  14. 10
      lib/ballistics/ballistics.cpp
  15. 1
      lib/ballistics/ballistics.h

88
ChangeLog

@ -0,0 +1,88 @@ @@ -0,0 +1,88 @@
Jan 2011 mnix@wanm.com.au
* Added TargetWindow - view of target as seen from shooter.
* Added a perspective checkbox to the target window. This switches
between path as seen by shooter (on) and path relative to line of
sight (off). For example, a bullet 1/2 way to the target will
line up with a point twice as far above line of sight in the target
as it actually is. ie if the bullet is 1" above line of sight at 50
yds, it will be in line with a point 2" above line of sight on a
target at 100 yds. The line appears to move on the target because as
you move the target back (say to 200 yds) the bullet at 50 yds and
1" high will line up with a point 4" high on the target at 200 yds.
* If a file name is given on the command line it is loaded at startup.
No checking is done on the file name - if it does not exist,
bad things may happen.
* Added various target types including common NRA and ISSF targets
* Added a "variance" ring around the impact point. This is 1 MOA plus
a bit on the sides as alowance for spin drift (it's added to both
sides and left to the viewer to decide on whether to allow for left
or right twist. The amount is so small it doesn't matter much
anyway (we allow a generic 0.1 MOA per 100 yards beyond 100 yards)
Nov 2010 mnix#wanm.com.au
* Added a drop down box to the Plot Window to select scope guides.
* Changed the calculations for the scope guides to draw them more
accurately.
* Get Zero to float in the path plot
* Clip the scope guides
* Added an option for guides every 1 degree
Oct 2010 mnix@wanm.com.au
* Added scope guides to the path plot as a ready reference to how the
trajectory compares to the field of view of the scope, in particular to
one and 5 MIL marks on a MIL-DOT reticle. Included code for MOA
as well, but commented it out pending GUI button to select
MIL/MOA/NONE
* Modified InputWindow and PlotWindow to handle plotting memory 3
* Consolidated a lot of code in PlotWindow into 3 new functions.
* modified InputWindow::cb_Solve() to treat zero ranges < 2 yards as a
zeroangle and report the zeroangle used in the output window.
This allows plotting the paths of different loads shot from the one
barrel and scope alignment (eg for a two different loads in a .308
without adjusting the scope, what is the elevation adjustment for
each load?) Useful for hunters who might select different loads for
different targets, but do not want to mess with their zero.
* Allowed for larger y_range in plots.
* Reduced the minimum range in the PlotWindow to 50 yds (default still
200). Useful for low power (ie .22) shooters.
* Added Drop (MIL), Windage (MIL) and Target Size (MIL) columns to the
RangeWindow (not all export formats have been updated yet).
All useful for users of MIL-DOT reticles.
Need to add a GUI box for entering the target size in inches - that
way you can enter the size in inches of whatever you intend to shoot,
then in the field measure your target in MIL in the scope, look that up
on the range table and instantly get bullet drop and windage in MIL,
no maths required.
* Added metric conversions of the summary data at the top of the range
table.
* Cleaned up SOME of the misuse of malloc/delete/free
delete calls the destructor then frees the memory. Calling free on
an object after deleting it is an error, so is calling delete after
calling the destructor!
Also mixing new/free and malloc/delete on the same object is bad.
Only use malloc with free, and only new with delete.
* Re-wrote the GenTable and Export* code in RangeWindow to be data-driven.
Adding a column, or modifying the layout of the load data is now
done in one place and automatically appears in ALL output formats.

9
GBCSolution.cpp

@ -32,6 +32,7 @@ GBCSolution::~GBCSolution(){ @@ -32,6 +32,7 @@ GBCSolution::~GBCSolution(){
if (this->sln != NULL) {
free(this->sln);
this->sln=NULL;
}
}
@ -158,6 +159,14 @@ double GBCSolution::GetVy(int yardage){ @@ -158,6 +159,14 @@ double GBCSolution::GetVy(int yardage){
}
else return 0;
}
double GBCSolution::GetDrop(int yardage){
double size=sln[__BCOMP_MAXRANGE__*10+1];
if (yardage<size){
return sln[10*yardage+9];
}
else return 0;
}
double GBCSolution::GetEnergy(int k){
return (double)weight*GetVelocity(k)*GetVelocity(k)/450436;

1
GBCSolution.h

@ -58,6 +58,7 @@ class GBCSolution { @@ -58,6 +58,7 @@ class GBCSolution {
double GetVelocity(int yardage);
double GetVx(int yardage);
double GetVy(int yardage);
double GetDrop(int yardage);
double GetEnergy(int yardage);
int df;

5
GNU_Ballistics.cpp

@ -2,8 +2,11 @@ @@ -2,8 +2,11 @@
#include <FL/Fl_Window.H>
#include "InputWindow.h"
using namespace std;
int main (){
int main (int argc, char *argv[]){
InputWindow win(400,500,"GNU Exterior Ballistics Computer");
if (argc==2) {
win.OpenFile(argv[1]);
}
return Fl::run();
}

195
InputWindow.cpp

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
#include "lib/ballistics/ballistics.h"
#include "InputWindow.h"
#include "TargetWindow.h"
InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
@ -61,7 +61,7 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){ @@ -61,7 +61,7 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
inBC = new Fl_Float_Input(10,80,50,20," Drag Coefficient");
inWeight=new Fl_Int_Input(10,105,50,20," Projectile Weight (grains)");
inMV = new Fl_Int_Input(10,130,50,20," Initial Velocity (ft/s)");
inZero = new Fl_Int_Input(10,155,50,20," Zero Range (yds)");
inZero = new Fl_Float_Input(10,155,50,20," Zero Range (yds)");
inSH = new Fl_Float_Input(10,180,50,20," Sight Height Over Bore (in)");
inAngle = new Fl_Int_Input(10,205,50,20," Shooting Angle (deg)");
inVwind = new Fl_Int_Input(10,230,50,20," Wind Velocity (mi/hr)");
@ -146,6 +146,7 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){ @@ -146,6 +146,7 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
Fl_Menu_Item m_Analysis = {"&Analysis",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_RangeTable = {"&Range Table",0,(Fl_Callback*)cb_RangeTable,this};
Fl_Menu_Item mc_QuickPlot = {"Quick &Plot",0,(Fl_Callback*)cb_Plot, this};
Fl_Menu_Item mc_TargetPlot= {"&Target Plot",0,(Fl_Callback*)cb_Target, this};
Fl_Menu_Item mc_RangeCard = {"&Range Card",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_ClickChart = {"&Click Chart",0,(Fl_Callback*)cb_Nothing,this,FL_MENU_DIVIDER};
Fl_Menu_Item mc_MVA = {"&Advanced Analysis",0,(Fl_Callback*)cb_Nothing,this};
@ -158,8 +159,8 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){ @@ -158,8 +159,8 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
Fl_Menu_Item m_Storage = {"&Solution Memory",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_Store1 = {"Store to Memory 1 ",0,(Fl_Callback*)cb_Store1,this};
Fl_Menu_Item mc_Store2 = {"Store to Memory 2 ",0,(Fl_Callback*)cb_Store2,this,FL_MENU_DIVIDER};
Fl_Menu_Item mc_Store3 = {"Store to Memory 3 ",0,(Fl_Callback*)cb_Store3,this};
Fl_Menu_Item mc_Store2 = {"Store to Memory 2 ",0,(Fl_Callback*)cb_Store2,this};
Fl_Menu_Item mc_Store3 = {"Store to Memory 3 ",0,(Fl_Callback*)cb_Store3,this,FL_MENU_DIVIDER};
Fl_Menu_Item mc_Store4 = {"Store to Memory 4 ",0,(Fl_Callback*)cb_Store4,this};
Fl_Menu_Item mc_Store5 = {"Store to Memory 5 ",0,(Fl_Callback*)cb_Store5,this};
Fl_Menu_Item mc_Store6 = {"Store to Memory 6 ",0,(Fl_Callback*)cb_Store6,this};
@ -192,7 +193,7 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){ @@ -192,7 +193,7 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
#define MANALYSIS 7
#define MSTORAGE 19
#define MSTORAGE 20
Fl_Menu_Item menuitems[] = {
m_File, //0
mc_New,
@ -204,18 +205,19 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){ @@ -204,18 +205,19 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
m_Analysis, //7
mc_RangeTable,
mc_QuickPlot,
mc_TargetPlot,
mc_RangeCard,
mc_ClickChart,
mc_MVA,
{0}, // 13
{0}, // 14
m_Tools,
mc_OptimizePBR,
mc_CalcBC,
mc_Options,
{0},
m_Storage,
mc_Store1, //20
mc_Store2, //21
mc_Store1, //21
mc_Store2, //22
mc_Store3,
mc_Store4,
mc_Store5,
@ -242,7 +244,7 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){ @@ -242,7 +244,7 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
InputWindow::~InputWindow(){
// Free any memory we are using.
if (Solution!=NULL) {free(Solution);Solution=NULL;}
if (Solution!=NULL) { free(Solution); Solution=NULL;}
if (Smem1!=NULL) { free(Smem1); Smem1=NULL; }
if (Smem2!=NULL) { free(Smem2); Smem2=NULL; }
if (Smem3!=NULL) { free(Smem3); Smem3=NULL; }
@ -252,15 +254,15 @@ InputWindow::~InputWindow(){ @@ -252,15 +254,15 @@ InputWindow::~InputWindow(){
if (Smem7!=NULL) { free(Smem7); Smem7=NULL; }
if (Smem8!=NULL) { free(Smem8); Smem8=NULL; }
if (gsln!=NULL) { gsln->~GBCSolution(); delete gsln; gsln=NULL;}
if (mem1!=NULL) { mem1->~GBCSolution(); delete mem1; mem1=NULL;}
if (mem2!=NULL) { mem2->~GBCSolution(); delete mem2; mem2=NULL;}
if (mem3!=NULL) { mem3->~GBCSolution(); delete mem3; mem3=NULL;}
if (mem4!=NULL) { mem4->~GBCSolution(); delete mem4; mem4=NULL;}
if (mem5!=NULL) { mem5->~GBCSolution(); delete mem5; mem5=NULL;}
if (mem6!=NULL) { mem6->~GBCSolution(); delete mem6; mem6=NULL;}
if (mem7!=NULL) { mem7->~GBCSolution(); delete mem7; mem7=NULL;}
if (mem8!=NULL) { mem8->~GBCSolution(); delete mem8; mem8=NULL;}
if (gsln!=NULL) { delete gsln; gsln=NULL;}
if (mem1!=NULL) { delete mem1; mem1=NULL;}
if (mem2!=NULL) { delete mem2; mem2=NULL;}
if (mem3!=NULL) { delete mem3; mem3=NULL;}
if (mem4!=NULL) { delete mem4; mem4=NULL;}
if (mem5!=NULL) { delete mem5; mem5=NULL;}
if (mem6!=NULL) { delete mem6; mem6=NULL;}
if (mem7!=NULL) { delete mem7; mem7=NULL;}
if (mem8!=NULL) { delete mem8; mem8=NULL;}
delete inG1;
delete inG2;
@ -359,8 +361,11 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) { @@ -359,8 +361,11 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
}
// Find the zero angle of the bore relative to the sighting system.
zeroangle=ZeroAngle(df,bc,v,sh,zero,0);
// if the zero distance <= 2 yards, it is a preset zero angle used to match the
// firing trajectory from another solution
if (zero <= 2.0) zeroangle=zero;
else zeroangle=ZeroAngle(df,bc,v,sh,zero,0);
// Generate a solution using the GNU Ballistics library call.
numRows = SolveAll(df,bc,v,sh,angle,zeroangle,windspeed,windangle,&(lSolution));
@ -403,7 +408,7 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) { @@ -403,7 +408,7 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
}
// Otherwise we assume success, and inform the user of our success.
sprintf(txt1,"GNU Ballistics Computer: Solution Valid.\nSolution's maximum valid range is %d yards\nUse the options in the 'Solution' menu to view results.",numRows-2);
sprintf(txt1,"GNU Ballistics Computer: Solution Valid.\nSolution's maximum valid range is %d yards\nBore angle is %0.5f above sights\nUse the options in the 'Solution' menu to view results.",numRows-2,zeroangle);
T->oStatus->value(txt1);
EnableMenu((InputWindow*) vd);
@ -415,10 +420,6 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) { @@ -415,10 +420,6 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
}
T->gsln=lsln;
}
return;
@ -511,15 +512,15 @@ void InputWindow::cb_Clear(Fl_Widget* o, void* v) { @@ -511,15 +512,15 @@ void InputWindow::cb_Clear(Fl_Widget* o, void* v) {
if (T->Smem7!=NULL) { free(T->Smem7); T->Smem7=NULL; }
if (T->Smem8!=NULL) { free(T->Smem8); T->Smem8=NULL; }
if (T->gsln!=NULL) { T->gsln->~GBCSolution(); delete T->gsln; T->gsln=NULL;}
if (T->mem1!=NULL) { T->mem1->~GBCSolution(); delete T->mem1; T->mem1=NULL;}
if (T->mem2!=NULL) { T->mem2->~GBCSolution(); delete T->mem2; T->mem2=NULL;}
if (T->mem3!=NULL) { T->mem3->~GBCSolution(); delete T->mem3; T->mem3=NULL;}
if (T->mem4!=NULL) { T->mem4->~GBCSolution(); delete T->mem4; T->mem4=NULL;}
if (T->mem5!=NULL) { T->mem5->~GBCSolution(); delete T->mem5; T->mem5=NULL;}
if (T->mem6!=NULL) { T->mem6->~GBCSolution(); delete T->mem6; T->mem6=NULL;}
if (T->mem7!=NULL) { T->mem7->~GBCSolution(); delete T->mem7; T->mem7=NULL;}
if (T->mem8!=NULL) { T->mem8->~GBCSolution(); delete T->mem8; T->mem8=NULL;}
if (T->gsln!=NULL) { /*T->gsln->~GBCSolution();*/ delete T->gsln; T->gsln=NULL;}
if (T->mem1!=NULL) { /*T->mem1->~GBCSolution();*/ delete T->mem1; T->mem1=NULL;}
if (T->mem2!=NULL) { /*T->mem2->~GBCSolution();*/ delete T->mem2; T->mem2=NULL;}
if (T->mem3!=NULL) { /*T->mem3->~GBCSolution();*/ delete T->mem3; T->mem3=NULL;}
if (T->mem4!=NULL) { /*T->mem4->~GBCSolution();*/ delete T->mem4; T->mem4=NULL;}
if (T->mem5!=NULL) { /*T->mem5->~GBCSolution();*/ delete T->mem5; T->mem5=NULL;}
if (T->mem6!=NULL) { /*T->mem6->~GBCSolution();*/ delete T->mem6; T->mem6=NULL;}
if (T->mem7!=NULL) { /*T->mem7->~GBCSolution();*/ delete T->mem7; T->mem7=NULL;}
if (T->mem8!=NULL) { /*T->mem8->~GBCSolution();*/ delete T->mem8; T->mem8=NULL;}
// Turn the memory labels back to black to show they are null.
@ -565,7 +566,7 @@ void InputWindow::cb_RangeTable(Fl_Widget*, void* v){ @@ -565,7 +566,7 @@ void InputWindow::cb_RangeTable(Fl_Widget*, void* v){
// Spawn a new RangeWindow using the current solution to populate it.
if (T->gsln != NULL && T->gsln->sln != NULL){
new RangeWindow(600,400,T->gsln);
new RangeWindow(760,520,T->gsln);
}
else {
T->oStatus->value("Error creating Range Window. Unknown Error.");
@ -672,40 +673,43 @@ void InputWindow::cb_Open(Fl_Widget* o, void*v){ @@ -672,40 +673,43 @@ void InputWindow::cb_Open(Fl_Widget* o, void*v){
InputWindow* T = (InputWindow*)v;
// A solution for locally working with gsln (hence the name lsln)
GBCSolution* lsln = NULL;
// Get the file name to load
char* fname=NULL;
fname = fl_file_chooser("Please select a file to open.","*.gbc","",0);
if (fname==NULL) {
T->oStatus->value("GNU Ballistic Computer: Error opening file!");
return;
}
}
T->OpenFile(fname);
}
void InputWindow::OpenFile(char * fname) {
// A solution for locally working with gsln (hence the name lsln)
GBCSolution* lsln = NULL;
// and open it for binary read.
FILE* ofile = fopen(fname,"rb");
// Free an old solution if there is one, because we want to
// write over it.
if (T->gsln != NULL) {
free(T->gsln);
T->gsln=NULL;
if (gsln != NULL) {
delete(gsln);
gsln=NULL;
}
// Allocate some space for the loaded solution.
if (lsln != NULL) {
free(lsln);
delete(lsln);
lsln=NULL;
}
// Assign some new memory for lsln.
lsln = (GBCSolution*)malloc(sizeof(GBCSolution));
lsln = new GBCSolution; // (GBCSolution*)malloc(sizeof(GBCSolution));
if (lsln==NULL){
T->oStatus->value("GNU Ballistic Computer: Memory allocation error.");
oStatus->value("GNU Ballistic Computer: Memory allocation error.");
return;
}
@ -716,15 +720,15 @@ void InputWindow::cb_Open(Fl_Widget* o, void*v){ @@ -716,15 +720,15 @@ void InputWindow::cb_Open(Fl_Widget* o, void*v){
fclose(ofile);
if (read!=sizeof(GBCSolution)){
T->oStatus->value("GNU Ballistic Computer: Error reading file data!\nPlease ensure the file is a valid GNUBC solution.");
oStatus->value("GNU Ballistic Computer: Error reading file data!\nPlease ensure the file is a valid GNUBC solution.");
if (lsln!=NULL) {
free(lsln);
delete(lsln);
lsln=NULL;
}
if (T->gsln!=NULL) {
free(T->gsln);
T->gsln=NULL;
if (gsln!=NULL) {
delete(gsln);
gsln=NULL;
}
return;
@ -732,51 +736,51 @@ void InputWindow::cb_Open(Fl_Widget* o, void*v){ @@ -732,51 +736,51 @@ void InputWindow::cb_Open(Fl_Widget* o, void*v){
// Set the parent's solution pointer to the local one we just imported.
T->gsln=lsln;
gsln=lsln;
// Load the solution data into the INPUT fields in the InputWindow.
char buff[1024];
T->inName->value(lsln->Name());
sprintf(buff,"%.3f",lsln->BC()); T->inBC->value(buff);
sprintf(buff,"%.2f",lsln->SightHeight()); T->inSH->value(buff);
sprintf(buff,"%d",lsln->MuzzleVelocity()); T->inMV->value(buff);
sprintf(buff,"%d",lsln->ShootingAngle()); T->inAngle->value(buff);
sprintf(buff,"%d",lsln->ZeroRange()); T->inZero->value(buff);
sprintf(buff,"%d",lsln->WindSpeed()); T->inVwind->value(buff);
sprintf(buff,"%d",lsln->WindAngle()); T->inAwind->value(buff);
sprintf(buff,"%d",lsln->Temp()); T->inTemp->value(buff);
sprintf(buff,"%.2f",lsln->Pressure()); T->inPressure->value(buff);
sprintf(buff,"%d",lsln->Humidity()); T->inHumidity->value(buff);
sprintf(buff,"%d",lsln->Altitude()); T->inAltitude->value(buff);
sprintf(buff,"%d",lsln->Weight()); T->inWeight->value(buff);
T->ckWeather->value(lsln->UseWeather());
T->cb_ckWeather(o,v);
T->inG1->value(0);
T->inG2->value(0);
T->inG5->value(0);
T->inG6->value(0);
T->inG7->value(0);
T->inG8->value(0);
if (lsln->df==G1) T->inG1->set();
if (lsln->df==G2) T->inG2->set();
if (lsln->df==G5) T->inG5->set();
if (lsln->df==G6) T->inG6->set();
if (lsln->df==G7) T->inG7->set();
if (lsln->df==G8) T->inG8->set();
inName->value(lsln->Name());
sprintf(buff,"%.3f",lsln->BC()); inBC->value(buff);
sprintf(buff,"%.2f",lsln->SightHeight()); inSH->value(buff);
sprintf(buff,"%d",lsln->MuzzleVelocity()); inMV->value(buff);
sprintf(buff,"%d",lsln->ShootingAngle()); inAngle->value(buff);
sprintf(buff,"%d",lsln->ZeroRange()); inZero->value(buff);
sprintf(buff,"%d",lsln->WindSpeed()); inVwind->value(buff);
sprintf(buff,"%d",lsln->WindAngle()); inAwind->value(buff);
sprintf(buff,"%d",lsln->Temp()); inTemp->value(buff);
sprintf(buff,"%.2f",lsln->Pressure()); inPressure->value(buff);
sprintf(buff,"%d",lsln->Humidity()); inHumidity->value(buff);
sprintf(buff,"%d",lsln->Altitude()); inAltitude->value(buff);
sprintf(buff,"%d",lsln->Weight()); inWeight->value(buff);
ckWeather->value(lsln->UseWeather());
cb_ckWeather(NULL,this);
inG1->value(0);
inG2->value(0);
inG5->value(0);
inG6->value(0);
inG7->value(0);
inG8->value(0);
if (lsln->df==G1) inG1->set();
if (lsln->df==G2) inG2->set();
if (lsln->df==G5) inG5->set();
if (lsln->df==G6) inG6->set();
if (lsln->df==G7) inG7->set();
if (lsln->df==G8) inG8->set();
// We don't actually have a valid solution, so make sure to set the solution
// double* pointer to NULL before we call solve.
T->gsln->sln=NULL;
gsln->sln=NULL;
// And now solve the loaded parameters.
DisableMenu(T);
T->cb_Solve(o,v);
DisableMenu(this);
cb_Solve(NULL,this);
// Finally inform the user of our success.
T->oStatus->value("GNU Ballistics Computer: File loaded successfully.");
oStatus->value("GNU Ballistics Computer: File loaded successfully.");
return;
@ -790,8 +794,22 @@ void InputWindow::cb_Plot(Fl_Widget* o, void* v){ @@ -790,8 +794,22 @@ void InputWindow::cb_Plot(Fl_Widget* o, void* v){
GBCSolution* sln = T->gsln;
GBCSolution* lmem1 = T->mem1;
GBCSolution* lmem2 = T->mem2;
GBCSolution* lmem3 = T->mem3;
new PlotWindow(700,500,sln,lmem1,lmem2,lmem3);
}
void InputWindow::cb_Target(Fl_Widget* o, void* v){
InputWindow* T = (InputWindow*)v;
GBCSolution* sln = T->gsln;
GBCSolution* lmem1 = T->mem1;
GBCSolution* lmem2 = T->mem2;
GBCSolution* lmem3 = T->mem3;
new PlotWindow(700,500,sln,lmem1,lmem2);
new TargetWindow(600,600,sln,lmem1,lmem2,lmem3);
}
@ -801,7 +819,6 @@ void InputWindow::cb_Store1(Fl_Widget* o, void* v){ @@ -801,7 +819,6 @@ void InputWindow::cb_Store1(Fl_Widget* o, void* v){
T->oStatus->value("GNU Ballistics Computer: Stored to Memory 1");
if (T->mem1 != NULL) {
if (T->mem1->sln!=NULL) free (T->mem1->sln);
delete(T->mem1);
}

8
InputWindow.h

@ -29,12 +29,16 @@ @@ -29,12 +29,16 @@
#include "AboutWindow.h"
#include "LicenseWindow.h"
#include "PlotWindow.h"
#include "TargetWindow.h"
class InputWindow : public Fl_Window{
public:
InputWindow(int w, int h, const char* title );
~InputWindow();
void OpenFile(char *fname);
Fl_Button* btSolve;
Fl_Button* btReset;
Fl_Button* btStdAtmosphere;
@ -81,7 +85,7 @@ class InputWindow : public Fl_Window{ @@ -81,7 +85,7 @@ class InputWindow : public Fl_Window{
Fl_Float_Input* inSH;
Fl_Int_Input* inMV;
Fl_Int_Input* inAngle;
Fl_Int_Input* inZero;
Fl_Float_Input* inZero;
Fl_Int_Input* inVwind;
Fl_Int_Input* inAwind;
Fl_Int_Input* inTemp; Fl_Float_Input* inPressure;
@ -107,6 +111,7 @@ class InputWindow : public Fl_Window{ @@ -107,6 +111,7 @@ class InputWindow : public Fl_Window{
Fl_Menu_Item m_Analyze;
Fl_Menu_Item mc_Table;
Fl_Menu_Item mc_Plot;
Fl_Menu_Item mc_Target;
Fl_Menu_Item mc_Compare;
Fl_Menu_Item m_Aids;
@ -154,6 +159,7 @@ class InputWindow : public Fl_Window{ @@ -154,6 +159,7 @@ class InputWindow : public Fl_Window{
static void cb_Save(Fl_Widget*, void*);
static void cb_Open(Fl_Widget*, void*);
static void cb_Plot(Fl_Widget*, void*);
static void cb_Target(Fl_Widget*, void*);
static void cb_Options(Fl_Widget*, void*);
static void cb_Store1(Fl_Widget*, void*);

2
Makefile.am

@ -10,6 +10,7 @@ gebcprogdir=../ @@ -10,6 +10,7 @@ gebcprogdir=../
gebc_SOURCES = \
InputWindow.cpp \
PlotWindow.cpp \
TargetWindow.cpp \
RangeWindow.cpp \
LicenseWindow.cpp \
AboutWindow.cpp \
@ -18,6 +19,7 @@ gebc_SOURCES = \ @@ -18,6 +19,7 @@ gebc_SOURCES = \
GNU_Ballistics.cpp \
InputWindow.h \
PlotWindow.h \
TargetWindow.h \
RangeWindow.h \
LicenseWindow.h \
AboutWindow.h \

1005
PlotWindow.cpp

File diff suppressed because it is too large Load Diff

29
PlotWindow.h

@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
#include <FL/fl_draw.h>
#include <FL/Fl_Menu_Bar.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Choice.H>
#include <stdio.h>
#include <stdlib.h>
@ -18,11 +19,12 @@ @@ -18,11 +19,12 @@
class PlotWindow : public Fl_Window {
public:
PlotWindow(int, int, GBCSolution*, GBCSolution*, GBCSolution*);
PlotWindow(int, int, GBCSolution*, GBCSolution*, GBCSolution*, GBCSolution*);
~PlotWindow(void);
GBCSolution* gsln;
GBCSolution* mem1;
GBCSolution* mem2;
GBCSolution* mem3;
@ -32,22 +34,32 @@ class PlotWindow : public Fl_Window { @@ -32,22 +34,32 @@ class PlotWindow : public Fl_Window {
int cheight;
int x_ticks;
int y_ticks;
int xmin, ymin, xmax, ymax;
int y0;
int x_range;
double y_range;
double x_scale, y_scale;
void PlotPath(void);
void PlotMem(GBCSolution* mem, int mode);
void SetupPlot(void);
void DrawPlotBackground(int mode, const char *ylabel);
void DrawPlotData(int mode);
void PlotPath(int ptype);
void PlotEnergy(void);
void PlotVelocity(void);
void PlotVelocity(int ptype);
int x_click;
int y_click;
Fl_Round_Button* rbPlotPath;
Fl_Round_Button* rbPlotVelocity;
Fl_Round_Button* rbPlotEnergy;
Fl_Check_Button* btMem1;
Fl_Check_Button* btMem2;
Fl_Check_Button* btMem3;
Fl_Value_Slider* sl_x;
Fl_Choice* cScopeGuides;
Fl_Choice* cPlotType;
Fl_Menu_Bar* menu;
@ -58,6 +70,9 @@ class PlotWindow : public Fl_Window { @@ -58,6 +70,9 @@ class PlotWindow : public Fl_Window {
static void cb_slUpdate(Fl_Widget* o, void* v);
static void cb_Mem1(Fl_Widget* o, void* v);
static void cb_Mem2(Fl_Widget* o, void* v);
static void cb_Mem3(Fl_Widget* o, void* v);
static void cb_Guides(Fl_Widget* o, void* v);
static void cb_PlotType(Fl_Widget* o, void* v);
};

605
RangeWindow.cpp

@ -1,5 +1,8 @@ @@ -1,5 +1,8 @@
#include "RangeWindow.h"
#define MOAtoMIL(moa) (moa/3.438)
#define MILtoMOA(mil) (mil*3.438)
RangeWindow::RangeWindow(int w, int h, GBCSolution* inSLN):Fl_Window(w,h,inSLN->Name()){
begin();
menu = new Fl_Menu_Bar(0,0,w,30,"MENU");
@ -55,16 +58,19 @@ RangeWindow::RangeWindow(int w, int h, GBCSolution* inSLN):Fl_Window(w,h,inSLN-> @@ -55,16 +58,19 @@ RangeWindow::RangeWindow(int w, int h, GBCSolution* inSLN):Fl_Window(w,h,inSLN->
tbl = new Fl_Browser(5,35,w-10,h-40,"Hello");
colwidths = (int*)malloc(10*sizeof(int));
colwidths = (int*)malloc(12*sizeof(int));
colwidths[0]=70; // Range (yds)
colwidths[1]=70; // Drop (in)
colwidths[2]=70; // Drop (MOA)
colwidths[3]=70; // Vel (ft/s)
colwidths[4]=70; // Energy (ft-lb)
colwidths[5]=70; // Winddrift (in)
colwidths[6]=70; // Windage (ft)
colwidths[7]=70; // Time (s)
colwidths[8]=0;
colwidths[3]=70; // Drop (MIL)
colwidths[4]=70; // Target Size (MILs)
colwidths[5]=70; // Vel (ft/s)
colwidths[6]=70; // Energy (ft-lb)
colwidths[7]=70; // Winddrift (in)
colwidths[8]=70; // Windage (ft)
colwidths[9]=70; // Windage (MIL)
colwidths[10]=70; // Time (s)
colwidths[11]=0;
tbl->column_widths(colwidths);
tbl->column_char('\t');
@ -72,6 +78,7 @@ RangeWindow::RangeWindow(int w, int h, GBCSolution* inSLN):Fl_Window(w,h,inSLN-> @@ -72,6 +78,7 @@ RangeWindow::RangeWindow(int w, int h, GBCSolution* inSLN):Fl_Window(w,h,inSLN->
min=0;
max=1000;
step=10;
targetsize=4.0; // inches
GenTable();
@ -88,21 +95,116 @@ RangeWindow::~RangeWindow(){ @@ -88,21 +95,116 @@ RangeWindow::~RangeWindow(){
}
/*
Mini-HOWTO: modifying the range table.
For the table data:
- update COLUMNS define, headers0, headers1, format,
sqlnames and xmlnames arrays below.
- add a case to GetData for the column data
For the load data at the top:
- modify GetPreface() and GetPrefaceLines()
Note: entries with a blank sqlname are not written to the sql output.
entries with a blank xmlname are not written to the xml output.
*/
#define COLUMNS 11
static const char *headers0[COLUMNS]={"Range", "Drop", "Drop", "Drop", "4\" Obj", "Velocity","Energy", "Wind Drift","Windage", "Windage", "Time"};
static const char *headers1[COLUMNS]={"(yards)","(inches)","(MOA)", "(MIL)", "(MIL)", "(ft/s)", "(ft-lbs)","(inches)", "(MOA)", "(MIL)", "(s)" };
static const char *format [COLUMNS]={"%.0f", "%.2f", "%.2f", "%.2f", "%.2f", "%.0f", "%.0f", "%.2f", "%.2f", "%.2f", "%.2f"};
static const char *sqlnames[COLUMNS]={"range", "drop", "elev_moa", "elev_mil","", "velocity","energy", "winddrift", "windage_moa","windage_mil","time"};
static const char *xmlnames[COLUMNS]={"Range", "Drop", "ElevMOA", "ElevMIL", "", "Velocity","Energy", "WindDrift", "WindageMOA", "WindageMIL", "Time"};
int RangeWindow::GetColumns(void){
return COLUMNS;
}
int RangeWindow::GetHeaderLines(void){
return 2;
}
int RangeWindow::GetPrefaceLines(void){
return 5;
}
void RangeWindow::GetPreface(int l, char *str){
switch (l) {
case 0: sprintf(str,"Drag Coefficient: %.3f Projectile Weight: %d grains",Sln->BC(), Sln->Weight());
break;
case 1: sprintf(str,"Initial Velocity: %d (ft/s) Zero Range: %d yards (%d metres) Shooting Angle: %d degrees",Sln->MuzzleVelocity(), Sln->ZeroRange(), (int)(Sln->ZeroRange()*0.9144), Sln->ShootingAngle());
break;
case 2: sprintf(str,"Wind Velocity: %d mph (%1.1f m/sec) Wind Direction: %d degrees",Sln->WindSpeed(), Sln->WindSpeed()*0.44704, Sln->WindAngle());
break;
case 3: sprintf(str,"Altitude: %d feet (%1.0f M) Barometer: %.2f in-Hg (%1.0f mbar)",
Sln->Altitude(), Sln->Altitude() * 0.3048,
Sln->Pressure(), Sln->Pressure() * 33.8639);
break;
case 4: sprintf(str,"Temperature: %d F (%1.0f C) Relative Humidity: %d%%",
Sln->Temp(), 100.0/(212-32) * (Sln->Temp() - 32),
Sln->Humidity());
break;
default: *str='\0';
break;
}
}
const char *RangeWindow::GetHeader(int col, int row){
if (col<0 || col>=GetColumns()) return NULL;
if (row==0) return headers0[col];
if (row==1) return headers1[col];
return NULL;
}
/* returns the data for a column at a given range */
int RangeWindow::GetData(int col, int range, char *buf){
if (col>=GetColumns()) { *buf='\0'; return 0; }
if (range<0) { *buf='\0'; return 0; }
if (range==0 &&
(col==2 || col==3 || col==4 || col==8 || col==9)
) return sprintf(buf, "-");
double v=0;
switch (col) {
case 0: v= Sln->GetRange(range); break;
case 1: v= Sln->GetPath(range); break;
case 2: v= Sln->GetMOA(range); break;
case 3: v= MOAtoMIL(Sln->GetMOA(range)); break;
case 4: v= (targetsize / 36.0 * 1000) / range; break;
case 5: v= Sln->GetVelocity(range); break;
case 6: v= Sln->GetVelocity(range);
v= Sln->Weight()*v*v/450436;
break;
case 7: v= Sln->GetWindage(range); break;
case 8: v= Sln->GetWindageMOA(range); break;
case 9: v= MOAtoMIL(Sln->GetWindageMOA(range)); break;
case 10:v= Sln->GetTime(range); break;
}
return sprintf(buf, format[col], v);
}
static char buffer[20];
char *RangeWindow::GetData(int col, int range){
GetData(col, range, buffer);
return buffer;
}
void RangeWindow::GenTable(){
double r,p,m,v,e,wi,wm,t;
tbl->clear();
int MIN=this->min;
int MAX=this->max;
int STEP=this->step;
int num=Sln->MaxRows();
// printf("NUM: %d",num);
@ -110,34 +212,43 @@ void RangeWindow::GenTable(){ @@ -110,34 +212,43 @@ void RangeWindow::GenTable(){
if (MIN>MAX) MIN=MAX;
char* str = (char*)malloc(1024*sizeof(char));
char* strp;
// Print some general information about the load.
sprintf(str,"@b%s",Sln->Name()); tbl->add(str);
sprintf(str,"Drag Coefficient: %.3f Projectile Weight: %d grains",Sln->BC(), Sln->Weight()); tbl->add(str);
sprintf(str,"Initial Velocity: %d (ft/s) Zero Range: %d yards Shooting Angle: %d degrees",Sln->MuzzleVelocity(), Sln->ZeroRange(), Sln->ShootingAngle()); tbl->add(str);
sprintf(str,"Wind Velocity: %d mph Wind Direction: %d degrees",Sln->WindSpeed(), Sln->WindAngle()); tbl->add(str);
sprintf(str,"Altitude: %d feet Barometer: %.2f in-Hg Temperature: %d F Relative Humidity: %d%%",Sln->Altitude(), Sln->Pressure(), Sln->Temp(), Sln->Humidity()); tbl->add(str);
sprintf(str, "@b%s", Sln->Name());
tbl->add(str);
for (int n=0; n < GetPrefaceLines(); n++) {
GetPreface(n, str);
tbl->add(str);
}
tbl->add("");
tbl->add("@b@cRange\t@b@cDrop\t@b@cDrop\t@b@cVelocity\t@b@cEnergy\t@b@cWind Drift\t@b@cWindage\t@b@cTime",0);
tbl->add("@c(yards)\t@c(inches)\t@c(MOA)\t@c(ft/s)\t@c(ft-lb)\t@c(inches)\t@c(MOA)\t@c(s)",0);
for (int n=MIN;n<=MAX;n=n+STEP){
r=Sln->GetRange(n);
p=Sln->GetPath(n);
m=Sln->GetMOA(n);
v=Sln->GetVelocity(n);
wi=Sln->GetWindage(n);
wm=Sln->GetWindageMOA(n);
t=Sln->GetTime(n);
e=Sln->Weight()*v*v/450436;
sprintf(str,"@c%.0f\t@c%.2f\t@c%.2f\t@c%.0f\t@c%.0f\t@c%.2f\t@c%.2f\t@c%.2f",r,p,m,v,e,wi,wm,t);
tbl->add(str,0);
}
// headers
for (int hline=0; hline < GetHeaderLines(); hline++) {
int col;
strp=str;
for (col=0; col < GetColumns()-1; col++) {
strp+=sprintf(strp, "@b@c%s\t", GetHeader(col, hline));
}
sprintf(strp, "@b@c%s", GetHeader(col,hline));
tbl->add(str);
}
// actual data
for (int n=MIN;n<=MAX;n=n+STEP){
int col;
strp=str;
for (col=0; col < GetColumns()-1; col++) {
strp+=sprintf(strp, "@c%s\t", GetData(col, n));
}
sprintf(strp, "@c%s", GetData(col,n));
tbl->add(str,0);
}
free(str);
}
@ -282,32 +393,31 @@ void RangeWindow::cb_ExportCSV(Fl_Widget* f, void* vtt){ @@ -282,32 +393,31 @@ void RangeWindow::cb_ExportCSV(Fl_Widget* f, void* vtt){
FILE* ofile = fopen(fname,"w");
// Print the output to a file.
double r,p,m,v,e,wi,wm,t;
int MIN=T->min;
int MAX=T->max;
int STEP=T->step;
fprintf(ofile, "Range,Drop,Drop,Velocity,Energy,Wind Drift,Windage,Time");
fprintf(ofile, "\n(yards),(inches),(MOA),(ft/s),(ft-lb),(inches),(MOA),(s)");
// headers
for (int hline=0; hline < T->GetHeaderLines(); hline++) {
int col;
for (col=0; col < T->GetColumns()-1; col++) {
fprintf(ofile, "%s,", T->GetHeader(col,hline));
}
fprintf(ofile,"%s\n", T->GetHeader(col,hline));
}
int num=T->Sln->MaxRows();
if (MAX>num) MAX=num;
if (MIN>MAX) MIN=MAX;
// actual data
for (int n=MIN;n<=MAX;n=n+STEP){
r=T->Sln->GetRange(n);
p=T->Sln->GetPath(n);
m=T->Sln->GetMOA(n);
v=T->Sln->GetVelocity(n);
e=0;
wi=T->Sln->GetWindage(n);
wm=T->Sln->GetWindageMOA(n);
t=T->Sln->GetTime(n);
e=T->Sln->Weight()*v*v/450436;
fprintf(ofile,"\n%.0f,%.2f,%.2f,%.0f,%.2f,%.2f,%.2f,%.2f",r,p,m,v,e,wi,wm,t);
int col;
for (col=0; col < T->GetColumns()-1; col++) {
fprintf(ofile, "%s,", T->GetData(col, n));
}
fprintf(ofile,"%s\n", T->GetData(col, n));
}
fclose(ofile);
@ -325,69 +435,39 @@ void RangeWindow::cb_ExportExcel(Fl_Widget* f, void* vtt){ @@ -325,69 +435,39 @@ void RangeWindow::cb_ExportExcel(Fl_Widget* f, void* vtt){
FILE* ofile = fopen(fname,"w");
// Print the output to a file.
double r,p,m,v,e,wi,wm,t;
int MIN=T->min;
int MAX=T->max;
int STEP=T->step;
fprintf(ofile, "\n<html><head><title>$s</title></head>");
fprintf(ofile, "\n\n<table><tr>");
fprintf(ofile, "<td>Range</td>\
<td>Drop</td>\
<td>Drop</td>\
<td>Velocity</td>\
<td>Energy</td>\
<td>Winddrift</td>\
<td>Windage</td>\
<td>Time</td></tr>"
);
fprintf(ofile,"\n<tr>");
fprintf(ofile, "<td>(yards)</td>\
<td>(inches)</td>\
<td>(MOA)</td>\
<td>(ft/s)</td>\
<td>(ft-lb)</td>\
<td>(inches)</td>\
<td>(MOA)</td>\
<td>(s)</td>"
);
fprintf(ofile, "\n<html><head><title>%s</title></head>", T->Sln->Name());
fprintf(ofile, "\n\n<table>");
// headers
for (int hline=0; hline < T->GetHeaderLines(); hline++) {
int col;
fprintf(ofile, "<tr>");
for (col=0; col < T->GetColumns()-1; col++) {
fprintf(ofile, "<td>%s</td>", T->GetHeader(col,hline));
}
fprintf(ofile,"<td>%s</td></tr>\n", T->GetHeader(col,hline));
}
int num=T->Sln->MaxRows();
if (MAX>num) MAX=num;
if (MIN>MAX) MIN=MAX;
for (int n=MIN;n<=MAX;n=n+STEP){
r=T->Sln->GetRange(n);
p=T->Sln->GetPath(n);
m=T->Sln->GetMOA(n);
v=T->Sln->GetVelocity(n);
e=0;
wi=T->Sln->GetWindage(n);
wm=T->Sln->GetWindageMOA(n);
t=T->Sln->GetTime(n);
e=T->Sln->Weight()*v*v/450436;
fprintf(ofile,"\n<tr>\
<td>%.0f</td>\
<td>%.2f</td>\
<td>%.2f</td>\
<td>%.0f</td>\
<td>%.2f</td>\
<td>%.2f</td>\
<td>%.2f</td>\
<td>%.2f</td></tr>",
r,p,m,v,e,wi,wm,t);
int col;
fprintf(ofile, "<tr>");
for (col=0; col < T->GetColumns()-1; col++) {
fprintf(ofile, "<td>%s</td>", T->GetData(col, n));
}
fprintf(ofile,"<td>%s</td></tr>\n", T->GetData(col, n));
}
fprintf(ofile,"\n</table></html>");
fclose(ofile);
}
@ -403,66 +483,39 @@ void RangeWindow::cb_ExportOO(Fl_Widget* f, void* vtt){ @@ -403,66 +483,39 @@ void RangeWindow::cb_ExportOO(Fl_Widget* f, void* vtt){
FILE* ofile = fopen(fname,"w");
// Print the output to a file.
double r,p,m,v,e,wi,wm,t;
int MIN=T->min;
int MAX=T->max;
int STEP=T->step;
fprintf(ofile, "\n<html><head><title>%s</title></head>","TO DO ");
fprintf(ofile, "\n\n<table><tr>");
fprintf(ofile, "\n<td>Range</td>\
\n<td>Drop</td>\
\n<td>Drop</td>\
\n<td>Velocity</td>\
\n<td>Energy</td>\
\n<td>Winddrift</td>\
\n<td>Windage</td>\
\n<td>Time</td></tr>"
);
fprintf(ofile,"\n\n<tr>");
fprintf(ofile, "\n<td>(yards)</td>\
\n<td>(inches)</td>\
\n<td>(MOA)</td>\
\n<td>(ft/s)</td>\
\n<td>(ft-lb)</td>\
\n<td>(inches)</td>\
\n<td>(MOA)</td>\
\n<td>(s)</td>"
);
fprintf(ofile, "\n<html><head><title>%s</title></head>", T->Sln->Name());
fprintf(ofile, "\n\n<table>");
// headers
for (int hline=0; hline < T->GetHeaderLines(); hline++) {
int col;
fprintf(ofile, "<tr>");
for (col=0; col < T->GetColumns()-1; col++) {
fprintf(ofile, "<td>%s</td>", T->GetHeader(col,hline));
}
fprintf(ofile,"<td>%s</td></tr>\n", T->GetHeader(col,hline));
}
int num=T->Sln->MaxRows();
if (MAX>num) MAX=num;
if (MIN>MAX) MIN=MAX;
for (int n=MIN;n<=MAX;n=n+STEP){
r=T->Sln->GetRange(n);
p=T->Sln->GetPath(n);
m=T->Sln->GetMOA(n);
v=T->Sln->GetVelocity(n);
e=0;
wi=T->Sln->GetWindage(n);
wm=T->Sln->GetWindageMOA(n);
t=T->Sln->GetTime(n);
e=T->Sln->Weight()*v*v/450436;
fprintf(ofile,"\n<tr>\
\n<td>%.0f</td>\
\n<td>%.2f</td>\
\n<td>%.2f</td>\
\n<td>%.0f</td>\
\n<td>%.2f</td>\
\n<td>%.2f</td>\
\n<td>%.2f</td>\
\n<td>%.2f</td></tr>",
r,p,m,v,e,wi,wm,t);
int col;
fprintf(ofile, "<tr>");
for (col=0; col < T->GetColumns()-1; col++) {
fprintf(ofile, "<td>%s</td>", T->GetData(col, n));
}
fprintf(ofile,"<td>%s</td></tr>\n", T->GetData(col, n));
}
fprintf(ofile,"\n</table></html>");
fclose(ofile);
}
@ -477,70 +530,42 @@ void RangeWindow::cb_ExportHTML(Fl_Widget* f , void* vtt){ @@ -477,70 +530,42 @@ void RangeWindow::cb_ExportHTML(Fl_Widget* f , void* vtt){
FILE* ofile = fopen(fname,"w");
// Print the output to a file.
double r,p,m,v,e,wi,wm,t;
int MIN=T->min;
int MAX=T->max;
int STEP=T->step;
fprintf(ofile, "\n<html><head><title>%s</title></head>","");
fprintf(ofile, "\n\n<table width=560 bgcolor=black><tr>");
fprintf(ofile, "\n<td width=70 bgcolor=white align=center><b>Range</b></td>\
\n<td width=70 bgcolor=white align=center><b>Drop</b></td>\
\n<td width=70 bgcolor=white align=center><b>Drop</b></td>\
\n<td width=70 bgcolor=white align=center><b>Velocity</b></td>\
\n<td width=70 bgcolor=white align=center><b>Energy</b></td>\
\n<td width=70 bgcolor=white align=center><b>Winddrift</b></td>\
\n<td width=70 bgcolor=white align=center><b>Windage</b></td>\
\n<td width=70 bgcolor=white align=center><b>Time</b></td></tr>"
);
fprintf(ofile,"\n\n<tr>");
fprintf(ofile, "\n<td width=70 bgcolor=white align=center><b>(yards)</b></td>\
\n<td width=70 bgcolor=white align=center><b>(inches)</b></td>\
\n<td width=70 bgcolor=white align=center><b>(MOA)</b></td>\
\n<td width=70 bgcolor=white align=center><b>(ft/s)</b></td>\
\n<td width=70 bgcolor=white align=center><b>(ft-lb)</b></td>\
\n<td width=70 bgcolor=white align=center><b>(inches)</b></td>\
\n<td width=70 bgcolor=white align=center><b>(MOA)</b></td>\
\n<td width=70 bgcolor=white align=center><b>(s)</b></td>"
);
fprintf(ofile, "\n<html><head><title>%s</title></head>",T->Sln->Name());
fprintf(ofile, "\n\n<table width=560 bgcolor=black>");
// headers
for (int hline=0; hline < T->GetHeaderLines(); hline++) {
int col;
fprintf(ofile, "<tr>\n");
for (col=0; col < T->GetColumns()-1; col++) {
fprintf(ofile, "\t<td width=70 bgcolor=white align=center><b>%s</b></td>", T->GetHeader(col,hline));
}
fprintf(ofile,"\t<td width=70 bgcolor=white align=center>%s</b></td>\n</tr>\n", T->GetHeader(col,hline));
}
int num=T->Sln->MaxRows();
if (MAX>num) MAX=num;
if (MIN>MAX) MIN=MAX;
for (int n=MIN;n<=MAX;n=n+STEP){
r=T->Sln->GetRange(n);
p=T->Sln->GetPath(n);
m=T->Sln->GetMOA(n);
v=T->Sln->GetVelocity(n);
e=0;
wi=T->Sln->GetWindage(n);
wm=T->Sln->GetWindageMOA(n);
t=T->Sln->GetTime(n);
e=T->Sln->Weight()*v*v/450436;
e=v*v/450436;
fprintf(ofile,"\n\n<tr>\
\n<td width=70 bgcolor=white align=center>%.0f</td>\
\n<td width=70 bgcolor=white align=center>%.2f</td>\
\n<td width=70 bgcolor=white align=center>%.2f</td>\
\n<td width=70 bgcolor=white align=center>%.0f</td>\
\n<td width=70 bgcolor=white align=center>%.2f</td>\
\n<td width=70 bgcolor=white align=center>%.2f</td>\
\n<td width=70 bgcolor=white align=center>%.2f</td>\
\n<td width=70 bgcolor=white align=center>%.2f</td></tr>",
r,p,m,v,e,wi,wm,t);
int col;
fprintf(ofile, "<tr>");
for (col=0; col < T->GetColumns()-1; col++) {
fprintf(ofile, "\t<td width=70 bgcolor=white align=center>%s</td>", T->GetData(col, n));
}
fprintf(ofile,"\t<td width=70 bgcolor=white align=center>%s</td>\n</tr>\n", T->GetData(col, n));
}
fprintf(ofile,"\n</table></html>");
fclose(ofile);
}
void RangeWindow::cb_ExportSQL(Fl_Widget* f, void* vtt){
RangeWindow* T = (RangeWindow*)vtt;
@ -552,7 +577,6 @@ void RangeWindow::cb_ExportSQL(Fl_Widget* f, void* vtt){ @@ -552,7 +577,6 @@ void RangeWindow::cb_ExportSQL(Fl_Widget* f, void* vtt){
FILE* ofile = fopen(fname,"w");
// Print the output to a file.
double r,p,m,v,e,wi,wm,t;
int MIN=T->min;
int MAX=T->max;
@ -561,37 +585,36 @@ void RangeWindow::cb_ExportSQL(Fl_Widget* f, void* vtt){ @@ -561,37 +585,36 @@ void RangeWindow::cb_ExportSQL(Fl_Widget* f, void* vtt){
int num=T->Sln->MaxRows();
if (MAX>num) MAX=num;
if (MIN>MAX) MIN=MAX;
char* str = (char*)malloc(1024*sizeof(char));
char* strp;
// The column names are in their own array. Columns with blank sql names are
// not written to the output.
for (int hline=0; hline < T->GetHeaderLines(); hline++) {
int col;
strp=str;
for (col=0; col < T->GetColumns()-1; col++) {
if (sqlnames[col] && *sqlnames[col])
strp+=sprintf(strp, "%s,", sqlnames[col]);
}
sprintf(strp, "%s", sqlnames[col]);
}
for (int n=MIN;n<=MAX;n=n+STEP){
r=T->Sln->GetRange(n);
p=T->Sln->GetPath(n);
m=T->Sln->GetMOA(n);
v=T->Sln->GetVelocity(n);
e=0;
wi=T->Sln->GetWindage(n);
wm=T->Sln->GetWindageMOA(n);
t=T->Sln->GetTime(n);
e=T->Sln->Weight()*v*v/450436;
fprintf(ofile,"\nINSERT INTO BallisticData {range, drop, elevation, velocity, energy, winddrift, windage, time} VALUES\
{%.0f,\
%.2f, \
%.2f,\
%.0f,\
%.2f,\
%.2f,\
%.2f,\
%.2f};",