World coordinates as float to chunk and pixel coordinates - c++

I have no idea right now for how to calculate pixel coordinates within the chunk.
I calculate the chunk from the world coordinates like this:
float xCoord = ..., yCoord = ...; //Can be positive and negative.
int xChunk = static_cast<int>(std::floor((xCoord + WORLD_OFFSET_X_F) / CHUNK_XY_SIZE_F));
int yChunk = static_cast<int>(std::floor((yCoord + WORLD_OFFSET_Y_F) / CHUNK_XY_SIZE_F));
It would be easy to calculate the pixel coordinates within the chunk if they were integers. Example:
int xCoord = ..., yCoord = ...; //Can be positive and negative.
int xPixel = (xCoord + WORLD_OFFSET_X_I) % CHUNK_XY_SIZE_I; Or by using the AND(&) operator.
int yPixel = (yCoord + WORLD_OFFSET_Y_I) % CHUNK_XY_SIZE_I;
This doesn't work by using floating point numbers. How can I accomplish the same results with floating point numbers?
Thanks in advance.

You can do it exactly the same way. You just have to use a floating point modulo instead of integer. Take a look at fmod

Related

C++: Rotating point around origin, but output point is not correct by some margin

first time asking.
I want to rotate a point in 3d in c++ in the XY Plane and am using the following function for the task.
void rotateXY(double angle){
//save the x and y and z coordinates in seperate variables
double x = this->pos[0]; // value 1
double y = this->pos[1]; // value 0
double z = this->pos[2]; // value 0, but in the xy rotation it is not important
double radian = angle*M_PI/180;
this->pos[0] = cos(radian)*x - sin(radian)*y;
this->pos[1] = sin(radian)*x + cos(radian)*y;
this->pos[2] = 1*z;
};
I got the matrix from https://gamedevelopment.tutsplus.com/tutorials/lets-build-a-3d-graphics-engine-linear-transformations--gamedev-7716
In this I am directly manipulating the coordinates of the point, hence the this->pos[0]
If I call another function called rotateXYP where I first substract a mathematical vector from the rotating point and add the same mathematical vector to it after the rotate I get the wanted results.
void rotateXYP(double angle, eng::point originOfRotation){
this->subVec(originOfRotation);
this->rotateXY(angle);
this->addVec(originOfRotation);
};
void rotateXY(double angle){
//save x,y and z in seperate variables for manipulation
double x = this->pos[0]; // value 1
double y = this->pos[1]; // value 0
double z = this->pos[2]; // value 0, but in the xy rotation it is not important
//convert from degrees to radians because cmath requires it
double radian = angle*M_PI/180;
//apply the values according to a rotation matrix found on the internet
this->pos[0] = cos(radian)*x - sin(radian)*y;
this->pos[1] = sin(radian)*x + cos(radian)*y;
this->pos[2] = 1*z;
};
My Question
Why am I getting with the point (1|0|0) as an input to the function rotateXY(90) the follwing as an output.
(6.12323e-17|1|0)
instead of
(0|1|0)
and if I call the function rotateXYP(90, some point), I get the correct point, without the tiny number on the x-coordinate.
I suspect it has something to do with the cos and sin in the following line of code:
this->pos[0] = cos(radian)*x - sin(radian)*y;
As I am too inexperienced with c++ I seek answeres and hope that this was not a bad question.
Your implementation is correct. This is just the nature of floating point arithmetic. All numbers are represented as approximations. When translating the point you get a better numeric condition.
I might add that this effect will occur independent of the programming language and hardware used.
I have solved my problem by adding a variable named accuracy which controls the number of decimal places the double is allowed to have.
void rotateXY(double angle){
//Accuracy: a is the number of decimal places
int a = 2;
int acc = pow(10,a);
//save x,y and z in seperate variables for manipulation
double x = this->pos[0]; // value 1
double y = this->pos[1]; // value 0
double z = this->pos[2]; // value 0, but in the xy rotation it is not important
//convert from degrees to radians because cmath requires it
double radian = angle*M_PI/180;
//apply the values according to a rotation matrix found on the internet
this->pos[0] = round((cos(radian)*x - sin(radian)*y)*acc)/acc;
this->pos[1] = round((sin(radian)*x + cos(radian)*y)*acc)/acc;
this->pos[2] = round((1*z)*acc)/acc;
};

C++: "Distance" between 2 coordinates in 2D array

For a game I'm writing I need to find an integer value for the distance between two sets of coordinates. It's a 2D array that holds the different maps. (Like the original zelda). The further you go from the center (5,5) the higher the number should be since the difficulty of enemies increases. Ideally it should be between 0 and 14. The array is 11x11.
Now, I tried to use the pythagoras formula that I remember from highschool, but it's spewing out overflow numbers. I can't figure out why.
srand(rand());
int distance=sqrt(pow((5-worldx), 2)-pow((5-worldy), 2));
if(distance<0) //alternative to abs()
{
distance+=(distance * 2);
}
if(distance>13)
{
distance=13;
}
int rnd=rand()%(distance+1);
Monster testmonster = monsters[rnd];
srand(rand()); does not make sense, it should be srand(time(NULL));
don't use pow for square, just use x*x
your formula is also wrong, you should add number together not minus
sqrt return double and cast to int will round it down
i think sqrt always return positive number
you know abs exists right? why not use it? also distance = -distance is better than distance+=(distance * 2)
srand(time(NULL));
int dx = 5 - worldx;
int dy = 5 - worldy;
int distance=sqrt(dx * dx + dy * dy);
if(distance>13)
{
distance=13;
}
int rnd=rand()%(distance+1);
Monster testmonster = monsters[rnd];
It's a^2 + b^2 = c^2, not minus. Once you call sqrt with a negative argument, you're on your own.
You're subtracting squares inside your square root, instead of adding them ("...-pow...").

c++ integer division

Say I've got
SDL_Rect rect;
rect.x = 5; // rect.x is of type "Uint16"
int y = 11;
and I want to perform the operation rect.x/y.
I want to get the result as a floating point number and then round up to the nearest int.
Something like this:
float result = rect.x/y;
int rounded = ceil(result);
How should I do this?
Cast either rect.x or y to float, and then do the division. This will force the entire division operation to take place in floating point.
float result = rect.x/(float)y;
int rounded = ceil(result);
You need to cast your variables.
float result = (float)rect.x / (float)y;
int rounded = ceil(result);
You can do this without any floating point types. If x and y are positive integers, then x divided by y, rounded up is (x+y-1)/y.

Scale x and y velocities to between -MAX and MAX in c++

I am trying to scale some x and y velocity values to be between -MAX and MAX and maintain their proportions. The numbers can be negative, zero, or positive. This is being used to enforce a speed limit on x and y velocities. Here's what I've got:
if(abs(velocities.x) <= MAX_TRANSLATIONAL_VELOCITY && abs(velocities.y) <= MAX_TRANSLATIONAL_VELOCITY)
return;
float higher = max(abs(velocities.x), abs(velocities.y));
velocities.x = (velocities.x / higher) * MAX_TRANSLATIONAL_VELOCITY;
velocities.y = (velocities.y / higher) * MAX_TRANSLATIONAL_VELOCITY;
This is not really working and the robots I'm applying it to are kind of spazzing out. Is there a standard way to accomplish this?
Thanks.
To normalize a vector you shouldn't divide its components by the maximum of any of them but by their magnitude which is the euclidean norm of the vector.
Actually you shouldn't check a single component, first you calculate magnitude, then if it's over MAX_MAGNITUDE, you normalize the vector and multiply it by MAX_MAGNITUDE.
float magnitude = sqrt(v.x*v.x + v.y*v.y);
if (magnitude > MAX_MAGNITUDE)
{
v /= magnitude; // I'm assuming overloaded operators here
v *= MAX_MAGNITUDE;
}

Getting closest point on grid to point

I have a one dimensional gird. its spacing is a floating point. I have a point with floating point coordinate as well. I need to find its distance to the closest grid point.
For example:
0.12
|
*
|---------|---------|---------|---------|---------|
0 0.1 0.2 0.3 0.4 0.5
The result would be -0.02 since the closest point is behind it.
However if it was
-0.66
|
*
|---------|---------|---------|---------|---------|
-1 -0.8 -0.6 -0.4 -0.2 0
The result will be 0.06. As you can see its in floating point and can be negative.
I tried the following:
float spacing = ...;
float point = ...;
while(point >= spacing) point -= spacing;
while(point < 0) point += spacing;
if(std::abs(point - spacing) < point) point -= spacing;
It works, but I'm sure there is a way without loops
Let us first compute the nearest points on the left and right as follows:
leftBorder = spacing * floor(point/spacing);
rightBorder = leftBorder + spacing;
Then the distance is straightforward:
if ((point - leftBorder) < (rightBorder - point))
distance = leftBorder - point;
else
distance = rightBorder - point;
Note that, we could find the nearest points alternatively by ceiling:
rightBorder = spacing * ceil(point/spacing);
leftBorder = rightBorder - spacing;
std::vector<float> spacing = ...;
float point = ...;
float result;
Since you say the spacing isn't (linear), I would cache the sums:
std::vector<float> sums(1, 0.0);
float sum=0;
for(int i=0; i<spacing.size(); ++i)
sums.push_back(sum+=spacing[i]);
//This only needs doing once.
//sums needs to be in increasing order.
Then do a binary search to find the point to the left:
std::vector<float>::iterator iter;
iter = std::lower_bound(sums.begin(), sums.end(), point);
Then find the result from there:
if (iter+1 == sums.end())
return point-*iter;
else {
float midpoint = (*iter + *(iter+1))/2;
if (point < midpoint)
result = point - *iter;
else
result = *(iter+1) - point;
}
[EDIT] Don't I feel silly. You said the spacing wasn't constant. I interpreted that as not-linear. But then your sample code is linear, just not a compile-time constant. My bad. I'll leave this answer as a more general solution, though your (linear) question is solvable much faster.
Here is my first blush attempt, note that this is not tested at all.
float remainder = fmod(point, spacing); // This is the fractional difference of the spaces
int num_spaces = point/spacing; // This is the number of "spaces" down you are, rounded down
// If our fractional part is greater than half of the space length, increase the number of spaces.
// Not sure what you want to do when the point is equidistant to both grid points
if(remainder > .5 * spacing)
{
++num_spaces;
}
float closest_value = num_spaces*spacing;
float distance = closest_value - point;
You should just round the number using this:
float spacing = ...;
float point = ...;
(point > 0.0) ? floor(point + spacing/2) : ceil(point - spacing/2);
Much, much more generally, for arbitrary spacing, dimensions, and measures of distance (metric), the structure you're looking for would be a Voronoi Diagram.