cartesianToPolar for SVG circle / inverse of polartoCartesian - javascript

I've seen this function floating around:
function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;
return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
};
}
It works fine for my purposes - determining the absolute X, Y coordinates for the given angle on a circle having centerX, centerY and radius. It works for 360, 0, 180 — all valid SVG values.
Geometry is not my strong suit, but I have not found, nor am I able to write, a function which takes a similar description of the circle, and X, Y coordinates on its circumference (e.g. as output by polarToCartesian), and returns an answer corresponding to angleInDegrees, with no fudging. I am looking for a pair of functions with a 1->1 correspondence.

Math.atan2(Y-centerY, X-centerX) * 180 / Math.PI
gives you angle of point X,Y relative to center.
Note that in your formula (angleInDegrees-90) causes X/Y exchange (like you count angles from vertical axis). If you need this, add 90 to result.
Also atan2 domain is -Pi..Pi (-180..180). If you need only positive angles, add 360 if result is negative.
Seems you need this result:
(Math.atan2(Y-centerY, X-centerX) * 180 / Math.PI + 450) % 360

Related

How to do a 3d rotation to a 2d point in JavaScript (Azure Face Rotation)

I am using the Azure Face API to get the landmarks and rotation angle of a given face. The problem is that all of those points are 2d objects, and I need to rotate them in a 2d space using the yaw, roll and pitch angles of the face.
I have tried to rotate them in the roll angle using this function:
const rotatePoint = (pivotPoint, point, angle) => {
const { x: px, y: py } = pivotPoint;
const { x, y } = point;
var radians = (Math.PI / 180) * angle,
cos = Math.cos(radians),
sin = Math.sin(radians),
nx = cos * (x - px) + sin * (y - py) + px,
ny = cos * (y - py) - sin * (x - px) + py;
return { x: nx, y: ny };
};
Using the center of the FaceRectangle (here you can see it: https://learn.microsoft.com/es-es/azure/cognitive-services/face/images/face.detection.jpg) as pivot point. But I think that the pivot point will only work with a roll rotation. Just imagine a 3d object which is rotated in 3d dimensions. If you have the vertices of this object in a 2d plane, to fully remove the rotation you will need to rotate it in the 3 angles. Correct me if i'm wrong.
Is there any formula to rotate the 2d points in the 3 angles?

Get the number of degrees the div is on in javascript

I have a circle and I need to know the level of a particular div. For example, I have divided a circle here into 4 pieces. My goal is to find out how many degrees the circled div is at. This so that I can change the color of the background. So for example when a div is between 0 and 90 degrees, the background color should be blue, and from 90 to 180 degrees green. Can this be calculated with javascript?
I myself had already experimented to calculate the difference between the points with the x position and the y position of an object, but unfortunately without success. that looked like this:
handleDrag = (e, ui) => {
var p1 = {
x: ui.x,
y: ui.y
};
var p2 = {
x: ui.x,
y: ui.y
};
// angle in radians
var angleRadians = Math.atan2(p2.y - p1.y, p2.x - p1.x);
// angle in degrees
var angleDeg = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;
console.log("graden:"+angleDeg);
}
Anyone have any advice?

Trying to calculate mouse x or y (or ratio of both) with given angle to give a distance

I have the xy coordinates from before and during a drag event, this.x and this.y```` are the current coordinates,this.lastXandthis.lastY``` are the origin.
What I need to do is given a radian of the source element, determine which mouse coordinate to use, IE if the angle is 0 then the x coordinates is used to give a "distance" if the degrees are 90 then the y coordinates are used
if the radian is 0.785398 then both x and y would need to be used.
I have the following code for one axis, but this only flips the y coordinates
let leftPosition;
if (this.walls[this.dragItem.wall].angle < Math.PI / 2) {
leftPosition = Math.round((-(this.y - this.lastY) / this.scale + this.dragItem.origin.left));
} else {
leftPosition = Math.round(((this.y - this.lastY) / this.scale + this.dragItem.origin.left));
}
I have an example here https://engine.owuk.co.uk
what I need to do is have the radian dictate what x or y coordinate is used to control the drag of the item by calculating the leftPosition, I have been loosing my mind trying to get this to work :(
The Math.sin and Math.cos is what you need, here is an example
<canvas id="c" width=300 height=150></canvas>
<script>
const ctx = document.getElementById('c').getContext('2d');
function drawShape(size, angle, numPoints, color) {
ctx.beginPath();
for (j = 0; j < numPoints; j++) {
a = angle * Math.PI / 180
x = size * Math.sin(a)
y = size * Math.cos(a)
ctx.lineTo(x, y);
angle += 360 / numPoints
}
ctx.fillStyle = color;
ctx.fill();
}
ctx.translate(80, 80);
drawShape(55, 0, 7, "green");
drawShape(45, 0, 5, "red");
drawShape(35, 0, 3, "blue");
ctx.translate(160, 0);
drawShape(55, 15, 7, "green");
drawShape(45, 35, 5, "red");
drawShape(35, 25, 3, "blue");
</script>
Here is a theoretical answer to your problem.
In the simplest way, you have an object within a segment that has to move relative to the position of the mouse, but constrained by the segment's vector.
Here is a visual representation:
So with the mouse at the red arrow, the blue circle needs to move to the light blue.
(the shortest distance between a line and a point)
How do we do that?
Let's add everything we can to that image:
The segment and the mouse form a triangle and we can calculate the length of all sides of that triangle.
The distance between two points is an easy Pythagorean calculation:
https://ncalculators.com/geometry/length-between-two-points-calculator.htm
Then we need the height of the triangle where the base is our segment:
https://tutors.com/math-tutors/geometry-help/how-to-find-the-height-of-a-triangle
That will give us the distance from our mouse to the segment, and we do know the angle by adding the angle of the segment + 90 degrees (or PI/2 in radians) that is all that we need to calculate the position of our light blue circle.
Of course, we will need to also add some min/max math to not exceed the boundaries of the segment, but if you made it this far that should be easy pickings.
I was able to make the solution to my issue
let position;
const sin = Math.sin(this.walls[this.dragItem.wall].angle);
const cos = Math.cos(this.walls[this.dragItem.wall].angle);
position = Math.round(((this.x - this.lastX) / this.scale * cos + (this.y - this.lastY) / this.scale * sin) + this.dragItem.origin.left);

Finding the difference between two centers after rotation

I'm making a royo canvas editor but with HTML, everything is perfect but I have a trigonometry problem that I can't get out.
https://i.stack.imgur.com/ErKNo.png
I break it 10deg to the right or left and then increase the height to 302px. It then moves to the opposite side when it should remain in the same position.
The problem is that I have to calculate the difference between the rotated and increased center from the unrotated center to get the difference and subtract it to get the same location.
I currently use a formula to do just the opposite, which is to get X2, Y2 and X1, Y1 having the rotation and the center point.
const center = { x: layer.size.width / 2, y: layer.size.height / 2 };
const rotate = this.getAbsoluteRotation(layer) * Math.PI / 180;
return {
x: center.x - center.x * Math.abs(Math.cos(rotate)) - center.y * Math.abs(Math.sin(rotate)),
y: center.y - center.x * Math.abs(Math.sin(rotate)) - center.y * Math.abs(Math.cos(rotate))
};
I understand that I need the reverse of this formula.
Thank you ;)

Rotate rectangle around a point

How would I get 4 points rotated a certain degrees around a pointer to form a rectangle? I can rotate a point around a point, but I can't offset it to make a rectangle that isn't distorted.
If you can rotate a point around a point then it should be easy to rotate a rectangle - you just rotate 4 points.
Here is a js function to rotate a point around an origin:
function rotate_point(pointX, pointY, originX, originY, angle) {
angle = angle * Math.PI / 180.0;
return {
x: Math.cos(angle) * (pointX-originX) - Math.sin(angle) * (pointY-originY) + originX,
y: Math.sin(angle) * (pointX-originX) + Math.cos(angle) * (pointY-originY) + originY
};
}
And then you can do this to each point.
Here is an example: http://jsfiddle.net/dahousecat/4TtvU/
Change the angle and hit run to see the result...

Categories

Resources