Tracker
A. First Edition
This is a small program which is used for my project.
The problem is simple. I have a series of data files which are the results of "evolver". Evolver is
a soft package such that it can simulate the intension movements of liquid. Now we want to know
how exactly a small chip moves which floats on the top of liquid.
E.Further improvement
It is a small game and no one would bother to treat them seriously, I presume.
F.File listing
1. main.cpp(main)
2. tracker.h
3. tracker.cpp
file name: main.cpp(main)
#include "tracker.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main()
{
Tracker T;
T.readFile();
//T.display();
T.tracking(-0.141400, -0.141400);
T.displayTrack();
return 0;
}
file name: tracker.h
//#include <stdio.h>
//#include <stdlib.h>
//#x0 x0/TW_x y0 y0/TW_y z0 phi Fo Fp Fz torque
const int RowCount=11;//this is the data row
const int ColCount=10;//this is the data col
const double StepX=0.014142;
const double StepY=0.014142;
const int Quadrant=4;
const int GridRow=11;//this means the number of row of grid
const int GridCol=11;//this means the number of col of grid
const int StartQuadrant=3;
const double StartX=-0.141421;
const double StartY=-0.141421;
const double PI=3.14159265358979323846;
const double TimeStep=0.001;//milisecond
const double Mass=0.4*0.4*2.8*0.01;//pad_width=0.4, thickness=0.01, density=2.8
const int MaxTrackStep=100;
struct Coord
{
double x;
double y;
};
struct GRID
{
double x0;
double y0;
double fx;
double fy;
double torque;
};
class Tracker
{
private:
double vx, vy, ax, ay;
int t;
double ABS(double num){return num>=0?num:-num;}
Coord tracks[MaxTrackStep];
GRID grids[Quadrant][GridRow][GridCol];
bool force(double x, double y, double& f_x, double& f_y);
public:
void readFile(char* fileName="results");
void tracking(double startx, double starty);
void display();//for debug
void displayTrack();
};
file name: tracker.cpp
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <fstream.h>
#include "tracker.h"
//#define ABS(x) (x>=0?x:-x)
void Tracker::readFile(char* fileName)
{
const int EmptyLine=10;
ifstream in;
char buffer[512];
int lines=0, quadrant;
double x,y,fp,fo, tor, dump, theta;
in.open(fileName);
while (lines<EmptyLine)
{
in.getline(buffer, 512);
lines++;
}
while (!in.eof())
{
for (int q=0; q<Quadrant; q++)
{
quadrant=(q+StartQuadrant)%Quadrant;
for (int r=0; r<GridRow; r++)
{
for (int c=0; c<GridCol; c++)
{
//Fo := Fx*cos(pi+theta) + Fy*sin(pi+theta);
//Fp := Fy*cos(pi+theta) - Fx*sin(pi+theta);
//there is problem of "pi+theta" as theta is already the 3rd quadrant
//theta = atan2(yoff, xoff) ranging from -PI to PI
in>>x>>dump>>y>>dump>>dump>>dump>>fo>>fp>>dump>>tor;
theta=atan2(y, x);
grids[quadrant][r][c].x0=x;
grids[quadrant][r][c].y0=y;
grids[quadrant][r][c].torque=tor;
grids[quadrant][r][c].fx=fo*cos(PI+theta)-fp*sin(PI+theta);
grids[quadrant][r][c].fy=fo*sin(PI+theta)+fp*cos(PI+theta);
}
}
}
break;
}
/*
while(!in.eof())
{
in.getline(buffer, 512);
}
*/
}
bool Tracker::force(double x, double y, double& f_x, double& f_y)
{
int r=0,c=0, quadrant=0;
double distanceX, distanceY, prop_x, prop_y, fx_hi, fx_lo, fy_hi, fy_lo;
bool found=false;
f_x=f_y=0;
if (y<0)
{
quadrant+=2;
}
if (x<0)
{
quadrant+=1;
}
for(r=0; r<GridRow-1; r++)
{
if (found)
{
break;
}
for (c=0; c<GridCol-1; c++)
{
if (ABS(x) < ABS(grids[quadrant][r+1][c].x0)
&&ABS(x) >= ABS(grids[quadrant][r][c].x0)
&&ABS(y) < ABS(grids[quadrant][r][c+1].y0)
&&ABS(y) >= ABS(grids[quadrant][r][c].y0))
{
found=true;
//because (x,y) is in-between four points
distanceX=ABS(grids[quadrant][r][c].x0-grids[quadrant][r+1][c].x0);
distanceY=ABS(grids[quadrant][r][c].y0-grids[quadrant][r][c+1].y0);
//proportion
prop_x=ABS(x-grids[quadrant][r][c].x0);
prop_x/=distanceX;
prop_y=ABS(y-grids[quadrant][r][c].y0);
prop_y/=distanceY;
//for fx, it is prop_x
fx_hi=grids[quadrant][r+1][c+1].fx*(1-prop_x)+
grids[quadrant][r][c+1].fx*prop_x;
fx_lo=grids[quadrant][r+1][c].fx*(1-prop_x)+
grids[quadrant][r][c].fx*prop_x;
//but the total depends on prop_y
f_x =fx_hi*prop_y+fx_lo*(1-prop_y);
fy_hi=grids[quadrant][r+1][c+1].fy*(1-prop_y)+
grids[quadrant][r+1][c].fy*prop_y;
fy_lo=grids[quadrant][r][c+1].fy*(1-prop_y)+
grids[quadrant][r][c].fy*prop_y;
//but the total depends on prop_y
f_y =fy_hi*prop_x+fy_lo*(1-prop_x);
break;
}
}
}
return found;
}
void Tracker::tracking(double startx, double starty)
{
double fx, fy, x, y;
vx=vy=ax=ay=0;
x=startx;
y=starty;
t=0;
tracks[t].x=x;
tracks[t].y=y;
do
{
if (force(tracks[t].x, tracks[t].y, fx, fy))
{
ax=fx/Mass;
ay=fy/Mass;
vx+=ax*TimeStep;
vy+=ay*TimeStep;
x+=ax*TimeStep*TimeStep/2+vx*TimeStep;
y+=ay*TimeStep*TimeStep/2+vy*TimeStep;
tracks[t+1].x=x;
tracks[t+1].y=y;
}
else
{
break;
}
t++;
}while (t<MaxTrackStep-1);
}
void Tracker::displayTrack()
{
for (int i=0; i<t; i++)
{
printf("x=%f, y=%f\n", tracks[i].x, tracks[i].y);
}
}
void Tracker::display()
{
for (int q=0; q<Quadrant; q++)
{
for (int r=0; r<GridRow; r++)
{
for (int c=0; c<GridCol; c++)
{
printf("x=%f,y=%f,fx=%f,fy=%f,torque=%f\n", grids[q][r][c].x0,
grids[q][r][c].y0, grids[q][r][c].fx, grids[q][r][c].fy,
grids[q][r][c].torque);
}
printf("\n\n");
}
}
}
/*
void Tracker::readFile(char* fileName)
{
const int EmptyLine=10;
FILE* stream;
char buffer[512];
int lines=0;
double x,y,fp,fo, tor, dump;
stream=fopen(fileName, "r");
while (!feof(stream))
{
//omit empty data line
while (lines<EmptyLine)
{
fgets(buffer, 512, stream);
lines++;
}
//now start reading
fgets(buffer, 512, stream);
if (strlen(buffer)!=0)
{
//#x0 x0/TW_x y0 y0/TW_y z0 phi Fo Fp Fz torque
// sscanf(buffer, "%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n", x,dump, y,dump, dump,
// dump, fo, fp, dump, tor);
sscanf(buffer, "%f", x);
}
}
}
*/
The result is like following:
x=-0.141400, y=-0.141400
x=-0.129308, y=-0.129279
x=-0.108501, y=-0.108465
x=-0.078684, y=-0.078633
x=-0.039354, y=-0.039295
x=0.006118, y=0.006196
x=0.044441, y=0.051592
x=0.073316, y=0.100191
Press any key to continue