How to get x, y distance from a circle - javascript

I've drawn a square shape whose width & length 20x, or 20y then I have drawn a circle inside the square whose radius 10x. Now a ray from the center of the circle went through the boundary of the circle at 45-degree angle (it can be 38 degrees or anything). Now how can i get x & y distance of connection ground of ray & circle from the square shape?
I've tried this code:
var radius = 10 //radius,
x = Math.cos(Math.PI * 45 / 180) * radius
y = Math.sin(Math.PI * 45 / 180) * radius
I'm not getting the exact distance with this code, what is the currect way to get this x & y distance?

It seems that your coord origin is the top left of the enclosing square and the y axis is oriented downwards.
In that case,
var radius = 10 //radius,
x = radius + Math.cos(Math.PI * 45 / 180) * radius
y = radius - Math.sin(Math.PI * 45 / 180) * radius

[update]
you can get the x & y distances using this formulas:
var radius = 10 //radius,
var angle = 90
var d = Math.PI/180 //to convert deg to rads
if (0 <= angle & angle <= 45){
deg = angle * d
x = radius * Math.cos(deg)
y = radius * Math.sin(deg)
}else if( 45 < angle & angle <= 90){
deg = (90-angle) * d
x = radius * Math.cos(deg)
y = radius * Math.sin(deg)
}
console.log("x = " + x)
console.log("y = " + y)
If the angle is less than 45° we use the normal formulas as shown in the code.
But if the angle is greater than 45° we have to use the angle between the line and the y-axis which equal to 90-(angle value).
I hope this will solve your problem.

After someone's edit, your post contains the correct expressions for calculating x and y coordinates from the center of the circle ("from center" row in the table). In order to get the "remaining" part to the edges of its bounding square ("to border" row in the table), these distances can be subtracted from the radius:
function calculate(){
var radius=document.getElementById("radius").valueAsNumber||10;
var radians=document.getElementById("degrees").valueAsNumber*Math.PI/180||0;
document.getElementById("x1").innerHTML=radius*Math.cos(radians);
document.getElementById("y1").innerHTML=radius*Math.sin(radians);
document.getElementById("x2").innerHTML=radius-radius*Math.cos(radians)
document.getElementById("y2").innerHTML=radius-radius*Math.sin(radians)
}
<input type="number" placeholder="radius" id="radius"><br>
<input type="number" placeholder="degrees" id="degrees"><br>
<button onclick="calculate()">Calculate</button><br>
<table border="1">
<tr><th></th><th>x</th><th>y</th></tr>
<tr><th>from center</th><td id="x1"></td><td id="y1"></td></tr>
<tr><th>to border</th><td id="x2"></td><td id="y2"></td></tr>
</table>

Related

Calculate percentage of a circle from center to out on click

I want to get the percent radius of an arc (circle).
The idea is, on click event on the canvas, find the element that collide with click point. I did it, there is no problem to find the element that collide.
Bu i want to calculate if an element's type is a circle, calculate the collide percentage from center of the arc to the outside.
The code below is for collision detection.
if(element.type == "circle") { // circle detection
let dx = x - element.left,
dy = y - element.top,
dist = Math.abs(Math.sqrt(dx * dx + dy * dy));
if (dist <= element.width / 2) {
collision = {
hitTo: // calculate percentage???,
object: element
};
}
}
I don't know how to do this. Can you help?
Ensure you have x and y position from the center of the circle (not from the top-left) then you can calculate the percentage by using inverse tangent trigonometric function.
var x = 0.5;
var y = 0.5;
var angle = Math.atan(y/x);
var percentage = 100 * angle / (2 * Math.PI);
console.log("Percentage: ", percentage);
For example, with both x and y set to 0.5, you get percentage equal to 12.5

Calculate vector with given angle and length

Is there any way in which, in javascript, I can call a function with an x and y co-ord and a direction (angle in degrees) and it will return a set of new co-ords that has been 'moved' by 10px in the direction given from the original co-ords? I looked around but all I can find is ways to get the angle of two given co-ords.
This function returns an array [xCoord, yCoord] of the new coordinates:
function myFunction(xCoord, yCoord, angle, length) {
length = typeof length !== 'undefined' ? length : 10;
angle = angle * Math.PI / 180; // if you're using degrees instead of radians
return [length * Math.cos(angle) + xCoord, length * Math.sin(angle) + yCoord]
}
I just wanted to point out, that the answers of are not correct IMHO. I've created a JSFiddle showing that the correct implementation must be something like this:
function getRelativeVector(angle, length, xOffset, yOffset) {
angle = angle * Math.PI / 180;
return {
X:length * Math.sin(angle) + xOffset,
Y:length * Math.cos(angle) + yOffset
};
}
The other solutions shown here from #Audrius and #Markus are simply twisted in cos and sin. They are working for angles between 0 and 45 degrees only.
The formula would be:
X = length * sin(angle) + xLocation
Y = length * cos(angle) + yLocation
The shift in x coordinate is L*cos(a) and shift in y coordinate is L*sin(a), where a is the angle ("direction given") and L is 10 px in your case.

How to calculate rotation angle from rectangle points?

I have 4 points 1,2,3,4 that closes a rectangle.
The points are in a array in this following way: x1 y1 x2 y2 x3 y3 x4 y4
The problem I have is that the rectangle can be rotated in a angle.
How can I calculate the original points (gray outline), and the angle?
I'm trying to reproduce this effect in javascript+css3-transform, so I need to first know the straight dimensions and then rotate with the css.
I just know if the rectangle is straight by comparing points e.g. y1==y2
if(x1==x4 && x2==x3 && y1==y2 && y4==y3){
rectangle.style.top = y1;
rectangle.style.left = x1;
rectangle.style.width = x2-x1;
rectangle.style.height = y4-y1;
rectangle.style.transform = "rotate(?deg)";
}
You can use any coordinate pair on the same side to calculate the rotation angle. Note that mathematic angles normally assume 0 as long the +ve X axis and increase by rotating anti–clockwise (so along the +ve Y axis is 90°, -ve X axis is 180° and so on).
Also, javascript trigonometry functions return values in radians that must be converted to degrees before being used in a CSS transform.
If the shape is not rotated more than 90°, then life is fairly simple and you can use the tanget ratio of a right angle triangle:
tan(angle) = length of opposite side / length of adjacent side
For the OP, the best corners to use are 1 and 4 so that rotation is kept in the first quadrant and clockwise (per the draft CSS3 spec). In javascript terms:
var rotationRadians = Math.atan((x1 - x4) / (y1 - y4));
To convert to degrees:
var RAD2DEG = 180 / Math.PI;
var rotationDegrees = rotationRadians * RAD2DEG;
If the rotation is more than 90°, you will need to adjust the angle. e.g. where the angle is greater than 90° but less than 180°, you'll get a -ve result from the above and need to add 180°:
rotationDegrees += 180;
Also, if you are using page dimentions, y coordinates increase going down the page, which is the opposite of the normal mathetmatic sense so you need to reverse the sense of y1 - y4 in the above.
Edit
Based on the orientation of points in the OP, the following is a general function to return the center and clockwise rotation of the rectangle in degrees. That's all you should need, though you can rotate the corners to be "level" yourself if you wish. You can apply trigonometric functions to calculate new corners or just do some averages (similar to Ian's answer).
/** General case solution for a rectangle
*
* Given coordinages of [x1, y1, x2, y2, x3, y3, x4, y4]
* where the corners are:
* top left : x1, y1
* top right : x2, y2
* bottom right: x3, y3
* bottom left : x4, y4
*
* The centre is the average top left and bottom right coords:
* center: (x1 + x3) / 2 and (y1 + y3) / 2
*
* Clockwise rotation: Math.atan((x1 - x4)/(y1 - y4)) with
* adjustment for the quadrant the angle is in.
*
* Note that if using page coordinates, y is +ve down the page which
* is the reverse of the mathematic sense so y page coordinages
* should be multiplied by -1 before being given to the function.
* (e.g. a page y of 400 should be -400).
*
* #see https://stackoverflow.com/a/13003782/938822
*/
function getRotation(coords) {
// Get center as average of top left and bottom right
var center = [(coords[0] + coords[4]) / 2,
(coords[1] + coords[5]) / 2];
// Get differences top left minus bottom left
var diffs = [coords[0] - coords[6], coords[1] - coords[7]];
// Get rotation in degrees
var rotation = Math.atan(diffs[0]/diffs[1]) * 180 / Math.PI;
// Adjust for 2nd & 3rd quadrants, i.e. diff y is -ve.
if (diffs[1] < 0) {
rotation += 180;
// Adjust for 4th quadrant
// i.e. diff x is -ve, diff y is +ve
} else if (diffs[0] < 0) {
rotation += 360;
}
// return array of [[centerX, centerY], rotation];
return [center, rotation];
}
The center of the rectangle is right between two opposite corners:
cx = (x1 + x3) / 2
cy = (y1 + y3) / 2
The size of the rectangle is the distance between two points:
w = sqrt(pow(x2-x1, 2) + pow(y2-y1, 2))
h = sqrt(pow(x3-x2, 2) + pow(y3-y2, 2))
The corners of the gray rectangle can be calculated from the center and the size, for example the top left corner:
x = cx - w / 2
y = cy - h / 2
The angle is the arctangent of a side of the square:
a = arctan2(y4 - y1, x4 - x1)
(I'm not sure exactly which angle it returns, or what angle you expect for that matter, so you get to test a bit.)
This is how you get the angle between the vertical pink line and the black line starting at the pink line intersection:
var deg = 90 - Math.arctan((x2-x1) / (y2-y1));
The dimensions can be calculated with the help of the Pythagoras theorem:
var width = Math.sqrt((x2-x1)^2 / (y2-y1)^2));
var height = Math.sqrt((x1-x4)^2) / (y4-y1)^2));
The positional coordinates (left and top) are the averages of x1 and x3 and y1 and y3 respectively.
var left = Math.floor((x1 + x3) / 2);
var top = Math.floor((y1 + y3) / 2);
You want to use the negative-margin trick.
var marginLeft = -Math.ceil(width / 2);
var marginTop = -Math.ceil(height / 2);

Algorithm: Function to resolve degrees to x,y for drawing SVG Pie Graphs

I am working with SVG graphics to draw Pie Graphs. I am given the degrees a pie graph should be - eg 277 degrees - and the diameter - eg 200px - and I need to draw a circle of 277 degrees.
With SVG graphics I need to resolve that 277 degrees to a point where that circle will end.
I am not the greatest with math, so I have come up with a formula/javascript function that will allow me to take a degrees value & come up with a x,y point of where the circle will end.
Will my Javascript function(at the bottom) correctly resolve a degrees to a correct point? Can you help me develop my algorithm to obtain the coordinate from a degree value? Or maybe there is an existing algorithm I can use that I dont know about?
My Algorithm: (Which I require help with)
So the values I am given are: Circle Diameter: 200px, Circle size: 277 degrees.
I require the point at which 277 ends when rotating around the point 0,0.
277 ends in the 1st quadrant which means I need to use sin (is that correct?)
So the values I know now of the triangle are: the hypotenuse=100px(the radius), the angle=7 degrees(277-270).
sin(7) = o/100;
0.1219 = o/100;
o = 12.2;
Therefore the y point is 12.2 (for my sakes 0,0 is the top left corner so its really midY-x = 100-12.2 = 87.8; (is that correct?)
Now to determine the x pos, I use cos(is that correct?).
cos(7) = a/100;
a = 99.25;
Therefore the x point is 99.25 or 100-99.25=0.75;
So the x,y coordinate of 277 degrees is 0.75,87.8. Is that correct?
So in code this algorithm would be:
function resolveToPoint( deg, diameter )
{
if ( deg <= 0)
return 0;
var x = 0;
var y = 0;
var angle = 0;
var rad = diameter/2;
var midX = rad;
var midY = rad;
if (deg <= 90)
angle = 90 - deg;
else if (deg <= 180)
angle = deg - 90;
else if (deg <= 270)
angle = deg - 180;
else if (deg <= 360)
angle = deg - 270;
// Q: Will I ALWAYS use cos to determine the x & sin for the x NO MATTER what quadrant the angle is in??
x = Math.cos(angle) * rad;
y = Math.sin(angle) * rad;
if (deg <= 90)
{
x = midX + x;
y = midY - y;
}
else if (deg <= 180)
{
x = midX + x;
y = midY + y;
}
else if (deg <= 270)
{
x = midX - x;
y = midY + y;
}
else if (deg <= 360)
{
x = midX - x;
y = midY - y;
}
return {mX: x, mY: y};
}
Then I'll use it in a SVG like so:
function outputPiegraph( point, rad, diameter )
{
var svg = '<svg width="%spx" height=""%spx" id='pie' style="background-color: green;">
<path d="M%spx,%spx L%spx, %spx A%spx,"%spx 1 1,1 %spx,%spx z"
fill="red" stroke="blue" stroke-width="2" />"
</svg>';
return sprintf(svg, diameter, diameter, point.mX, point.mY, rad, rad, rad, diameter);
}
This is simple conversion from polar to Cartesian coordinates:
function resolveToPoint(deg, diameter) {
var rad = Math.PI * deg / 180;
var r = diameter / 2;
return {mX: r * Math.cos(rad), mY: r * Math.sin(rad)};
}
http://en.wikipedia.org/wiki/Polar_coordinates#Converting_between_polar_and_Cartesian_coordinates
If you consider the unit circle, then the X-coordinate for a given (radians-based) angle is given by the cosine, likewise, the Y-coordinate is given by the sine. So, you can solve this easily as follows.
function resolveToPoint(deg, diameter) {
var radians = angle_in_degrees / 180 * Math.PI;
var x = diameter / 2 * cos(radians);
var y = diameter / 2 * sin(radians);
return {mX : x, mY: y};
}

Use X,Y coordinates to plot points inside a circle

Is there a way in javascript to plot x,y coordinates so they fall into a circle rather than a square?
For example if I have the following code:
circleRadius = 100;
context.drawImage(img_elem, dx, dy, dw, dh);
I need to figure out a combination of x,y values that would fall inside a 100 pixel circle.
Thanks!
choose an x at random between -100 and 100
a circle is defined by x^2 + y^2 = r^2, which in your case equals 100^2 = 10000
From this equation you can get that y^2 = 10000 - x^2 , therefore the points with a chosen x and y = +/-sqrt(10000 - x^2) will lye on the circle.
choose an y at random between the two coordinates found at point 3
You're set!
EDIT:
In JS:
var radius = 100;
x = Math.random() * 2 * radius - radius;
ylim = Math.sqrt(radius * radius - x * x);
y = Math.random() * 2 * ylim - ylim;
Another edit: a jsFiddle Example
If you want equidistributed coordinates you better go for
var radius = 100
var center_x = 0
var center_y = 0
// ensure that p(r) ~ r instead of p(r) ~ constant
var r = radius*Math.sqrt(Math.random(1))
var angle = Math.sqrt(2*Math.PI)
// compute desired coordinates
var x = center_x + r*Math.cos(angle);
var y = center_y + r*Math.sin(angle);
If you want more points close to the middle then use
var r = radius*Math.random(1)
instead.
not sure what you mean for javascript but
x = R*cos(theta) and y = R*sin(theta) are the Cartesian points for a circle. R is the radius of course and theta is the angle which goes from 0 to 2*Pi.
I'm posting this as a solution because this question was the only relevant result in google.
My question/problem was how to add cartesian coordinates inside a circle where x and y would not exceed r.
Examples:
plot: (45,75) inside a circle with a radius of 100 (this would normally fall inside the circle, but not the correct position)
plot: (100,100) inside a circle with a radius of 100 (this would normally fall outside the circle
Solution
// The scale of the graph to determine position of plot
// I.E. If the graph visually uses 300px but the values only goto 100
var scale = 100;
// The actual px radius of the circle / width of the graph
var radiusGraph = 300;
// Plot the values on a cartesian plane / graph image
var xCart = xVal * radiusGraph;
var yCart = yVal * radiusGraph;
// Get the absolute values for comparison
var xCartAbs = Math.abs( xCart );
var yCartAbs = Math.abs( yCart );
// Get the radius of the cartesian plot
var radiusCart = Math.sqrt( xCart * xCart + yCart * yCart );
// Compare to decide which value is closer to the limit
// Once we know, calculate the largest possible radius with the graphs limit.
// r^2 = x^2 + y^2
if ( xCartAbs > yCartAbs ) { // Less than 45°
diff = scale / xCartAbs;
radiusMaximum = Math.sqrt( radiusGraph * radiusGraph + Math.pow( yCartAbs * diff, 2) );
} else if ( yCartAbs > xCartAbs ) { // Greater than 45°
diff = scale / yCartAbs;
radiusMaximum = Math.sqrt( radiusGraph * radiusGraph + Math.pow( xCartAbs * diff, 2) );
} else { // 45°
radiusMaximum = Math.sqrt( 2 * ( radiusGraph * radiusGraph ) );
}
// Get the percent of the maximum radius that the cartesian plot is at
var radiusDiff = radiusCart / radiusMaximum;
var radiusAdjusted = radiusGraph * radiusDiff;
// Calculate the angle of the cartesian plot
var theta = Math.atan2( yCart, xCart );
// Get the new x,y plot inside the circle using the adjust radius from above
var xCoord = radiusAdjusted * Math.cos( theta );
var yCoord = radiusAdjusted * Math.sin( theta );
Not sure if this is correct JavaScript code, but something like this:
for (x = -r; x < r; x++) {
for (y = -r; x < r; y++) {
if ((x * x + y * y) < (r * r)) {
// This x/y coordinate is inside the circle.
// Use <= if you want to count points _on_ the circle, too.
}
}
}

Categories