Angle of Rotation - javascript

Here is the code, I am trying to get the angle of rotation. I am rotating an image around a dial. I am getting all the angles right except when it reaches 270 degree it does some funky stuff. The angle changes to negative. It works fine from 0 to 270 but i cant get it to display angle between 270 to 360..Please give me some suggestions
this.rotate = function(x){
this.node.style.MozTransform="rotate("+x+"deg)";
this.node.style.WebkitTransform="rotate("+x+"deg)";
this.node.style.OTransform="rotate("+x+"deg)";
this.node.style.msTransform="rotate("+x+"deg)";
this.node.style.Transform="rotate("+x+"deg)";
myintID = setInterval(function(){
//Math!
angleFromEye = Math.atan2((cursorLocation.y-self.my_y), cursorLocation.x- self.my_x)*(180/Math.PI)+ 90;
//Rotate
self.rotate(angleFromEye);

Actually the angle is negative for the values -90 to 0 also, but you add 90 to the angle, so you don't see that.
Simply add 360 to the angle when it's negative:
if (angleFromEye < 0) angleFromEye += 360;

I think your problem is with your conversion from the range of return values of atan2 to your desired range.
atan2 gives angles in radians, in the range [-pi,pi], you want angles in degrees in the range [0,360].
Your conversion gives you angles in degrees in the range [-180+90,180+90] = [-90,270].
atan2(...)*(180/Math.PI) + 90
Try this instead:
atan2(...)*(180/Math.PI) + 180

I recently created a jQuery plugin, that allows you to get the rotation of an element, and also to rotate an element. It works in ie7 and ie8 as well.
Here: http://wp-dreams.com/jquery-element-rotation-plugin/

Related

Sphere rotation in Babylon.js

I want to ask for help regarding rotation using the Babylon.js framework.
I need the sphere to rotate 45 degrees, exactly aligned with the diagonal circle, which has a 45 degree orientation, but I'm not getting it.
The code I made is in the link below:
https://codepen.io/polalas/pen/VwvaKwL
The method responsible for the rotation is the loop () method, which is triggered every time the scene is rendered.
function loop () {
var y1 = scene.getMeshByName("I1");
y1.rotation.y - = 0.01 * Math.sin (Math.PI / 4);
y1.rotation.x - = 0.01 * Math.sin (Math.PI / 4);
}
I imagine that I mishandled the rotation. Could someone help, please?
Using your code, the best way to achieve that is to first rotate the parent of the sphere (what you called newMesh (or I1)) 45 degrees around the Z axis right before adding the sphere as a child:
newMesh.rotate(BABYLON.Axis.Z, Math.PI / 4);
Afterwards you can rotate it around its Local (!) X axis in your render loop:
function loop(){
var y1 = scene.getMeshByName("I1");
}
This way you get a perfect rotation around your (mocked) pivot.

Rotating to point at something in radians without wrapping around zero

Let's say I have a circle with a line sticking out of it.
I want that line to point at the center of the window, no matter where the circle moves to.
But, I want that line to slowly move to that angle. I don't want the rotation to be calculated and set every single frame, but rather calculated and tweened to that direction.
The issue I'm having with this is that if you move to make the line rotate around where the radians meet 0, it will do a full 360 (or 3.14 in rads ;) to get to that point.
I have spent a while trying to think of how to explain this best, here is a codepen that can hopefully help clarify what I'm asking
// CenterX/Y is the center of the screen.
// dotX/Y is the center of the circle.
var angleToCenter=Math.atan2(centerY-dotY,centerX-dotX);
if (angleToCenter<currentAngle) {
currentAngle-=0.05;
} else {
currentAngle+=0.05;
}
if you move to the right of the screen, then go above or below the center, you will see the line move in a full circle to try to get to the calculated direction. How do I avoid this? I want the line to seamlessly rotate to point at the center, via the shortest possible way, not by doing a full circle.
Great question. Very different.
I would have an inverse (-1) relationship defined for any location below the black circle. Such that, if the red circle crosses a horizontal axis - whose boundry is defined by the black circle - the mathematical result to your equation is inversed.
This would make 0 degrees as we typically think of it, now positioned at 180 degrees.
Reasoning: Looking at your CodePen it's obvious that the stem is going "the long way around", but you want it to go the "short way around". The most intuitive way to make that happen would seem to be to inverse the red-circles calculated rotation. The simplest method I can think of would be to inverse the polarity of the circle.
The problem lies in the point where angleToCenter switches from Math.PI to -Math.PI (and vice versa).
Therefore I'd suggest you create an "epsilon angle distance", in which the angles will be hard-coded:
var angleToCenter = Math.atan2(centerY - dotY, centerX - dotX);
var epsilon = 0.05;
if (Math.abs(angleToCenter - Math.PI) <= epsilon / 2 || Math.abs(angleToCenter + Math.PI) <= epsilon / 2) {
if (dotY > centerY) {
currentAngle = -Math.PI;
} else if (dotY < centerY) {
currentAngle = Math.PI;
}
} else if (angleToCenter < currentAngle - epsilon) {
currentAngle -= epsilon;
} else {
currentAngle += epsilon;
}
For the full edit, you can check my fork to your CodePan

ThreeJS oribital camera short rotation

I have an orbital camera that orbits are a globe. There are several markers on the globe that the user can click on, and the camera will move to that point.
Using TweenMax for the animation like this -
TweenMax.to(currentPos, 3, {
theta:targetPos.theta,
phi:targetPos.phi,
radius:targetPos.radius,
ease:Circ.easeIn,
onComplete:btnZoomComplete,
onUpdateParams:["{self}"],
onComplete:SataliteTweenComplete,
onUpdate: function(tween) {
controls.setThetaPhi(tween.target.theta, tween.target.phi, tween.target.radius);
}
});
This works great, however is doesn't take into consideration the shortest route to get there. So it can quite often go 'round the back' of the globe.
ThreeJS seems to measure the angle in a really strange unit system:
0, 1.57 (equivalent to 90 degrees), 3.14 (eq 180dg), then after 3.14 is jumps to -3.14, -1.57 (eq to 270dg), then back to 0... So this blowing my mind on how to work it out.
For example, say the camera is at 2.6 and it needs to go over to -2.61, at the moment the camera will animate CCW (2.6 to -2.16), where as visual it needs to animate CW, which would move from 2.6 to 3.14, -3.14 then to -2.61.
Any help on this would be really appreciated.
I guess there are two problems, how to work out which way to go round, but then how to actually animate across from 2.6 -> 3.14, jump to -3.14 seamlessly -> -2.61
So that "strange unit-system" is just radians and it's quite common to measure theta/phi values in a range from -180° to 180° and -90° to 90° (think latitude/longitude, same thing). The conversion is simple:
angleDegrees = radians / Math.PI * 180;
radians = angleDegrees / 180 * Math.PI;
Now the tweening-library will just interpolate from one value to the other and doesn't know what these values represent. So it simply can't know how to handle the shortest path when it comes to rotations. However, you can do this before starting the tween.
Say we animate from 2.6 to -2.6 (or 149° to -149°).
var from = 2.6, to = -2.6;
The direction and angular distance for the animation can be calculated as
var distance = to - from;
// === -5.2
A negative value here means counterclockwise, and 5.2 (~298°) is the "distance" the camera will travel. Now keep in mind that any angle plus or minus 360° (2 * Math.PI) will essentially land you at the same position. So lets try:
var distance = (to + 2 * Math.PI) - from;
// === 1.083185307179586 (~62°)
So, if you rotate from your position at 2.6 to -2.6 + 2 * Math.PI (or, from 149° to -149° + 360° = 211°), you will get a clockwise animation with a shorter path.
To make sure that all values stay in their allowed range, we change the onUpdate-function a little bit to wrap around properly:
controls.setThetaPhi(
tween.target.theta % Math.PI,
tween.target.phi % Math.PI,
tween.target.radius);
You will probably also want to update the currentPos value with the actual values before the animation starts and below computation happens.
What's left to do is solving this for the general case, so to find out when to do the clockwise and counterclockwise rotation. To see if the other way around would be shorter, we just need to see if the distance would be greater than 180°:
if (Math.abs(to - from) > Math.PI) {
if (to > 0) { // if to is positive we remove a full-circle, add it otherwise
to = to - 2 * Math.PI;
} else {
to = to + 2 * Math.PI;
}
}

Coming up with an Algorithm

I have a circle in my canvas. The mouse position is calculated in relation to the canvas. I want the circle to move when the mouse is at <=100px distance from it. The minimum distance to start moving is 100px, at 0.5px/tick. It goes up to 2px/tick at 20px distance.
Basically, the closer the mouse is to the circle, the faster the circle should move.
What I have so far moves the circle when distance is less or equal to 100 -- (I'm using easeljs library)
function handleTick() {
distance = calculateDistance(circle, mX, mY);
if (distance<=100) {
circle.x += 0.3;
stage.update();
}
}
What I want
function handleTick() {
distance = calculateDistance(circle, mX, mY);
if (distance<=100) {
circleSpeed = // equation that takes distance and outputs velocity px/tick.
circle.x += circleSpeed;
stage.update();
}
}
So I thought this was a mathmatical problem and posted it on math exchange, but so far no answers. I tried googling several topics like: "how to come up with an equation for a relation" since I have the domain (100, 20) and the range (0.5, 2). What function can relate them?
Thing is I'm bad at math, and these numbers might not even have a relation - I'm not sure what I'm looking for here.
Should I write a random algorithm "circleSpeed = 2x + 5x;" and hope it does what I want? Or is it possible to do as I did - "I want these to be the minimum and maximum values, now I need to come up with an equation for it"?
A pointer in the right direction would be great because so far I'm shooting in the dark.
If I understand it correctly, you want circleSpeed to be a function of distance, such that
circleSpeed is 0.5 when distance is 100.
circleSpeed is 2 when distance is 20.
There are infinity functions which fulfill that, so I will assume linearity.
The equation of the line with slope m and which contains the point (x₀,y₀) is
y = m (x-x₀) + y₀
But in this case you have two points, (x₁,y₁) and (x₂,y₂), so you can calculate the slope with
y₂ - y₁
m = ───────
x₂ - x₁
So the equation of the line is
y₂ - y₁
y = ─────── (x - x₁) + y₁
x₂ - x₁
With your data,
0.5 - 2
y = ──────── (x - 20) + 2 = -0.01875 x + 2.375
100 - 20
Therefore,
circleSpeed = -0.01875 * distance + 2.375
I assume you want a linear relation between the distance and speed?
If so, you could do something like circleSpeed = (2.5 - 0.5(distance/20)).
That would, however set the speed linearly from 0 to 2.5 on the range (100 to 0), but by using another if like this if (distance < 20) circleSpeed = 2 you would limit the speed to 2.0 at 20 range.
It's not 100% accurate to what you asked for, but pretty close and it should look ok I guess. It could possibly also be tweaked to get closer.
However if you want to make the circle move away from the mouse, you also need to do something to calculate the correct direction of movement as well, and your problem gets a tiny bit more complex as you need to calculate speed_x and speed_y
Here is a simple snippet to animate the speed linearly, what that means is that is the acceleration of the circle will be constant.
if distance > 100:
print 0
elseif distance < 20:
print 2
else:
print 2 - (distance -20 ) * 0.01875
Yet other relationships are possible, (other easings you might call them) but they will be more complicated, hehe.
EDIT: Whoops, I’d made a mistake.

Get camera's current rotation in degrees

I'm using a THREE.PerspectiveCamera with THREE.OrbitControls for rotation etc.
When I rotate the camera I want to update a symbol on Google Maps to show the direction of the camera.
Trying to get the rotation of (Y) in degrees like this:
360 / Math.PI * perspectiveCamera.rotation.y;
It returns the degrees from ..5..15...180..15..5 then -5..-15...-180..-15..-5.
Is there a another way to get the y rotation of the camera in 360 degrees?
In the past I have used radians * 180 / Math.PI to convert radians to degrees. More on these conversions here.
Or you could add 180 to the angle you are currently calculating to get a range from 0 to 360 :)

Categories