I'm trying to find intersecting point on circle. Can anybody solve this?. please find my problem's explanation image click here to see image
I'm going to assume you have the radius of the circle, as well as the center point of the circle. If you do, then the coordinates of the respective points are as follows:
// assume r is set to the radius of the circle
// and (x, y) is the center of the circle
p1.x = x - r * Math.sin(Math.acos(150 / r));
p1.y = y + 150;
p2.x = x + r * Math.sin(Math.acos(150 / r));
p2.y = y + 150;
Related
I want to calculate the rotation of a specific point (top and left). It's a bit complicated. I know the original top and left. Then a scaling is added and then the rotation is calculated.
At the moment i do this. (orginal left:-350, orginal top: -10, f1_scale: 0.544444, rotation angle:-30deg)
function sin(x) {
return Math.sin(x / 180 * Math.PI);
}
function cos(x) {
return Math.cos(x / 180 * Math.PI);
}
function rotate(x, y, a) {
var x2 = cos(a) * x - sin(a) * y;
var y2 = sin(a) * x - cos(a) * y;
return [x2, y2];
}
var scaledLeft = -350 * f1_scale;
var scaledTop = -10 * f1_scale;
var rotateOut = rotate(scaledLeft, scaledTop,-30);
This works for the left (x) coordinate, but the y coordinate is way off.
Can someone see what i did wrong or did someone already tried this?
Thank you.
You need to understand math behind it. First, look at this image http://prntscr.com/amd2it where:
(x0, y0) are coordinates of starting point
(x1, y1) are coordinates after rotation
(p, q) are coordinates of point of rotation
In order to find (x1, y1), you need to know value of (p, q), as well as (x0, y0) and angle a. If we apply elementary geometry, we get this:
sin(a)( q - y0 ) = q - y1
y1 = q - sin(a)( q - y0 )
and
cos(a)( p - x0 ) = p - x1
x1 = p - cos(a)( p - x0 )
or you can use Pythagoras' theorem for second value.
When we understand this, I don't think it will be problem to translate it to code.
I have two rectangles with pivots,
I need to attach the position of the green rectangle based on the rotation of the red rectangle
The result should be like in the picture:
I tried different formulas and nothing succeeded
red rectangle:
x=500, y=100, width=200, height=500, pivotX=100, pivotY=400
green rectangle:
x=450, y=150, width=100, height=400, pivotX=50, pivotY=50
I tried something like this:
var radians = (Math.PI / 180) * red.degree;
green.x += red.pivotX * Math.cos(radians) - red.pivotY * Math.sin(radians);
green.y += red.pivotX * Math.sin(radians) + red.pivotY * Math.cos(radians);
Big thanks to everyone that helped!
The pivot of a rectangle is originally at position (x + pivotX, y + pivotY). Take the vector pointing from the red pivot point towards the green pivot point, namely
vx = green.x + green.pivotX - red.x - red.pivotX;
vy = green.y + green.pivotY - red.y - red.pivotY;
That's the vector you rotate:
wx = Math.cos(radians)*vx - Math.sin(radians)*vy;
wy = Math.sin(radians)*vx + Math.cos(radians)*vy;
Then you can use that rotated w instead of the original v to determine the position of the green rectangle:
green.x += wx - vx;
green.y += wy - vy;
How can I detect when the user clicks inside the red bubble?
It should not be like a square field. The mouse must be really inside the circle:
Here's the code:
<canvas id="canvas" width="1000" height="500"></canvas>
<script>
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext("2d")
var w = canvas.width
var h = canvas.height
var bubble = {
x: w / 2,
y: h / 2,
r: 30,
}
window.onmousedown = function(e) {
x = e.pageX - canvas.getBoundingClientRect().left
y = e.pageY - canvas.getBoundingClientRect().top
if (MOUSE IS INSIDE BUBBLE) {
alert("HELLO!")
}
}
ctx.beginPath()
ctx.fillStyle = "red"
ctx.arc(bubble.x, bubble.y, bubble.r, 0, Math.PI*2, false)
ctx.fill()
ctx.closePath()
</script>
A circle, is the geometric position of all the points whose distance from a central point is equal to some number "R".
You want to find the points whose distance is less than or equal to that "R", our radius.
The distance equation in 2d euclidean space is d(p1,p2) = root((p1.x-p2.x)^2 + (p1.y-p2.y)^2).
Check if the distance between your p and the center of the circle is less than the radius.
Let's say I have a circle with radius r and center at position (x0,y0) and a point (x1,y1) and I want to check if that point is in the circle or not.
I'd need to check if d((x0,y0),(x1,y1)) < r which translates to:
Math.sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0)) < r
In JavaScript.
Now you know all these values (x0,y0) being bubble.x and bubble.y and (x1,y1) being x and y.
To test if a point is within a circle, you want to determine if the distance between the given point and the center of the circle is smaller than the radius of the circle.
Instead of using the point-distance formula, which involves the use of a (slow) square root, you can compare the non-square-rooted (or still-squared) distance between the points. If that distance is less than the radius squared, then you're in!
// x,y is the point to test
// cx, cy is circle center, and radius is circle radius
function pointInCircle(x, y, cx, cy, radius) {
var distancesquared = (x - cx) * (x - cx) + (y - cy) * (y - cy);
return distancesquared <= radius * radius;
}
(Not using your code because I want to keep the function general for onlookers who come to this question later)
This is slightly more complicated to comprehend, but its also faster, and if you intend on ever checking point-in-circle in a drawing/animation/object moving loop, then you'll want to do it the fastest way possible.
Related JS perf test:
http://jsperf.com/no-square-root
Just calculate the distance between the mouse pointer and the center of your circle, then decide whether it's inside:
var dx = x - bubble.x,
dy = y - bubble.y,
dist = Math.sqrt(dx * dx + dy * dy);
if (dist < bubble.r) {
alert('hello');
}
Demo
As mentioned in the comments, to eliminate Math.sqrt() you can use:
var distsq = dx * dx + dy * dy,
rsq = bubble.r * bubble.r;
if (distsq < rsq) {
alert('HELLO');
}
An alternative (not always useful meaning it will only work for the last path (re)defined, but I bring it up as an option):
x = e.pageX - canvas.getBoundingClientRect().left
y = e.pageY - canvas.getBoundingClientRect().top
if (ctx.isPointInPath(x, y)) {
alert("HELLO!")
}
Path can btw. be any shape.
For more details:
http://www.w3.org/TR/2dcontext/#dom-context-2d-ispointinpath
I'm Having a Bezier Curve in Javascript built with a few bezier Curves.
I can move handles and they keep the symmetry. I'm doing that by first calculating
the distance between Handle and Point on BeziƩr. Then I compare the distances
of the two handles, calculate a multiplier and apply it to the not dragged
handle. This works for keeping Symmetry.
But I want to achieve that the length of the not dragged handle stays the same.
http://cl.ly/image/0c1z00131m2y (a little picture explaining what i mean).
The code, i currently use to calculate the movement is this:
dx = Math.abs(drag.x - point.p[(draggedItemIndex)/2].x);
dy = Math.abs(drag.y - point.p[(draggedItemIndex)/2].y);
dx2 = Math.abs(point.cp[draggedItemIndex-1].x - point.p[draggedItemIndex/2].x);
dy2 = Math.abs(point.cp[draggedItemIndex-1].y - point.p[draggedItemIndex/2].y);
dxdx = dx2/dx;
dydy = dy2/dy;
point.cp[draggedItemIndex-1].x -= dragX*dxdx;
point.cp[draggedItemIndex-1].y -= dragY*dydy;
Thank you for your answer.
I'm now doing it with ciruclar calculations.
//Circle Center Point
cx = point.p[(draggedItemIndex)/2].x;
cy = point.p[(draggedItemIndex)/2].y;
//Dragged Point Position (To Circle Origin)
x1 = drag.x - cx;
y1 = drag.y - cy;
//Mirrored Point Position (To Circle Origin)
x2 = point.cp[draggedItemIndex-1].x - cx;
y2 = point.cp[draggedItemIndex-1].y - cy;
//Angle Dragged Point
a1 = Math.atan2(-y1,x1)*(180/Math.PI);
//Mirrored Angle
a2 = (a1-180)*(Math.PI/180)*(-1);
//Mirrored Point Radius
r = Math.sqrt(Math.pow(x2, 2)+Math.pow(y2, 2));
//Apply new Position to Point
point.cp[draggedItemIndex-1].x = cx + r * Math.cos(a2);
point.cp[draggedItemIndex-1].y = cy + r * Math.sin(a2);
I found this excellent question and answer which starts with x/y (plus the center x/y and degrees/radians) and calculates the rotated-to x'/y'. This calculation works perfectly, but I would like to run it in the opposite direction; starting with x'/y' and degrees/radians, I would like to calculate the originating x/y and the center x/y.
(x', y') = new position
(xc, yc) = center point things rotate around
(x, y) = initial point
theta = counterclockwise rotation in radians (radians = degrees * Pi / 180)
dx = x - xc
dy = y - yc
x' = xc + dx cos(theta) - dy sin(theta)
y' = yc + dx sin(theta) + dy cos(theta)
Or, in JavaScript/jQuery:
XYRotatesTo = function($element, iDegrees, iX, iY, iCenterXPercent, iCenterYPercent) {
var oPos = $element.position(),
iCenterX = ($element.outerWidth() * iCenterXPercent / 100),
iCenterY = ($element.outerHeight() * iCenterYPercent / 100),
iRadians = (iDegrees * Math.PI / 180),
iDX = (oPos.left - iCenterX),
iDY = (oPos.top - iCenterY)
;
return {
x: iCenterX + (iDX * Math.cos(iRadians)) - (iDY * Math.sin(iRadians)),
y: iCenterY + (iDX * Math.sin(iRadians)) + (iDY * Math.cos(iRadians))
};
};
The math/code above solves for the situation in Figure A; it calculates the position of the destination x'/y' (green circle) based on the known values for x/y (red circle), the center x/y (blue star) and the degrees/radians.
But I need math/code to solve for Figure B; where I can find not only the destination x/y (green circle), but also the destination center x/y (green star) from the known values of the starting x/y (grey circle, though probably not needed), the destination x'/y' (red circle) and the degrees/radians.
The code above will solve for the destination x/y (green circle) via iDegrees * -1 (thanks to #andrew cooke's answer which has since been removed by him), but in order to do that I need to feed into it the location of the destination center x/y (green star), and that is the calculations I'm currently missing, as you can see in Diagram C, below:
So... how do I find the coordinates ?/? (green star) given n, A (angle) and x'/y' (red circle)?
You're trying to find an inverse transformation. You start with the composition of two linear transformations, a translation T and a rotation R. You apply R first to a vector x and T second, so the expression is y = TRx. To solve the inverse problem you need the inverse of TR, written (TR)-1, which is equal to R-1T-1. The inverse of the rotation R is just the rotation by the negative of the angle (which you mention). The inverse of the translation is, similarly, the original translation multiplied by -1. So your answer is x = R-1T-1y.
In your present situation, you're given the rotation by means of its angle, but you'll need to compute the translation. You'll need the grey circle, which you didn't think you would need. Apply the rotation R (not its inverse) to the gray circle. Subtract this point from the red circle. This is the original translation T. Reverse the sign to get T-1.