How to rotate a point every second - c++

I have a point that I want to rotate that corresponds to every second in time like a second hand in a clock, it should rotate 6 degrees every second but i tried timing it and it does not take a minute to make a full rotation, here is the code
void rotate(const float& ox, const float& oy, float &x, float &y, const float& rotation) {
float tx = x-ox;
float ty = y-oy;
float nx = tx*cos(rotation) - ty*sin(rotation);
float ny = tx*sin(rotation) + ty*cos(rotation);
x = nx+ox;
y = ny+oy;
}
float origx = 1280/2, origy = 720/2, pntx = origx, pnty = origy-300, rotation=6; // variables
rotate(origx, origy, pntx, pnty, rotation*timer.delta); // update point, timer is an object that gets the delta time between frames of the main loop

Need to update the values for your variables like:
your origx should be 90 deg which is 0.5π rad
your origy should also be 90 deg which is 0.5π rad
every second step (rotation) is 6 deg which is 0.033333333333π rad
For sin and cos takes radians in the argument and not degrees.

Related

How to move object towards an angle in degrees? (C, C++)

I'm trying to move a bullet object towards a player position. I found this angle function online, and it seems to convert it to those coordinates in the comments. But i can't make the bullet follow in the direction.
float Angle(int p1x, int p1y, int p2x,int p2y)
{
//Make point1 the origin, make point2 relative to the origin so we do point1 - point1, and point2-point1,
//since we dont need point1 for the equation to work, the equation works correctly with the origin 0,0.
int deltaY = p2y - p1y;
int deltaX = p2x - p1x; //Vector 2 is now relative to origin, the angle is the same, we have just transformed it to use the origin.
float angleInDegrees = atan2(deltaY, deltaX) * 180 / PI;
//float angleInRadians = atan2(deltaY, deltaX);
angleInDegrees *= -1; // Y axis is inverted in computer windows, Y goes down, so invert the angle.
//Angle returned as:
// 90
// 135 45
//
// 180 Origin 0
//
// -135 -45
//
// -90
return angleInDegrees;
}
if (bulletsData[3] == STDEACTIVE){ //bulletData: 0 = x, 1 = y, 2 = dir, 3 = state
bulletsData[2] = Angle(bulletsData[0],bulletsData[1], plData[0], plData[1]);
bulletsData[3] = STACTIVE;
}
if (bulletsData[3] == STACTIVE){
if (ardu.everyXFrames(1)){
bulletsData[0] += cos(bulletsData[2]) * 1; //My attempt to move it towards the direction.
bulletsData[1] += sin(bulletsData[2]) * 1;
}
}
You are explicitly calculating angles in degrees, yet sin and cos expect radians, not degrees.
Without analyzing whether or not the Angle function is correct, your code will make more sense if you change the function to return a value in radians. You even have the required line there commented out.
So, something like this perhaps:
float angleInRadians = atan2(deltaY, deltaX);
return -angleInRadians; // Return negative angle to compensate for Y-down

Why is my vector rotation function changing the vector's magnitude?

I'm looking to make a simple function that rotates a vector's point b around point a for a given number of degrees.
What's odd is that my code seems to work somewhat - the vector is rotating, but it's changing length pretty drastically.
If I stop erasing the screen every frame to see every frame at once, I see the lines producing a sort of octagon around my origin.
Even weirder is that the origin isn't even in the center of the octagon - it's in the bottom left.
Here's my code:
struct Point { int x, y; };
struct Line {
Point a, b;
void rotate(double);
};
void Line::rotate(double t)
{
t *= 3.141592 / 180;
double cs = cos(t);
double sn = sin(t);
double trans_x = (double)b.x - a.x;
double trans_y = (double)b.y - a.y;
double newx = trans_x * cs - trans_y * sn;
double newy = trans_x * sn + trans_y * cs;
newx += a.x;
newy += a.y;
b.x = (int)newx;
b.y = (int)newy;
}
Using the olc::PixelGameEngine to render, which is why I'm using ints to store coordinates.

Accelerate to X velocity in Y seconds

How can I get something to go from X to Xgoal velocity in Y seconds?
The goalVelocity is set to (100, 100) and it does approach it but it takes way too long to get there.
I can multiply frameDelta by some number like 20 or 100 but I want to find out what to multiply frameDelta by to get it to reach goalVelocity in some number of seconds.
velocity, goalVelocity and origin are all Vec2f and frameDelta is a float
Right now I have this code:
velocity = approach(goalVelocity, velocity, frameDelta);
origin = origin + velocity * frameDelta;
The code for approach is:
inline float approach(float flGoal, float flCurrent, float dt)
{
float flDifference = flGoal - flCurrent;
if (flDifference > dt)
return flCurrent + dt;
if (flDifference < -dt)
return flCurrent - dt;
return flGoal;
}
inline Vec2f approach(Vec2f flGoal, Vec2f flCurrent, float dt)
{
return Vec2f(approach(flGoal.x, flCurrent.x, dt), approach(flGoal.y, flCurrent.y, dt));
}
Maybe I misunderstood your Question, but acceleration is just speed difference divided by time, so just multiply dt with X/Y.
A basic physics engine should look something like
Vec2f position, velocity, acceleration;
while (true)
{
acceleration = button ? thrust : 0;
velocity += acceleration * timeDelta;
position += velocity * timeDelta
redraw space ship at position;
sleep (timeDelta);
}
if you want to go from 0 to X velocity in Y seconds, then thrust = X/Y.

Wave vector in 2 dimensions

So I'm trying to make the player shoot a bullet that goes towards the mouse in a wavey pattern. I can get the bullet to move in a wavey pattern (albeit not really how I predicted), but not towards the mouse.
Vector2 BulletFun::sine(Vector2 vec) {
float w = (2 * PI) / 1000; // Where 1000 is the period
float waveNum = (2 * PI) / 5; // Where 5 is the wavelength
Vector2 k(0.0F, waveNum);
float t = k.dot(vec) - (w * _time);
float x = 5 * cos(t); // Where 5 is the amplitude
float y = 5 * sin(t);
Vector2 result(x, y);
return result;
}
Right now the speed isn't much of a concern, that shouldn't be too much of a problem once I have this figured out. I do get some angle change, but it seems to be reversed and only 1/8th a circle.
I'm probably miscalculating something somewhere. I just kind of learned about wave vectors.
I've tried a few other things, such as 1 dimensional travelling waves and another thing involving adjusting a normal sine wave by vec. Which had more or less the same result.
Thanks!
EDIT:
vec is the displacement from the player's location to the mouse click location. The return is a new vector that is adjusted to follow a wave pattern, BulletFun::sine is called each time the bullet receives and update.
The setup is something like this:
void Bullet::update() {
_velocity = BulletFun::sine(_displacement);
_location.add(_velocity); // add is a property of Tuple
// which Vector2 and Point2 inherit
}
In pseudocode, what you need to do is the following:
waveVector = Vector2(travelDistance,amplitude*cos(2*PI*frequency*travelDistance/unitDistance);
cosTheta = directionVector.norm().dot(waveVector.norm());
theta = acos(cosTheta);
waveVector.rotate(theta);
waveVector.translate(originPosition);
That should compute the wave vector in a traditional coordinate frame, and then rotate it to the local coordinate frame of the direction vector (where the direction vector is the local x-axis), and then translate the wave vector relative to your desired origin position of the wave beam or whatever...
This will result in a function very similar to
Vector2
BulletFun::sine(Bullet _bullet, float _amplitude, float _frequency, float _unitDistance)
{
float displacement = _bullet.getDisplacement();
float omega = 2.0f * PI * _frequency * _displacement / _unitDistance;
// Compute the wave coordinate on the traditional, untransformed
// Cartesian coordinate frame.
Vector2 wave(_displacement, _amplitude * cos(omega));
// The dot product of two unit vectors is the cosine of the
// angle between them.
float cosTheta = _bullet.getDirection().normalize().dot(wave.normalize());
float theta = acos(cosTheta);
// Translate and rotate the wave coordinate onto
// the direction vector.
wave.translate(_bullet.origin());
wave.rotate(theta);
}

Make Objects Follow Mouse

Other questions close to this topic don't seem to help me understand it very much. I'm just starting programming using Visual Studio and Direct2D and I'm having trouble understanding how to make two "eyes," which are ellipses inside of ellipses, follow my mouse.
Inside of the function void MainWindow::CalculateLayout() I'm using
const float radius3=radius/4;
const float radius3_2=radius/5;
const float x3=x-100;
const float y3=y-150;
ellipse3 = D2D1::Ellipse(D2D1::Point2F(x3, y3), radius3, radius3_2);
//left eye
const float radius4=radius/4;
const float radius4_2=radius/5;
const float x4=x+100;
const float y4=y-150;
ellipse4 = D2D1::Ellipse(D2D1::Point2F(x4, y4), radius4, radius4_2);
//right eye
const float radius5=radius/8;
const float radius5_2=radius5/2;
const float x5=x-100;
const float y5=y-150;
ellipse5 = D2D1::Ellipse(D2D1::Point2F(x5, y5), radius5, radius5_2);
// left eyeball
const float radius6=radius/8;
const float radius6_2=radius6/2;
const float x6=x+100;
const float y6=y-150;
ellipse6 = D2D1::Ellipse(D2D1::Point2F(x6, y6), radius6, radius6_2);
// right eyeball
to set up where the eyes and eyeballs are. I think that something along the line of this should be used to control where the mouse is. I am trying to do this from a blank project, not from a form. Is the solution to simply replace const float x5=x-100 with the X value of MouseMove?
You need to replace the definition of x5, but you need to do it with a formula which will bound it to stay within the eyeball.
Your formula will look something like this:
// compute the angle from the eyes to the mouse
angle = arctan( (mouseY - y) / (mouseX - x) );
// x-100 and y-150 are assumed to be the origins (center) of the eyeball
// eyeballRadius should be the radius of the eyeball, or slightly smaller (so the eyes do not extend outside of it)
x5 = (x-100) + cos(angle) * eyeballRadius;
y5 = (y-150) + sin(angle) * eyeballRadius;
Hope this helps.
To get the cross-eyed effect when the cursor is very near, you should have each eyeball compute its own angle, for example the left's would be leftAngle = arctan( (mouseY - (y-150)) / (mouseX - (x-100)) )