Texture rotating around background withut mouse in Monogame, c# - c#

Im trying to rotate a texture in Monogame ! It schould rotate around another object like doing a circle (not routate the texture it self ), it schould do a circle rotate. It schould not rotate with the mouse but continosly rotating in that radius itself. Im new in MOnogame and a tried everything for two last days and nothing worked. Some said that i schould do somethink with Sin and Cos but i didnt get it ! Its for a project and im very lost ! I would be very very greatfull if someone could help me ! [So this logo schould routate around the background ][2]
Link to picture https://www.dropbox.com/s/gywi7teun8lqfp1/Unbenannt.png?dl=0

This is a pure math problem. From what i can understand, what you want is to make your texture orbit around a point, see this formula :
newX = centerX + ( cosX * (pointX-centerX) + sinX * (pointY -centerY))
newY = centerY + ( -sinX * (pointX-centerX) + cosX * (pointY -centerY))
With : centerX and centerY being the point around you want to orbit
cosX and sinX being respectively the cosinus of the angle and the sinus of the angle
pointX and pointY being the position you want to apply rotation from (the texture position in your case)
Note that the angle should be in radians, and not in degrees.

Answers to this question can be found here:
Have an object circle an object
There are also examples of how to use Math in MonoGames
If you want to use a matrix and let the api rotate for you you could try something like this
public Vector2 RotateAboutOrigin(Vector2 point, Vector2 origin, float rotation)
{
return Vector2.Transform(pointorigin,Matrix.CreateRotationZ(rotation))+origin;
}

Related

Problems using camera in OpenGL

Hi, I am making an application which can make camera rotate around the model, I have successfully imported the obj format model
But I meet the problem when rotate the camera, the model will disappear as you can see
gl.Perspective(180, (double)Width / (double)Height, 100, 50000f);
The key code for rotating camera:
Calculate the center point of the model
currentX = Math.Sin(angle) * radius;
currentZ = Math.Cos(angle) * radius;
gl.LookAt(currentX,0,currentZ,
centerPoint.X, centerPoint.Y, centerPoint.Z,
0, 1, 0
);
Try modifying the near clipping plane to be much closer to the camera, and also lower the FoV angle. Try this:
gl.Perspective(90, (double)Width/(double)Height, 0.01f, 100.0f);
Check if the model is not closer than the near clipping plane. Check also the face culling: if your camera is inside the mesh, you are looking at the back faces of the polygons, which probably are not rendered.

Arrow rotating to face cursor needs to only do so while inside an angle made by two given directions

I have a 2d arrow rotating to always face the a target (the target in this case is the cursor), the pivot is my player character. I need to restrict this arrow to only follow the target if it is inside an angle of the player, an example would be 90 degrees, so it would only follow if the cursor is in the top right part of the screen.
I have worked with vector directions and methods such as Vector2D.angle, but they all seem to have some restriction i can't workaround, Vector2D.angles restriction is that the 3rd position it uses to calculate the angle is the world center(0, 0), my player is mobile so that doesn't work.
So i think what im asking is if theres a way to store an angle, and then check if something is within that.
Here is the code i use for rotating my arrow, theres more to the script but i removed the unnecesary parts:
public float speed;
public Transform target;
void Update()
{
Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 direction = target.position - transform.position;
target.position = mousePosition;
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
Quaternion rotation = Quaternion.AngleAxis(angle, Vector3.forward);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, speed * Time.deltaTime);
Sorry if this is formatted poorly, its my first time posting here, thank you a million times if you are able to help me, i have been stuck on this for days.
Was asked to clarify question so here is an attempt:
This picture shows an example of what i mean, the arrow is rotating around the center of the circle, (it is rotating so it always points towards my cursor). What i need is a way to restrict it so it only points towards the cursor if it is within a specific angle (red lines in picture), that's what im having trouble with. I can't find a way to store this threshold and i can't seem to find a way to compare the cursors direction with it.
I think it would be possible if it was possible to choose a custom center for Vector2D.angle, but that doesn't seem to be the case.
I hope this clarifies what my question, i may just very well be stupid and overlooking something obvious but i really can't find a way to make this possible.
thanks again.
Important fields/inputs
First, we need to know the boundary directions in world space:
public Vector2 boundaryDirectionLeft;
public Vector2 boundaryDirectionRight;
The important piece is that the angle made clockwise from boundaryDirectionLeft to boundaryDirectionRight is the region the arrow shall remain inside. In the case of your image, boundaryDirectionLeft could be Vector2.up and boundaryDirectionRight could be something like new Vector2(1f,-1f).
We also need to know which local direction the arrow is facing before any rotation is applied. E.g., if the arrow is always pointing with the local red arrow axis (the local right direction), this would be Vector2.right:
public Vector2 localArrowDirection;
And lastly, we need a top speed for our rotation, so we don't warp the arrow around when it's time to rotate. A good value to start with might be 360f, 360 degrees per second. Try experimenting with different values to find one that you like:
public float maxRotationSpeed;
The update procedure
In Update, determine the direction to the target:
Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 direction = mousePosition - transform.position;
Then, we need to know where the arrow is currently pointing. We can use Transform.TransformVector to find where the local localArrowDirection is pointing in world space:
Vector2 currentDirection = transform.TransformVector(localArrowDirection);
Then, determine the signed angle from boundaryDirectionLeft to the target direction, the same from boundaryDirectionLeft to boundaryDirectionRight, and the same from boundaryDirectionLeft to the current facing direction:
float directionAngle = Vector2.SignedAngle(boundaryDirectionLeft, direction);
float boundaryAngle = Vector2.SignedAngle(boundaryDirectionLeft, boundaryDirectionRight);
float currentAngle = Vector2.SignedAngle(boundaryDirectionLeft, currentDirection);
These values range from [-180,180], but we want them expressed in the range [0,360) to make the math easier later, so we can add 360f and use Mathf.Repeat on that sum:
directionAngle = Mathf.Repeat(directionAngle+360f, 360f);
boundaryAngle = Mathf.Repeat(boundaryAngle+360f, 360f);
currentAngle = Mathf.Repeat(currentAngle+360f, 360f);
At this point directionAngle is how many clockwise degrees from boundaryDirectionLeft that target is, and boundaryAngle is how many boundaryDirectionRight is, and currentAngle is the same for what direction we're currently facing.
So, now, we need to know how to properly clamp the angle between 0 and boundaryAngle. Anything too far above boundaryAngle is actually closer to the left boundary and should be clamped to the left boundary. In fact, since everything is between 0 and 360, anything higher than boundaryAngle+(360f-boundaryAngle)/2f is closer to the left. So, we just set anything higher than that to be 0 degrees away from boundaryDirectionLeft:
if (directionAngle > boundaryAngle + (360f - boundaryAngle)/2f)
{
directionAngle = 0f;
}
So, now we can clamp directionAngle with a high of boundaryAngle (it is already bottom clamped at 0f, so we can use Mathf.Min here):
directionAngle = Mathf.Min(directionAngle, boundaryAngle);
Now we can limit the angular difference between directionAngle and currentAngle using our maxRotationSpeed:
float deltaAngle = Mathf.Clamp(directionAngle-currentAngle,
-maxRotationSpeed * Time.deltaTime,
maxRotationSpeed * Time.deltaTime);
Now we can rotate the transform deltaAngle degrees clockwise (in world space):
transform.Rotate(0f,0f,deltaAngle,Space.World);

MonoGame - Have an object circle around a point

I have an object with a Vector2 Position, and a cursor with Vector2 Position.
When I hold a certain key, I want the object to circle around the object, but I'm having trouble calculating the correct coordinates.
I've managed to make the object circle around the cursor (but it's not going in a perfect circle, but more of a spiral) with this code:
Vector2 diff= Vector2.Normalize(cursor.Location - this.Location);
float angle = (float)Math.Atan2(diff.Y, diff.X) + (float)(90 * (Math.PI / 180));
this.Position += new Vector2((float)(speed * Math.Cos(angle)), (float)(speed* Math.Sin(angle)));
I calculate the angle between cursor's and object's locations, and add 90° (in radians) to that value, which, by my logic, should make the object travel in a perfect circle. However, the distance between the cursor and the object quickly spreads.
What am I calculating wrong here?
Usually when you want something to circle around a point, you define the distance to an amount and you incrementally change the angle in your Update method. THEN in your draw method you can draw it where you should by calculating the position from the cursor.Location, the distance from the cursor and the desired distance.
In most situations like these you want your orbiter to have the same loation like your cursor, so calculating the new position in the Draw method works best, given that these calculations are cheap and super fast (you generally do not want to hog down your Draw method).
I am not able to check it right now, but what you should be doing is something in these lines:
Given that your object should rotate D distance away from your cursor with an angular velocity of AngularVelocity (per second), then when this initially happens, set a variable angle to zero. Then in your update do:
angle += (gameTime.ElapsedGameTime.TotalSeconds * AngularVelocity)
and in your Draw method do:
var displacedPosition = new Vector2(D * Math.Sin(angle), D * Math.Cos(angle));
and render your orbiter using the displacedPosition instead of the normal position if it is currently orbiting.

Specify a Triangle's Vertices based on radius and center coordinate

Is there a code formula for this? I am using C# and XNA, and in my class I have an array of three vectors (representing the vertices of the triangle), as well as a separate vector coordinate.
I plan to update these positions in the loop as it escalates further towards the top of the screen.
I'd ask maths.stackexchange.com, but seeing as how this applies to programming (and I personally am better at reading code as opposed to math itself - I'm still taking Algebra in school), I think it would make more sense for me to ask it here.
Edit
Yes, I am looking for an equilateral triangle. Or any triangle, for that matter. It doesn't matter what it is. All I am looking for is a formula; is that so hard to ask for?
Teh Problem
Basically, the problem I am trying to solve is to shoot a triangle out of my player (think Space Invaders; i.e., the triangle acts as a ray from the ray gun). What I need is a formula of code which will allow the triangle to be rendered based on its center position and radius, as the triangle will move upwards on its Y coordinate. I have the draw calls, and they work, but the problem is that the triangle when put in a for loop draw iteration (where the center vector position - on the Y coordinate - is incremented by N) simply sits next to the player's position when being drawn.
I think this is what you are looking for...
the angle is the orientation of the triangle...
this build a triangle....
void BuildTriangle(Vector2 Center, float Radius, float Angle, Vector2[] tri)
{
for (int i=0; i<3; i++)
{
t[i].X = Center.X + Radius * (float) Math.Cos(Angle + i * 2 * MathHelper.PI/3);
t[i].Y = Center.Y + Radius * (float) Math.Sin(Angle + i * 2 * MathHelper.PI/3);
}
}
if you want to move it, add to the center a velocity vector and rebuild it...

Rotation around a point

Can anyone help me with this please
I want to be able to rotate a 3D object around a stationary 3D object. Well there will be no movement involved as I just want to draw the objects at their locations once the game starts and then they will remain there for the remainder of the game.
Say for instance I have a object X that is stationary in 3D space. I then have 2 other objects, Y1 and Y2. Both of these objects are stationary as well and cant be moved. All 3 objects are on the same x and y axis. Lets say X is at (0,0,0) and Y1 is at (0,0,-50). I want to draw Y2 at a 45 degree angle from Y1 around the Y-axis but keep it the same distance from X.
Can anyone please suggest the best way of doing this please?
I have tried the following but that just rotates the object around its origin. So I guess I have to rotate it around the world origin? How is this done?
Matrix.CreateRotationY(Rotation)
I'm not sure what you want, but this is one method for rotate one object around another:
Vector3 Origin; // Stationary Object
float Yaw, Pitch; // Angles
float Distance;
Vector3 OrbitOffset = Vector3.UnitX * Distance;
// Other approach that consider the initial pos of the object to rotate
// Vector3 OrbitOffset = OrbitPos - Origin;
Matrix Rotation = Matrix.CreateFromYawPitchRoll(Yaw, Pitch, 0);
Vector3.Transform(ref OrbitOffset, ref Rotation, out OrbitOffset);
Vector3 OrbitPos = Origin + OrbitOffset; // Final position of the rotated object
if you dont need rotation about more than 2 angles at once, you can use basic Euler method.
see :
http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
thats a mathematical approach tough... but it works..
Just if you want a rotation around multiple axes, you will have serious problems with gimbal lock

Categories