Dynamically compute SVG Path for a full circle with JavaScript - javascript

I'm trying to draw the perimeter of a circle depending on the angle inputed by the user. The angle determines the perimeter completion : 360° being the full circle, 180 half of the circle, and so on.
My problem is : given the radius, the angle and the center coordinates of the circle, how can I dynamically compute the path of the perimeter ?
I know it's probably basic math but everything I tried so far didn't work.
Here is my fiddle : https://jsfiddle.net/Hal_9100/L311qq88/
My problem is finding the right formula for the x and y coordinates of the path :
var x = i * (radius * Math.cos(angle)) + centerX;
var y = i * (radius * Math.sin(angle)) + centerY;
Am I going all wrong here ?
Here is an example of what I'm trying to do : please note that only the black perimeter should be drawn : I just used the dotted red lines to give a visual example of how the perimeter should be drawn depending on the value given by the user.

Yes, the problem is your maths. Here is the correct way to calculate the x,y coordinate pairs (note that the iteration is from zero to the required angle, not from zero to the radius):
for (var i = 0; i <= angle; i++) {
var x = (radius * Math.cos((i-90)*Math.PI/180)) + centerX;
var y = (radius * Math.sin((i-90)*Math.PI/180)) + centerY;
Your fiddle works fine if you substitute these three lines.

Related

Intersection of two Moving Objects

I'm trying to use the answer provided here: Intersection of two Moving Objects with Latitude/Longitude Coordinates
But I have some questions..
What is this angle:
var angle = Math.PI + dir - target.dir
I was thinking that the angle that should be used in the law of cosines is already "alpha or target.dir".. What is that line doing? Also in these two steps:
var x = target.x + target.vel * time * Math.cos(target.dir);
var y = target.y + target.vel * time * Math.sin(target.dir);
Shouldn't the code be using the angle between x- or y-axis and the target velocity vector? Why is the author using alpha here?
What is this angle:
var angle = Math.PI + dir - target.dir
The variable named angle is indeed the angle alpha. Because the direction dir is the direction from chaser to target, and we need it the other way round for this calculation, we add π to it before we subtract target.dir.
Maybe using the word angle as a variable name was a bit vague; I'll change it to alpha, the name I used for this angle in the images.
Shouldn't the code be using the angle between x- or y-axis and the target velocity vector? Why is the author using alpha here?
var x = target.x + target.vel * time * Math.cos(target.dir);
var y = target.y + target.vel * time * Math.sin(target.dir);
We are indeed using target.dir, which is the direction of the target, i.e. the angle between the x-axis and the target vector, to calculate the coordinates of the interception point, and not the angle alpha.

Get pixel position from bearing

I need to position a dot on a coordinate system based on its bearing and radius.
Using the following code i can position a dot at the correct distance from the center, but this only works horizontally.
What i need is both top & left position of the dot based on bearing & radius
setTimeout(function() {
var km2show = 100;
var testDistance = 50;
var width = $('#radar').width(); // Width & height of radar
var center = width/2; // Radar center
var px2km = center/km2show; // Pixels per km
var radius = radius2coor((px2km*testDistance),center);
var bearing = 45;
// Set height of radar based on the width
$('#radar').height(width);
// Set dot in center of radar
$('#centerDot').css({top: center, left: center});
$('#container').append("<div style='position:absolute;top:0px;left:"+radius+"px;color:white;'>*</div>");
},100);
function radius2coor(radius,center) {
var res = radius-center;
return res;
}
Please see
jsFiddle
So how would i go about getting bot top and left position of the dot ?
The end result should position the dot at the red marker having a bearing of 45 degrees:
The main issue you were encountering was that the angle wasn't in radians so first thing we want is to convert the 45 degrees to pi/4.
Also, when going from regular angular coordinates to x,y coordinates you multiply the radius by sine of the angle to find y coordinate and you multiply the radius by the cosine of the angle to get the x coordinate. Just think about the unit circle and it will make sense.
var bearing = parseInt(prompt("enter angle in degrees", "0"));
if(!isNaN(bearing)){
setTimeout(function() {
var km2show = 100;
var testDistance = 50;
var width = $('#radar').width(); // Width & height of radar
var center = width/2; // Radar center
var px2km = center/km2show; // Pixels per k
//not sure what this is doing so I set a random radius
//(called it distanceFromCenter). If you need this to be
//the distance between two cartesian points then you can
//just implement the distance formula.
//var radius = radius2coor((px2km*testDistance),center);
var radius = 100;
var radianBearing = (bearing/180)*Math.PI
// Set height of radar based on the width
$('#radar').height(width);
// Set dot in center of radar
$('#centerDot').css({top: center, left: center});
//the main issue you were encountering was that the angle wasn't in radians so I converted it.
positionDot(radius, radianBearing);
},100);
}
function positionDot(distanceFromCenter, bearing, width)
{
//when going from regular angular coordinates to x,y coordinates you multiply the radius by sine of the angle to find y coordinate and you multiply the radius by the cosine of the angle to get the x coordinate.
$('#container').append("<div style='position:absolute;top:"+(-distanceFromCenter*Math.sin(bearing)).toString()+"px;left:"+distanceFromCenter*Math.cos(bearing)+"px;color:white;'>*</div>");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id='radar' style='width:100%;max-width:400px;height:400px;border:1px black solid;border-radius:400px;background-color:#3c3c3c;position:relative;'>
<div id='centerDot' style='position:absolute;color:white;'>
<div style='position:relative;' id='container'></div>
<b>*</b>
</div>
</div>
To get both coordinates, you need coordinates of center, radius and bearing.
Note that trigonometric functions usually work with argument in radians, not degrees (don't know about javascript math library)
P.X = Center.X + Radius * Math.Cos(bearing)
P.Y = Center.Y + Radius * Math.Sin(bearing)
You can get it with:
x = center + radius * cos(bearing)
y = center + radius * sin(bearing)
and as MBo said, you have to convert bearing into radians
rad = deg * PI / 180
https://upload.wikimedia.org/wikipedia/sr/8/85/Trig-funkcije1.gif

collision check of a moving circle

im working on a 2d canvas game. i have a player circle and some circles (random in size and position). i made the random circles move around an random x.y point. this means i have to radii. one is the radius from the rotationpoint to the middlepoint of the "bubble" and the other ist die radius of the bubble itself.
what i need is the collision between playercircle und the bubbles. i know how to create circle to circle collisondetction with pythagorean theorem and it works quite well. However there is a problem:
right now the collision works for the random x and y point + the radius (from rotationpoint) but not for the bubble itself.
what i tryed is to store the x and y of the rotationpoint + the radius to the middlepoint of the bubble into a variable to use them in collision. it works quite fine. if i console.log these x and y points they give me the changing x and ys from the middlepoint of the bubble.
my problem now is that if if substract these point from the playercircle x and y i didnt work with the right collision. so obviously im missing somethig and right now i am at a dead end.
i made a fiddle to show you, the function for the collision is on line 170, variablenames BubbleX and BubbleY. The .counter to animate the around the neg. or positiv:
http://jsfiddle.net/CLrPx/1/ (you need to use the console to the if there is a collision or not)
function collideBubbles(c1, c2) {
// moving/rotation xPos and yPos
var bubbleX = c2.xPos + Math.cos(c2.counter / 100) * c2.radius; // actual x and y pos. from bubble!
var bubbleY = c2.yPos + Math.cos(c2.counter / 100) * c2.radius;
//console.log('bubbleX: ' + bubbleX);
//console.log('bubbleY: ' + bubbleY);
var dx = c1.xPos - bubbleX; // change with pos from actual bubble!
var dy = c1.yPos - bubbleY; // change with pos from actual bubble!
var distance = c1.radius + c2.bubbleRadius
// Pytagorean Theorem
return (dx * dx + dy * dy <= distance * distance);
}

Javascript: Find point on perpendicular line always the same distance away

I'm trying to find a point that is equal distance away from the middle of a perpendicular line. I want to use this point to create a Bézier curve using the start and end points, and this other point I'm trying to find.
I've calculated the perpendicular line, and I can plot points on that line, but the problem is that depending on the angle of the line, the points get further away or closer to the original line, and I want to be able to calculate it so it's always X units away.
Take a look at this JSFiddle which shows the original line, with some points plotted along the perpendicular line:
http://jsfiddle.net/eLxcB/1/.
If you change the start and end points, you can see these plotted points getting closer together or further away.
How do I get them to be uniformly the same distance apart from each other no matter what the angle is?
Code snippit below:
// Start and end points
var startX = 120
var startY = 150
var endX = 180
var endY = 130
// Calculate how far above or below the control point should be
var centrePointX = ((startX + endX) / 2);
var centrePointY = ((startY + endY) / 2);
// Calculate slopes and Y intersects
var lineSlope = (endY - startY) / (endX - startX);
var perpendicularSlope = -1 / lineSlope;
var yIntersect = centrePointY - (centrePointX * perpendicularSlope);
// Draw a line between the two original points
R.path('M '+startX+' '+startY+', L '+endX+' '+endY);
Generally you can get the coordinates of a normal of a line like this:
P1 = {r * cos(a) + Cx, -r * sin(a) + Cy},
P2 = {-r * cos(a) + Cx, r * sin(a) + Cy}.
A demo applying this to your case at jsFiddle.

Points on a (un)rotated rectangle

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.

Categories

Resources