canvas.rotate not working properly for me - javascript

I am in the process of making an arrow that points to an end goal using a canvas in HTML5 and Javascript. I am doing this by finding the x and y coordinates of the player and the end goal, then using Math.atan2() to find the angle. Up to that point everything works flawlessly, but then I get to the point of rendering the arrow at the same angle of the two points. I use ctx.translate() and ctx.rotate() to rotate the canvas accordingly, but it seems like the canvas doesn't rotate the same amount of degrees as I tell it to. For example:
var angles = 90;
ctx.rotate(angles);
but the canvas will rotate MUCH further than I want it to. Any clues as to why the canvas doesnt rotate by degrees and how to fix this? If needed here is the link to my game WIP: https://jsfiddle.net/juinorCPC/0azfu2wp/4/
EDIT:
I should probably also mention that i HAVE tried to rotate by radians and not by degrees, but the issue is that when i use radians, the canvas will rotate much LESS than it is supposed to.
EDIT x2:
I fixed the jsfiddle.
A quick example of the problem im seeing in action for those who cant get the fiddle to work:
Lets say I have a player in the middle of the canvas: (250, 250). I have a goal at another part of the canvas: (325, 125). I get the rotation in degrees: 23.96248897457819. Now i use ctx.rotate (better known as canvas.rotate() ) to rotate the canvas around the mid point (250, 250). The canvas does NOT rotate how i would like it to. IF i use degrees it rotates too much, if i use radians, it rotates too little.

Hola it me again try using this and if it work it work
function angle(playerX, playerY, goalX, goalY) {
var dx = playerX - goalX;
var dy = playerY - goalY;
var theta = Math.atan2(-dy, -dx);
theta *= 180 / Math.PI;
return theta;
}

Related

Issue with rotating the camera vertically

The following piece of code was written in order to rotate the camera by rad radians vertically (on an axis which has the angle of 90 deg on the vector where the camera looks at). However it's only working when the camera looks in Z direction (rotating on X axis) on every other case the code is rotating the camera on X axis when it shouldn't. Can you explain why is this happening? I would highly appreciate your help.
camera.getWorldDirection(direction)
console.log(direction)
/*direction.y or 0 I'm not sure*/
const axis = new THREE.Vector3(-1 * direction.z, 0,direction.x)
camera.rotateOnAxis(axis, rad)
I tried searching for similar issues, simulating the program paper. Unfortunately I could not solve it.

Straightening a face image within Canvas using click-points

I am trying to build a small app where my users can straighten up a tilted face with just 2 clicks
I ask my users to click on the middle of the nose and the middle of the eyebrows of the face within the image.
From there I get 2 points eyebrowMiddle(x1,y1) and noseMiddle (x2,y2).
Is it possible via these 2 points to calculate how much Canvas
rotation I need to have to rotate the image and make the face straight
in relation to the canvas rectangle?
Also, how can I detect and adjust accordingly if the image is tilted
to the left or right?
Here is a more descriptive image to show you what I mean now.
PS:
x1,y1 and x2,y2 are in relation to the canvas perimeter of
course, not the browser window or anything else.
We have tried the line equation such as m = (x2-x1) / (y2-y1) but the
result is always near 1 so I don't think we are following the right
course at the moment.
We don't care if the image looks wrong in the canvas as long as the
face features are parallel in relation to the bottom of the canvas
(they should be looking straight).
To perform such a rotation, you need to decide of the pivot point. Here i choose the eyebrow.
Then you have to choose a point in the target canvas where this pivot point will be hooked. I decided to choose the point at middle x coordinates, and at fourth of the screen in y.
To compute the rotation angle, you have to use atan2, which will nicely give you the angle for a given deltaY / deltaX in between two points ( angle = Math.atan2 ( delta y , delta x ) ) .
Then to draw :
- Translate to the target point.
- rotate by right angle.
- draw the image centering on its pivot.
ET VOILA, it works :-)
function rotate() {
ctx.save();
// go to default center position
ctx.translate(eyeBrowTargetPosition.x, eyeBrowTargetPosition.y);
// compute angle
var yDelta = noseMiddle.y - eyebrowMiddle.y;
var xDelta = noseMiddle.x - eyebrowMiddle.x ;
var angle = Math.atan2 (yDelta ,xDelta);
// compensate for angle
ctx.rotate(angle);
//draw image centering input on eyebrow
ctx.drawImage(face, -eyebrowMiddle.x, -eyebrowMiddle.y);
ctx.restore();
};
jsbin is here :
http://jsbin.com/wavokaku/2/edit?js,output
result with an approximation of the existing green dots :

Canvas move object in circle

I have a rectangle in canvas, and I know how to move it up and sideways.
What I want to do is have it move in a circular motion.
So my objects(rectangle) x and y would go in a circle.
Now I am assuming I need a radius for how far out and some formula for the speed(1pixel) to get it rotate on the axis.
Any idea's?
The parametric equation for moving in a circle is this:
x=r*cos(theta)
y=r*sin(theta)
theta is the angle, and r the radius.
If you want to know the change in theta to get the desired speed, solving for the distance d you get that the change in theta is: arccos(1-(d/r)^2/2)
The JavaScript functions are Math.cos, Math.sin, and Math.acos, respsectively. They all deal with radians.

Canvas image scaling, rotating, drawing

For a game project, I'm drawing images using their properties such as fileName, position, scale, rotation.
Here is the part that does the drawing:
this.context.save();
this.context.translate(item.position.x, item.position.y);
if (item.rotation > 0) {
this.context.rotate(item.rotation * (Math.PI / 180));
}
if (item.scale.x !== 1 || item.scale.y !== 1) {
this.context.scale(item.scale.x, item.scale.y);
}
var width = item.imageSize.width * item.scale.x;
var height = item.imageSize.height * item.scale.y;
this.context.drawImage(this.assets.image[item.fileName], -(width / 2), -(height / 2), width, height);
this.context.restore();
(don't mind the strange positioning, it's not important)
This works fine, but there is one thing that I don't understand:
Rotation and scaling can be done in two different ways: first scale and then rotate, or other way around. Logically, one would think that first scale then rotation is correct, but for some reason, it only works correctly if I first rotate then scale.
What is the correct way of doing this?
Where is your point of origin for your objects? Are the x/y the top left? If so that could be causing the issue.
Demo Scaling Then Rotating
ctx.translate(box.x, box.y);
ctx.scale(2,2);
ctx.rotate(box.angle);
Demo Rotating Then Scaling
ctx.translate(box.x, box.y);
ctx.rotate(box.angle);
ctx.scale(2,2);
If you notice both of those demos work fine regardless of when I perform the scaling and rotating. My point of origins however (where I translate to) are in the center of the boxes.
To answer your question (or attempt to) there is no right or wrong way, you can scale first or rotate first, its really just a matter of preference.
The "correct way" really depends on what you're trying to do. For you, it seems like rotating and then scaling results in what you expect.
Here is a fiddle that shows the difference between rotating then scaling and scaling then rotating: http://jsfiddle.net/HYbC7/3/
What's unexpected for me is when you scale then rotate. If you scale(x, y) where x and y are not equal, then rotate, then the rotation along the x-axis will be different than the rotation along the y-axis and the resulting grid will be skewed.

Canvas Rotating object about dynamic points

I have a rounded rectangle at a specific x, y, w, h on a canvas. I first do a context.translate to get the object where I want it, then when it comes to rotating it, this is where I'm having issues working out the math needed.
I can do a simple context.rotate(Math.PI/180 * 25) to rotate it 25degs but it rotates from the x,y. I really want to shift the rotating point to like x + (w/2) and y + (w/2).
I'm not sure how to tell the rotate method to rotate it around a different point. I think I have to rotate it like normal but recalculate x,y perhaps based on the rotation maybe?
The canvas always rotates about the origin (0,0). The ctx.translate command can be thought of as shifting the origin, so you must translate by (x+w/2, y+h/2) before you rotate if you wish to rotate about the center of the rectangle.
(and of course, translate back after, or use save and restore)

Categories