Find the point with radius and angle - actionscript-3

I'm not a genius in geometry, I'd like to find a point in as3 with the radius and a angle but I don't remember the rule, I know this should be simple!
Here's an example:
alt text http://img297.imageshack.us/img297/4879/examplepr.png

as3.x = centerX + radius * cos(angle)
as3.y = centerY + radius * sin(angle)
Note that the rotation in the picture linked to is in the "negative direction". I.e, an increase of the angle, yields a counter-clockwise rotation.

Let x0, y0 be the center of the circle being considered and t be the angle theta anti-clockwise from the x-axis (right horizontal).
The point you are looking for is then
x = x0 + r*cos(t)
y = y0 + r*sin(t)

You have to adjust your calculator to degree mode before making that calculation
more likley you will use angle in degree

Related

AS3 shooting bullets to cursor from centre of character position

I'm making a top down shooter game. I've got my character moving. All I want to do next is make a bullet shoot from the center of my character to the direction my cursor is at. How would i go about doing this?
I'm really struggling to think of the code i need to make this work.
This will involve simple vector math. There are tons of resources online about this. Here's the basic gist:
1) First, calculate the angle (in radians) between your character and your target (in this case the mouse location). You can use Math.atan2() to perform this calculation.
var angle:Number = Math.atan2(mouseY - playerY, mouseX - playerX);
2) Next, use that angle to create a vector (x,y delta) which represents the direction of travel for your bullet. You use Math.cos() and Math.sin() to compute the x and y value:
var speed:Number = 5;
var vector:Point = new Point(Math.cos(angle) * speed, Math.sin(angle) * speed);
3) Now you can update the bullets position each frame by that vector:
bullet.x += vector.x;
bullet.y += vector.y;
4) And if you want to make your bullet sprite point in the direction of travel, convert that angle to degrees and set the bullet sprite's rotation:
var degrees:Number = angle * (180 / Math.PI);
bullet.rotation = degrees;
Note that for the purpose of the math here, 0 degrees is considered to be right-facing along the x-axis, not up-facing like you might naturally think of 0 degrees (at least I do). What this means is your sprites unrotated orientation should be facing right-ward.

Solving the Points on a Rotated Rectangle

I am working in AS3.
I have a generic rectangle. This rectangle can have any length, any width and any rotation. I am trying to solve for the x and y coordinates of the four corners of the rectangle. I know the coordinates of the centre of the rectangle, I know its width, its height, the y distance between the highest and lowest point and the x distance between the farthest left and farthest right point as well as knowing the rotation.
My code currently looks like this (Object, of course, being the rectangle in question, keep in mind that when I apply this it can have any dimensions - This is just one possibility. Initial width and height are the actual length and width, while width and height referenced later are the x and y distances between the highest and lowest points and the farthest left and right points, rotation is of course rotation, and x and y are the object's centre coordinates).
import flash.events.Event;
addEventListener(Event.ENTER_FRAME, Rotate, false, 0, true);
var Radius:Number = Math.sqrt(((Object.height / 2) * (Object.height / 2)) + ((Object.width / 2) * (Object.width / 2)));
function Rotate(event:Event)
{
Object.rotation += 1;
Marker1.x = Math.sqrt((Radius * Radius) - ((Object.height / 2) * (Object.height / 2))) + Object.x;
Marker2.x = - Math.sqrt((Radius * Radius) - ((Object.height / 2) * (Object.height / 2))) + Object.x;
Marker3.y = Math.sqrt((Radius * Radius) - ((Object.width / 2) * (Object.width / 2))) + Object.y;
Marker4.y = - Math.sqrt((Radius * Radius) - ((Object.width / 2) * (Object.width / 2))) + Object.y;
Marker1.y = Object.y + (Object.height / 2);
Marker2.y = Object.y - (Object.height / 2);
Marker3.x = Object.x + (Object.width / 2);
Marker4.x = Object.x - (Object.width / 2);
}
As you can see I am attempting to use circle geometry to place four small circles (Markers 1-4) at the corners of the rectangle, just for testing purposes to confirm that I have gathered the correct coordinates. Problem is, the coordinates will always be placed in either +x and +y or -x and -y, but never the other two quadrants of the graph. I can't figure out a simple way of dynamically simulating the +- of the quadratic equation in the program. Does anyone know of a way to find these four points with and length, width and rotation of the rectangle?
If you represent the coordinates of the corners as offsets from the midpoint of the rectangle you can easily rotate them anti-clockwise by an angle θ with
dx' = dx × cos θ - dy × sin θ
dy' = dx × sin θ + dy × cos θ
You can then add the rotated offsets to the midpoint to recover the new coordinates of the corners.

the relation of the bezier Curve and ellipse?

I want to draw a oval in html5 canvas,and i found a good method for it in stackoverflow.but I have another quesition.
function drawEllipse(ctx, x, y, w, h) {
var kappa = 0.5522848;
ox = (w / 2) * kappa, // control point offset horizontal
oy = (h / 2) * kappa, // control point offset vertical
xe = x + w, // x-end
ye = y + h, // y-end
xm = x + w / 2, // x-middle
ym = y + h / 2; // y-middle
ctx.beginPath();
ctx.moveTo(x, ym);
ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
ctx.closePath();
ctx.stroke();
}
the method in the above link has use bezierCurveTo to draw a ellipse,but it has draw bezierCurveTo 4 times. but I think just 2 bezierCurveTo can draw a ellipse.like this:
but i'm weak in Mathematics,could someone tell me the relationship of "the control point" and "the oval point" please? or we must draw four bezier Curve to draw a oval?
thanks everybody
My background isn't in mathematics so if I'm wrong I'm sure someone will correct me, but from my understanding we can draw a pretty good approximation of an ellipse with just two cubic bezier curves but the coordinates will be a little tricky.
To answer your question about the relation between the oval point and the control points I think it best be answered by watching this video from the point I've selected if you're familiar with interpolation or from the beginning if you are not. Don't worry it is short.
One problem we're probably going to run into is that when we start from the top and do a bezierCurveTo the bottom of the ellipse with the corners of the rectangle (of the same width and height) as the control points, the ellipses width is going to be smaller than the rectangle. .75 times the size we want. So we can just scale the control points accordingly.
Our control point's x would be adjusted like so (assuming width is the width of the ellipse and we're dividing by two to get its offset from the origin)
var cpx = (width / .75) / 2;
Put together a visualization where you can play with the width and height and see the drawn ellipse.
The red ellipse is how we wanted it to be drawn, with the inner one how it would be drawn if we didnt reposition the control points. The lines illustrate De Casteljau's algorithm that was shown in the video.
Here's a screenshot of the visualization
You only need two cubic bezier curves to draw an ellipse. Here's a simplified version of DerekR's code that uses the original function arguments that you provided--assuming you want x and y to be the center of the ellipse:
jsFiddle
function drawEllipse(ctx, x, y, w, h) {
var width_over_2 = w / 2;
var width_two_thirds = w * 2 / 3;
var height_over_2 = h / 2;
ctx.beginPath();
ctx.moveTo(x, y - height_over_2);
ctx.bezierCurveTo(x + width_two_thirds, y - height_over_2, x + width_two_thirds, y + height_over_2, x, y + height_over_2);
ctx.bezierCurveTo(x - width_two_thirds, y + height_over_2, x - width_two_thirds, y - height_over_2, x, y -height_over_2);
ctx.closePath();
ctx.stroke();
}
Big thanks to BKH.
I used his code with two bezier curves to complete my ellipse drawing with any rotation angle. Also, I created an comparison demo between ellipses drawn by bezier curves and native ellipse() function (for now implemented only in Chrome).
function drawEllipseByBezierCurves(ctx, x, y, radiusX, radiusY, rotationAngle) {
var width_two_thirds = radiusX * 4 / 3;
var dx1 = Math.sin(rotationAngle) * radiusY;
var dy1 = Math.cos(rotationAngle) * radiusY;
var dx2 = Math.cos(rotationAngle) * width_two_thirds;
var dy2 = Math.sin(rotationAngle) * width_two_thirds;
var topCenterX = x - dx1;
var topCenterY = y + dy1;
var topRightX = topCenterX + dx2;
var topRightY = topCenterY + dy2;
var topLeftX = topCenterX - dx2;
var topLeftY = topCenterY - dy2;
var bottomCenterX = x + dx1;
var bottomCenterY = y - dy1;
var bottomRightX = bottomCenterX + dx2;
var bottomRightY = bottomCenterY + dy2;
var bottomLeftX = bottomCenterX - dx2;
var bottomLeftY = bottomCenterY - dy2;
ctx.beginPath();
ctx.moveTo(bottomCenterX, bottomCenterY);
ctx.bezierCurveTo(bottomRightX, bottomRightY, topRightX, topRightY, topCenterX, topCenterY);
ctx.bezierCurveTo(topLeftX, topLeftY, bottomLeftX, bottomLeftY, bottomCenterX, bottomCenterY);
ctx.closePath();
ctx.stroke();
}
You will find this explained slightly more math-based in http://pomax.github.io/bezierinfo/#circles_cubic, but the gist is that using a cubic bezier curve for more than a quarter turn is usually not a good idea. Thankfully, using four curves makes finding the required control points rather easy. Start off with a circle, in which case each quarter circle is (1,0)--(1,0.55228)--(0.55228,1)--(0,1) with scaled coordinates for your ellipse. Draw that four times with +/- signs swapped to effect a full circle, scale the dimensions to get your ellipse, and done.
If you use two curves, the coordinates become (1,0)--(1,4/3)--(-1,4/3)--(-1,0), scaled for your ellipse. It may still look decent enough in your application, it depends a bit on how big your drawing ends up being.
It can be mathematically proven, that circle can not be made with Bézier curve of any degree. You can make "almost circle" by approximating it.
Say you want to draw a quarter of circle around [0,0]. Cubic bézier coordinates are:
[0 , 1 ]
[0.55, 1 ]
[1 , 0.55]
[1 , 0 ]
It is a very good approximation. Transform it linearly to get an ellpise.

How do I calculate the location of points in a rotated shape AS3

I am creating a game in which I draw a series of polygons by creating points around a radius of a cricle.
Later on I rotate the shapes and I need to calculate the new location (X,Y) of the points based on the rotation. I have the Old XY of each point, the XY of the center of the shape, radius of shape and the rotation.
Have a look at my diagram of the problem.
It should be possible to use matrix transformations for this, but you can also do it manually:
http://www.siggraph.org/education/materials/HyperGraph/modeling/mod_tran/2drota.htm
So essentially;
newX = initialX * Math.cos(angle) - initialY * Math.sin(angle);
newY = initialY * Math.cos(angle) + initialX * Math.sin(angle);
//Angle is in radians btw
This assumes that the initialX/Y is relative to the center of rotation, so you would have to subtract the center point before starting, and then add it again after the calculation to place it correctly.
Hope this helps!
For each point do:
alpha = arctan2(x, y)
len = sqrt(x^2 + y^2)
newX = len * cos(alpha + rotation)
newy = len * sin(alpha + rotation)
Original [x,y] and new [newX,newY] coordinates are both relative to the center of your rotation. If your original [x,y] is absolut, you have to calculate relative first:
x = xAbs - xCenter
y = yAbs - yCenter
Make sure your arctan2 function provides a result of PI/2 or -PI/2 if x=0. Primitive arctan functions do not allow x=0.

Drawing an arrow at the end point of the line using line slope

I am developing a white board application which allows the user to draw line with arrow head (some like Microsoft Word line with arrow feature). I am using graphics property along with lineTo() method to draw a line. Now i have to draw a angular arrow on the last point of line. I am drawing the arrow by connecting the points around last points. As 360 line can pass through this point and each line can have a different angle of arrow. Please suggest me the way to calculating these point around the last point.
I've been doing something myself, and I needed it to look a bit nicer than just a triangle, and use relatively inexpensive calculations (as few calls to other functions as possible, like Math trigonometry). Here it is:
public static function DrawArrow(ax:int, ay:int, bx:int, by:int):void
{
// a is beginning, b is the arrow tip.
var abx:int, aby:int, ab:int, cx:Number, cy:Number, dx:Number, dy:Number, ex:Number, ey:Number, fx:Number, fy:Number;
var size:Number = 8, ratio:Number = 2, fullness1:Number = 2, fullness2:Number = 3; // these can be adjusted as needed
abx = bx - ax;
aby = by - ay;
ab = Math.sqrt(abx * abx + aby * aby);
cx = bx - size * abx / ab;
cy = by - size * aby / ab;
dx = cx + (by - cy) / ratio;
dy = cy + (cx - bx) / ratio;
ex = cx - (by - cy) / ratio;
ey = cy - (cx - bx) / ratio;
fx = (fullness1 * cx + bx) / fullness2;
fy = (fullness1 * cy + by) / fullness2;
// draw lines and apply fill: a -> b -> d -> f -> e -> b
// replace "sprite" with the name of your sprite
sprite.graphics.clear();
sprite.graphics.beginFill(0xffffff);
sprite.graphics.lineStyle(1, 0xffffff);
sprite.graphics.moveTo(ax, ay);
sprite.graphics.lineTo(bx, by);
sprite.graphics.lineTo(dx, dy);
sprite.graphics.lineTo(fx, fy);
sprite.graphics.lineTo(ex, ey);
sprite.graphics.lineTo(bx, by);
sprite.graphics.endFill();
}
You can also add the line color and thickness to the argument list, and maybe make it a member function of an extended Sprite, and you have a pretty nice, versatile function :) You can also play a bit with the numbers to get different shapes and sizes (small changes of fullness cause crazy changes in look, so careful :)). Just be careful not to set ratio or fullness2 to zero!
If you store the start and end point of the line, adding the arrow head should be relatively simple. If you subtract the end point coordinates from the start point coordinates, you will get the arrow direction vector (let's call it D). With this vector, you can determine any point on the line between the two points.
So, to draw the arrow head, you would need to determine a point (P1) on the segment that has a specific distance (d1) from the end point, determine a line that passes through it, and is perpendicular to D. And finally get a point (P2) that has a distance (d2) from the previously determined point. You can then determine the point that is symmetrical to P2, relative to D.
You will thus have an arrow head the length of d1 and a base with of 2 * d2.
Some additional information and a few code examples here: http://forums.devx.com/archive/index.php/t-74981.html