Let say I've 5 points, where p0 and p4 are fixed with values 0.0 and 4.0:
0 | 1.0 | 2.0 | 3.0 | 4
The points in the middle can change, but they must stretch the others once moving.
So for a stretch "to right", it must enlarge the prev values around the moving point and press the next ones between the moving point and the last point, keeping the proportions between each points.
I've write this code which move the 3° point to 2.5 from its original 2.0 x-position:
const int numPoints = 5;
double points[numPoints] = { 0.0, 1.0, 2.0, 3.0, 4.0 };
int stretchedPoint = 2;
double prevX = points[stretchedPoint];
points[stretchedPoint] = 2.5;
std::cout<< points[0];
for (int prevPoint = 1; prevPoint < numPoints - 1; prevPoint++) {
// prev points
if (prevPoint < stretchedPoint) {
double ratio = points[stretchedPoint] / prevX;
points[prevPoint] *= ratio;
// next points
} else if (prevPoint > stretchedPoint) {
double ratio = (points[numPoints - 1] - prevX) / (points[numPoints - 1] - points[stretchedPoint]);
points[prevPoint] *= ratio;
}
std::cout << " | " << points[prevPoint];
}
std::cout << " | " << points[numPoints - 1];
which give to me right result for prev points:
0 | 1.25 | 2.5 | 0.76 | 4
but when I try to apply the "same-wrapped-math" for the next points, I get a non-proportional scaling, which give weird results (4?)
Can anyone help me?
You forgot about non-zero starting point
points[prevPoint] = points[stretchedPoint] + ratio * (points[prevPoint] - prevX)
Note that same logic should be applied to previos points, if start value is non-zero
In general, to apply linear interpolation for initial X0..X1 interval and final X0new..X1new interval, one have to use
(Xnew - X0new) / (X1new - X0new) = (X - X0) / (X1 - X0)
so
XNew = X0new + (X1new - X0new) * (X - X0) / (X1 - X0)
What you did on the left side of the point (and which is working) can be rewritten somehow like this:
// double ratio = (points[stretchedPoint] - 0) / (prevX - 0);
// points[prevPoint] = 0 + ratio * (points[prevPoint] - 0);
To achieve exactly the dual on the right side, it should be:
} else if (prevPoint > stretchedPoint) {
double ratio = (points[numPoints - 1] - points[stretchedPoint]) /
(points[numPoints - 1] - prevX);
points[prevPoint] = points[numPoints - 1] -
ratio * (points[numPoints-1] - points[prevPoint]);
}
Related
I am trying to implement the Cubic Interpolation method using the next formula when a=-0.5 as usual.
My Linear Interpolation and Nearest Neighbor interpolation is working great but for some reason the Cubic interpolation fails with white pixels and turn them sometimes to turquoise color and sometimes messing around with another colors.
for example using rotation: (NOTE: please look carefully on the right image and you will notice the problems)
Another Example with much more black pixels. It almost seems to work perfectly but look on the dog's tongue. (strong white pixels turn to turquoise again)
you can see that my implementation of the Linear Interpolation is working great:
Since the actual rotation worked, I think I have a small mistake in the code that I did not notice, or maybe it's a numeric error or a double / float error.
It is important to note that I read the image normally and store the destination image as follows:
cv::Mat img = cv::imread("../dogfails.jpeg");
cv::Mat rotatedImageCubic(img.rows,img.cols,CV_8UC3);
Clarifications:
Inside my cubic interpolation function, srcPoint (newX and newY) is the "landing point" from the inverse transformation.
In my inverse transformations I am not using matrix multiplication with the pixels, right now I am just using the formulas for rotation. It might be important for the "numerical errors". For example:
rotatedX = x * cos(angle * toRadian) + y * sin(angle * toRadian);
rotatedY = x * (-sin(angle * toRadian)) + y * cos(angle * toRadian);
Here is my code for the Cubic Interpolation
double cubicEquationSolver(double d,double a) {
d = abs(d);
if( 0.0 <= d && d <= 1.0) {
double score = (a + 2.0) * pow(d, 3.0) - ((a + 3.0) * pow(d, 2.0)) + 1.0;
return score;
}
else if(1 < d && d <= 2) {
double score = a * pow(d, 3.0) - 5.0*a * pow(d, 2.0) + 8.0*a * d - 4.0*a;
return score;
}
else
return 0.0;
}
void Cubic_Interpolation_Helper(const cv::Mat& src, cv::Mat& dst, const cv::Point2d& srcPoint, cv::Point2i& dstPixel) {
double newX = srcPoint.x;
double newY = srcPoint.y;
double dx = abs(newX - round(newX));
double dy = abs(newY - round(newY));
double sumCubicBValue = 0;
double sumCubicGValue = 0;
double sumCubicRValue = 0;
double sumCubicGrayValue = 0;
double uX = 0;
double uY = 0;
if (floor(newX) - 1 < 0 || floor(newX) + 2 > src.cols - 1 || floor(newY) < 0 || floor(newY) > src.rows - 1) {
if (dst.channels() > 1)
dst.at<cv::Vec3b>(dstPixel) = cv::Vec3b(0, 0,0);
else
dst.at<uchar>(dstPixel) = 0;
}
else {
for (int cNeighbor = -1; cNeighbor <= 2; cNeighbor++) {
for (int rNeighbor = -1; rNeighbor <= 2; rNeighbor++) {
uX = cubicEquationSolver(rNeighbor + dx, -0.5);
uY = cubicEquationSolver(cNeighbor + dy, -0.5);
if (src.channels() > 1) {
sumCubicBValue = sumCubicBValue + (double) src.at<cv::Vec3b>(
cv::Point2i(round(newX) + rNeighbor, cNeighbor + round(newY)))[0] * uX * uY;
sumCubicGValue = sumCubicGValue + (double) src.at<cv::Vec3b>(
cv::Point2i(round(newX) + rNeighbor, cNeighbor + round(newY)))[1] * uX * uY;
sumCubicRValue = sumCubicRValue + (double) src.at<cv::Vec3b>(
cv::Point2i(round(newX) + rNeighbor, cNeighbor + round(newY)))[2] * uX * uY;
} else {
sumCubicGrayValue = sumCubicGrayValue + (double) src.at<uchar>(
cv::Point2i(round(newX) + rNeighbor, cNeighbor + round(newY))) * uX * uY;
}
}
}
if (dst.channels() > 1)
dst.at<cv::Vec3b>(dstPixel) = cv::Vec3b((int) round(sumCubicBValue), (int) round(sumCubicGValue),
(int) round(sumCubicRValue));
else
dst.at<uchar>(dstPixel) = sumCubicGrayValue;
}
I hope someone here will be able to help me, Thanks!
I have been trying to implement the meanshift algorithm for tracking objects, and have gone through the concepts involved.
As per now I have managed to successfully generate a backprojected stream from my camera with a single channel hue roi histogram and a single channel hue video stream which seems fine, I know there is a meanshift function within the opencv library but I am trying to implement one myself using the data structures provided in opencv, calculating the moments and computing the mean centroid of the search window.
But for some reason I am unable to locate the problem within my code as it keeps on converging to the upper left corner of my video stream for any input roi (region of interest) to be tracked. Following is a code snippet of the function for calculating the centroid of the search window where I feel the problem lies but not sure what it is, I would really appreciate if someone can point me in the right direction:
void moment(Mat &backproj, Rect &win){
int x_c, y_c, x_c_new, y_c_new;
int idx_row, idx_col;
double m00 = 0.0 , m01 = 0.0 , m10 = 0.0 ;
double res = 1.0, TOL = 0.003 ;
//Set the center of search window as the center of the probabilistic image:
y_c = (int) backproj.rows / 2 ;
x_c = (int) backproj.cols / 2 ;
//Centroid search solver until residual below certain tolerance:
while (res > TOL){
win.width = (int) 80;
win.height = (int) 60;
//First array element at position (x,y) "lower left corner" of the search window:
win.x = (int) (x_c - win.width / 2) ;
win.y = (int) (y_c - win.height / 2);
//Modulo correction since modulo of negative integer is negative in C:
if (win.x < 0)
win.x = win.x % backproj.cols + backproj.cols ;
if (win.y < 0)
win.y = win.y % backproj.rows + backproj.rows ;
for (int i = 0; i < win.height; i++ ){
//Traverse along y-axis (height) i.e. rows ensuring wrap around top/bottom boundaries:
idx_row = (win.y + i) % (int)backproj.rows ;
for (int j = 0; j < win.width; j++ ){
//Traverse along x-axis (width) i.e. cols ensuring wrap around left/right boundaries:
idx_col = (win.x + j) % (int)backproj.cols ;
//Compute Moments:
m00 += (double) backproj.at<uchar>(idx_row, idx_col) ;
m10 += (double) backproj.at<uchar>(idx_row, idx_col) * i ;
m01 += (double) backproj.at<uchar>(idx_row, idx_col) * j ;
}
}
//Compute new centroid coordinates of the search window:
x_c_new = (int) ( m10 / m00 ) ;
y_c_new = (int) ( m01 / m00 );
//Compute the residual:
res = sqrt( pow((x_c_new - x_c), 2.0) + pow((y_c_new - y_c), 2.0) ) ;
//Set new search window centroid coordinates:
x_c = x_c_new;
y_c = y_c_new;
}
}
It's my second ever query on stackoverflow so please excuse me for any guidelines that I forgot to follow.
EDIT
changed m00 , m01 , m10 to block level variables within WHILE-LOOP instead of function level variables, thanks to Daniel Strul for pointing it out but the problem still remains. Now the search window jumps around the frame boundaries instead of focusing on the roi.
void moment(Mat &backproj, Rect &win){
int x_c, y_c, x_c_new, y_c_new;
int idx_row, idx_col;
double m00 , m01 , m10 ;
double res = 1.0, TOL = 0.003 ;
//Set the center of search window as the center of the probabilistic image:
y_c = (int) backproj.rows / 2 ;
x_c = (int) backproj.cols / 2 ;
//Centroid search solver until residual below certain tolerance:
while (res > TOL){
m00 = 0.0 , m01 = 0.0 , m10 = 0.0
win.width = (int) 80;
win.height = (int) 60;
//First array element at position (x,y) "lower left corner" of the search window:
win.x = (int) (x_c - win.width / 2) ;
win.y = (int) (y_c - win.height / 2);
//Modulo correction since modulo of negative integer is negative in C:
if (win.x < 0)
win.x = win.x % backproj.cols + backproj.cols ;
if (win.y < 0)
win.y = win.y % backproj.rows + backproj.rows ;
for (int i = 0; i < win.height; i++ ){
//Traverse along y-axis (height) i.e. rows ensuring wrap around top/bottom boundaries:
idx_row = (win.y + i) % (int)backproj.rows ;
for (int j = 0; j < win.width; j++ ){
//Traverse along x-axis (width) i.e. cols ensuring wrap around left/right boundaries:
idx_col = (win.x + j) % (int)backproj.cols ;
//Compute Moments:
m00 += (double) backproj.at<uchar>(idx_row, idx_col) ;
m10 += (double) backproj.at<uchar>(idx_row, idx_col) * i ;
m01 += (double) backproj.at<uchar>(idx_row, idx_col) * j ;
}
}
//Compute new centroid coordinates of the search window:
x_c_new = (int) ( m10 / m00 ) ;
y_c_new = (int) ( m01 / m00 );
//Compute the residual:
res = sqrt( pow((x_c_new - x_c), 2.0) + pow((y_c_new - y_c), 2.0) ) ;
//Set new search window centroid coordinates:
x_c = x_c_new;
y_c = y_c_new;
}
}
The reason your algorithms always converges to the upper left corner independently of the input data is that m00, m10 and m01 are never reset to zero:
On iteration 0, for each moment variable m00, m10 and m01, you compute the right value m0
Between iteration 0 and iteration 1 , the moments variables are not reset and keep their previous value
Thus, on iteration 1, for each moment variable m00, m10 and m01, you actually sum the new moment with the old one and obtain ( m0 + m1 )
On iteration 2, you carry on summing the new moments on top of the previous ones and obtain ( m0 + m1 + m2 )
And so on, iteration by iteration.
At the very least, the moment variables should be reset at the beginning of each iteration.
Ideally, they should not be function-level variables but should rather be block-level variables, as they have no use outside the loop iterations (except for debugging purpose):
while (res > TOL){
...
double m00 = 0.0, m01 = 0.0, m10 = 0.0;
for (int i = 0; i < win.height; i++ ){
...
EDIT 1
The reason for the second problem you encounter (the ROI jumping all around the place) is that the computations of the moments are based on the relative coordinates i and j.
Thus, what you compute is [ avg(j) , avg(i) ], wher as what you really want is [ avg(y) , avg(x) ]. To solve this issue, I had proposed a first solution. I"ve replaced it by a much simpler solution below.
EDIT 2
The simplest solution is to add the coordinates of the ROI corner right at the end of each iteration:
x_c_new = win.x + (int) ( m10 / m00 ) ;
y_c_new = win.y + (int) ( m01 / m00 );
I'm working on a pretty cool project where I'm collecting data about the movement of a cursor, but I've run into an issue where I think I could use some help. I am constantly reading in data about the x and y position of the cursor (along with other relevant data), and once the cursor exceeds a certain threshold in the y-dimension, I need to calculate the movement direction (angle). Let me illustrate with a figure I drew:
What tends to happen is that the cursor moves in a somewhat straight line, but then curves towards the end of the movement. I need to calculate theta, i.e., the angle of the blue vector with respect to the positive x-axis. The idea I came up with is to use the last 2 samples to largely determine what the movement direction is, otherwise if I use too many samples I would skew what the actual angle is. To give an extreme case let me follow up with another picture:
Here each dot represents a sample. Note that if I use BOTH dots, the real angle I want will be wrong (again, I need to find the direction the cursor was moving in last, which is the vector drawn at the end of the line). I dont expect this case to come up much, but was wondering if there would be a way to solve for it if it does.
Lastly, note that the these motions can occur in either the first or second quadrant, if that makes a difference.
I'd really appreciate any help here. I'm coding this in C++ but I think I could translate any answer. Thanks.
This should get you started http://jsfiddle.net/0ao9oa7a/
Get all of the recorded points
Filter out points that are close together (I use 5 pixels)
Find the angles of each consecutive pair of points (atan2)
Find the absolute differences between each consecutive pair of angles
Throw away all of the angles before the max difference
Average the remaining angles (average all point vectors then atan2 back into an angle)
Code
function process(points) {
if(points.length === 0) {
txt = "Not enough points\n" + txt;
return null;
}
// compress points, removing those that are too close together
var newPoints = [];
newPoints.push(points[0]);
for(var i = 1; i < points.length; i++) {
if(Math.sqrt(Math.pow(points[i].x - newPoints[newPoints.length - 1].x, 2) + Math.pow(points[i].y - newPoints[newPoints.length - 1].y, 2)) > 5) {
newPoints.push(points[i]);
}
}
points = newPoints;
if(points.length < 2) {
txt = "Not enough points\n" + txt;
return null;
}
// get all of the angles
var angles = [];
for(var i=0; i < points.length - 1; i++) {
var rad = Math.atan2(points[i + 1].y - points[i].y, points[i + 1].x - points[i].x);
angles[i] = rad;
txt += "x: " + (points[i].x|0) + " y: " + (points[i].y|0) + " x: " + (points[i+1].x|0) + " y: " + (points[i+1].y|0) + " [" + ((rad * 180 / Math.PI)|0) + "]" + "\n";
}
txt += "\n";
// get all of the diffs between angles
// save the index of the max diff
var absDiffs = [];
var maxDiff = -1;
var maxDiffAngleIndex = -1;
for(var i=0; i < points.length - 1; i++) {
var delta = Math.abs(angles[i] - angles[i + 1]);
if(delta >= maxDiff) {
maxDiff = delta;
maxDiffAngleIndex = i + 1;
}
}
if(maxDiffAngleIndex == -1) {
txt = "Angle: " + angles[0] + " : " + (angles[0] * 180 / Math.PI) + "\n" + txt;
return angles[0];
} else if(maxDiffAngleIndex == angles.length - 1) {
txt = "Angle: " + angles[angle.length - 1] + " : " + (angles[angles.length - 1] * 180 / Math.PI) + "\n" + txt;
return angles[angles.length - 1];
} else {
// find the average angle from the index to the end
var sumX = 0;
var sumY = 0;
for(var i = maxDiffAngleIndex; i < angles.length; i++) {
sumX += Math.cos(angles[i]);
sumY += Math.sin(angles[i]);
}
var avgX = sumX / (angles.length - maxDiffAngleIndex);
var avgY = sumY / (angles.length - maxDiffAngleIndex);
//
var avgAngle = Math.atan2(avgY, avgX);
txt = "Angle: " + avgAngle + " : " + (avgAngle * 180 / Math.PI) + "\n" + txt;
return avgAngle;
}
}
As I can see, the “movement direction” (angle) of a point would be the angular coefficient of two dots, one dot at the end of the vector and the other one at the begnning.
Cause we can only find the angle with two dots, so we can make a line, since the direction vector would be (B-A), where A and B are the points I already told you about.
We can calcule this using the formula of the angular coefficient of a line:
m = Tan θ = Δy / Δx
And that is simply:
Tan θ = (yB – yA) / (xB – xA)
Where θ is the “movement direction” (angle) and (x,y) are the coordinates of the points A and B.
Talking about the quadrant, you will only need to use the trigonometric circle to know the sinal of the value of Tan θ, so take a look at this image:
And of course, after you find the value of Tan θ, you will need to use it to find the arctan θ, and that will be your final answer.
I have to draw an arrow. I have a head point and a tail point now i need to draw a triangular arrow cap. A triangle whose length is of size 5.How can i find coordinates of the end points of triangle. One thing is we have angle of 45.so if we can rotate the vector by 45 to obtain it.
` int x1=arrowStart.X;
int y1=arrowStart.Y;
int x2=arrowend.X;
int y2=arrowend.Y;
PointF arrowPoint=arrowend;
double arrowlength=sqrt(pow(x1-x2,2)+pow(y1-y2,2));
int ArrowMultiplier=1;
double arrowangle=atan2(y1-y2,x1-x2);
double pointx,pointy;
if(x1>x2)
{
pointx=x1 - (cos(arrowangle) * (arrowlength-3 * ArrowMultiplier ));
}
else
{
pointx = cos(arrowangle) * (arrowlength-3 * ArrowMultiplier ) + x1;
}
if (y1 > y2)
{
pointy = y1 - (sin(arrowangle) * (arrowlength -3 * ArrowMultiplier));
}
else
{
pointy = (sin(arrowangle) * (arrowlength-3 * ArrowMultiplier )) + y1;
}
PointF arrowPointBack(pointx,pointy);
double angleB = atan2((3 * ArrowMultiplier), (arrowlength - (3 * ArrowMultiplier)));
double angleC = (3.14) * (90 - (arrowangle * (180 /3.14)) - (angleB * (180 / 3.14))) / 180;
double secondaryLength = (3 * ArrowMultiplier)/sin(angleB);
if (x1 > x2)
{
pointx = x1 - (sin(angleC) * secondaryLength);
}
else
{
pointx = (sin(angleC) * secondaryLength) + x1;
}
if (y1 > y2)
{
pointy = y1 - (cos(angleC) * secondaryLength);
}
else
{
pointy = (cos(angleC) * secondaryLength) + y1;
}
PointF arrowPointLeft((float)pointx, (float)pointy);
angleC = arrowangle - angleB;
if (x1 > x2)
{
pointx = x1 - (cos(angleC) * secondaryLength);
}
else
{
pointx = (cos(angleC) * secondaryLength) +x1;
}
if (y1 > y2)
{
pointy =y1 - (sin(angleC) * secondaryLength);
}
else
{
pointy = (sin(angleC) * secondaryLength) + y1;
}
PointF arrowPointRight((float)pointx,(float)pointy);
PointF arrowPoints[4];
arrowPoints[0] = arrowPoint;
arrowPoints[1] = arrowPointLeft;
//arrowPoints[2] = arrowPointBack;
arrowPoints[2] = arrowPointRight;
arrowPoints[3] = arrowPoint;
`
Right, I suppose I should break it down for you:
First, you need to calculate the angle that the arrow sits at. This can be achieved with the inverse tangent function:
atan(diff_y, diff_x)
where diff_y and diff_x are the difference between the x and y values of your two end-points.
You can then add the desired angle of the arrow-head to this angle and use sin and cos to calculate the x and y values of the first of the extra points of the arrow-head.
new_x = head_x - 5 * cos (angle + pi/4)
new_y = head_y + 5 * sin (angle + pi/4)
for the other point, you do the same, but with a subtraction of the difference in angle.
new_x = head_x - 5 * cos (angle - pi/4)
new_y = head_y + 5 * sin (angle - pi/4)
You then have all the points you need.
I did this for fun (sue me, I was bored) and came up with this:
#include <math.h>
#include <iostream>
const double arrow_head_length = 3;
const double PI = 3.14159265;
const double arrow_head_angle = PI/6;
//returns the angle between two points, with coordinate1 describing the centre of the circle, with the angle progressing clockwise
double angle_between_points( std::pair<double,double> coordinate1, std::pair<double,double> coordinate2)
{
return atan2(coordinate2.second - coordinate1.second, coordinate1.first - coordinate2.first);
}
//calculate the position of a new point [displacement] away from an original point at an angle of [angle]
std::pair<double,double> displacement_angle_offset(std::pair<double,double> coordinate_base, double displacement, double angle)
{
return std::make_pair
(
coordinate_base.first - displacement * cos(angle),
coordinate_base.second + displacement * sin(angle)
);
}
int main()
{
std::pair<double,double> arrow_tail( 0, 0);
std::pair<double,double> arrow_head( 15,-15);
//find the angle of the arrow
double angle = angle_between_points(arrow_head, arrow_tail);
//calculate the new positions
std::pair<double,double> head_point_1 = displacement_angle_offset(arrow_head, arrow_head_length, angle + arrow_head_angle);
std::pair<double,double> head_point_2 = displacement_angle_offset(arrow_head, arrow_head_length, angle - arrow_head_angle);
//output the points in order: tail->head->point1->point2->head so if you follow them it draws the arrow
std::cout << arrow_tail.first << ',' << arrow_tail.second << '\n'
<< arrow_head.first << ',' << arrow_head.second << '\n'
<< head_point_1.first << ',' << head_point_1.second << '\n'
<< head_point_2.first << ',' << head_point_2.second << '\n'
<< arrow_head.first << ',' << arrow_head.second << std::endl;
}
The output can be saved as a .csv and loaded into excel for example, where you can use it to draw a connected scatter-graph that will form the shape of the arrow.
If this is homework, then before you do anything with it, make sure you know exactly how it works. That includes knowing the answers to questions like:
when calculating the angle, why does the code do point2_y-point1_y but point1_x-point2_x?
what direction is angle 0?
why does the angle increase going clockwise and not anti-clockwise?
why are there 5 outputs when only 4 points are needed?
what is the significance of PI/6 in the code? It isn't == 45 degrees. Why would this angle be better?
Also note that this question and answer will now pop up in a google search.
Working example: http://ideone.com/D4IwOy
You can paste the output into any graphing tool (such as this one) or save as a .csv and open in excel/spreadsheet of choice and plot a scatter graph to see the arrow coordinates. Note that it (annoyingly) doesn't keep the x and y scales equal so will stretch arrows like this one:
3,7
24,15
21.0381,15.4768
22.1061,12.6734
24,15
I'm now trying to generate straight sync points on my 2D map path.
In other words I want to spilt distance between point A on map for example X : 301 Y : 679 to point B X : 360 Y : 630, every 8 unit of distance is passed.
Every 8 distance unit calculated by sqrt(pow(a_x - b_x, 2), pow(a_y - b_y, 2)). I want to obtain next coordinates on map, like by a a_x + distance and b_y + distance.
I tried to do it but it didn't work, x axis doesnt change propertly.
Here is my code :
float base_x = active->getX();
float base_y = active->getY();
float destx = incoming_packet.get()->getFloat(4);
float desty = incoming_packet.get()->getFloat(8);
float distance = active->distance(destx, desty); // calculated by sqrt(pow(curent character x pos - destx, 2), pow(current character y pos - desty, 2))
float delta_X = active->vDistance(base_x, destx); // calculated by sqrt(pow(base_x - destx, 2))
float delta_Y = active->vDistance(base_y, desty); // calculated by sqrt(pow(base_y - desty, 2))
float cosa = delta_X / distance;
float sina = delta_Y / distance;
int mapx = 1;
int mapy = 1;
if(distance > 8)///active sync
{
for(float dist = 8; dist < distance;dist+=8)
{
base_x += mapx * (cosa * 8);
base_y += mapy * (sina * 8);
BOOST_LOG_TRIVIAL(debug) << "[ACTIVESYNC]NEXT SYNC ACK X : " << base_x << " Y : " << base_y;
}
}
What I'm doing here wrong ?
"cosa" (and cosb) are apparently dimensionless. (i.e. meters / meters)
"mapx" (and "mapy") are also dimensionless.
Note that in your for loop, base_x, base_y describe a point on the map.
And the 2 interesting computations in that loop
base_x += mapx * (cosa * 8);
base_y += mapy * (sina * 8);
become meaningless by attempting to add dimensionless numbers to a point. It might be ok to multiply by dimensionless numbers, but it is unreasonable to add dimensionless numbers to map points.
I suggest cosa and cosb be changed to represent the distance (i.e. meters) for each step.
float cosa = delta_X / 8; // size of steps in x direction
float sina = delta_Y / 8; // size of steps in y direction
Now the for loop can add 8 steps of cosa and sina appropriately to describe the path way points, and cosa and sina both have appropriate dimensions for the next computation.
The for loop can simplify to :
for(int step = 0; step < 8; step += 1)
{
base_x += (mapx * cosa);
base_y += (mapy * sina);
// remove or adapt the following
std::cout << std::setw(10) << std::left << (step+1) << std::setw(10)
<< base_x << std::setw(10) << base_y << std::endl;
// you were using:
//BOOST_LOG_TRIVIAL(debug) << "[ACTIVESYNC]NEXT SYNC ACK X : "
// << base_x << " Y : " << base_y;
}
My dummy code outputs:
base x/y 301 679
dest x/y 360 630
delta x/y 59 -49
step_x = 7.375
step_y = -6.125
step base_x base_y
0 301 679
1 308.375 672.875
2 315.75 666.75
3 323.125 660.625
4 330.5 654.5
5 337.875 648.375
6 345.25 642.25
7 352.625 636.125
8 360 630
Do these way points look more what you are looking for?