Source: https://mathbase.googlecode.com/svn
Basic form for formula of mathematics
Building the basic form to show the mathematical formula. - The project will start from 25/3/2012
Source: https://mathbase.googlecode.com/svn
Source: https://mathbase.googlecode.com/svn
Bezier curve
Bézier curve is a parametric curve frequently used in computer graphics and related fields. Generalizations of Bézier curves to higher dimensions are called Bézier surfaces, of which the Bézier triangle is a special case.
In vector graphics, Bézier curves are used to model smooth curves that can be scaled indefinitely. "Paths," as they are commonly referred to in image manipulation programs, are combinations of linked Bézier curves. Paths are not bound by the limits of rasterized images and are intuitive to modify. Bézier curves are also used in animation as a tool to control motion.
In other projects, I have to work with a natural curve and the curve must pass through the given point is limited. After research on other sites, I decided to write this, I know all the other articles were given very specific examples ... but, you know, a thousand a situation, plus I want to keep my knowledge through this article.
Quadratic bezier
Let's go to Wikipedia, you see close to the top of the page that the formula for a quadratic b curve looks like this. Given points P0 and P1, a linear Bézier curve is simply a straight line between those two points. The curve is given by
Written in ActionScript then, we can get the x and y positions of our curve with the following couple lines:
Cubic bezier.
With three points, we always identify a curve passing through(quadratic), how is four points the case?, we have again:
A cubic Bezier curve is defined by four points. Two are endpoints. (x0,y0) is the origin endpoint. (x3,y3) is the destination endpoint. The points (x1,y1) and (x2,y2) are control points.
Two equations define the points on the curve. Both are evaluated for an arbitrary number of values of t between 0 and 1. One equation yields values for x, the other yields values for y. As increasing values for t are supplied to the equations, the point defined by x(t),y(t) moves from the origin to the destination. This is how the equations are defined in Adobe's PostScript references.
x(t) = axt3 + bxt2 + cxt + x0
x1 = x0 + cx / 3
x2 = x1 + (cx + bx) / 3
x3 = x0 + cx + bx + ax
y(t) = ayt3 + byt2 + cyt + y0
y1 = y0 + cy / 3
y2 = y1 + (cy + by) / 3
y3 = y0 + cy + by + ay
This method of definition can be reverse-engineered so that it'll give up the coefficient values based on the points described above:
cx = 3 (x1 - x0)
bx = 3 (x2 - x1) - cx
ax = x3 - x0 - cx - bx
cy = 3 (y1 - y0)
by = 3 (y2 - y1) - cy
ay = y3 - y0 - cy - by
Now, simply by knowing coordinates for any four points, you can create the equations for a simple Bézier curve:
So, back to our formulas, given 4 control points (P0, P1, P2, P3), we can derive the mathematical formula of the cubic bezier as follow:

We can use a nice optimization in term of number of operations, let the formula be:
B(t) = αt3 + βt2 + γt + P0
α = P3 - P0 - γ - β
β =3(P2 - P1) - β
γ =3(P2 - P1)
Cubic bezier with degree n
Given n + 1 control Points Pj with j=0 to n, The bezier parametric curve is given by B(t) as follow:

Bezier curves are parametric curves, it means the formula above is applied independently to the x and y coordinate of the points for a 2D curve. The following shows a hybrid between a Math formula and a ActionScript dot syntax to make the formula easier to grab (hopefully it does):

There are a lot of very interesting property for bezier curves. Below are the fews that are relevant to us in this article:
Bézier curves can be defined for any degree n, you try to write a function with degree n and send to me, I'll very happy! :P
Here my processed for degree n:
http://en.wikipedia.org/wiki/Binomial_coefficient
http://en.wikipedia.org/wiki/Pascal's_triangle
http://en.wikipedia.org/wiki/Series_(mathematics)
http://en.wikipedia.org/wiki/Triangular_number
http://www.paultondeur.com/2008/03/09/drawing-a-cubic-bezier-curve-using-actionscript-3/
http://andywoodruff.com/blog/continuous-curves-with-actionscript-3/
http://blog.organa.ca/?p=38
http://www.algorithmist.net/as3pc.html
http://blog.onebyonedesign.com/actionscript/animating-bezier-curves/
http://code.google.com/p/bezier/
http://kelsocartography.com/blog/?p=2081
http://www.plus1coins.com/2010/06/drawing-bezier-curves-in-flash/
http://www.farmcode.org/post/2009/07/06/Fast-2D-Bezier-Library-for-ActionScript-3.aspx
In vector graphics, Bézier curves are used to model smooth curves that can be scaled indefinitely. "Paths," as they are commonly referred to in image manipulation programs, are combinations of linked Bézier curves. Paths are not bound by the limits of rasterized images and are intuitive to modify. Bézier curves are also used in animation as a tool to control motion.
In other projects, I have to work with a natural curve and the curve must pass through the given point is limited. After research on other sites, I decided to write this, I know all the other articles were given very specific examples ... but, you know, a thousand a situation, plus I want to keep my knowledge through this article.
Quadratic bezier
Let's go to Wikipedia, you see close to the top of the page that the formula for a quadratic b curve looks like this. Given points P0 and P1, a linear Bézier curve is simply a straight line between those two points. The curve is given by
B(t)=(1-t)2P0 + 2(1-t)tP1 + t2P2, t ∈[0,1]
and is equivalent to linear interpolation.Written in ActionScript then, we can get the x and y positions of our curve with the following couple lines:
//loop
t = 0; // t -> 1
P0 = new Point(10, 200);
P1 = new Point(150, 10);
P2 = new Point(260, 200);
//
var xp:Number = ( (1 - t) * (1 - t)) * P0.x + 2 * (1 - t) * t * P1.x + (t * t) * P2.x;
var yp:Number = ( (1 - t) * (1 - t)) * P0.y + 2 * (1 - t) * t * P1.y + (t * t) * P2.y;
| Quadratic bezier - click and move red point |
Cubic bezier.
With three points, we always identify a curve passing through(quadratic), how is four points the case?, we have again:
B(t) = t3(P3 + 3(P1 - P2) - P0) + 3t2(P0 - 2P1 + P2) + 3t(P1 - P0), t ∈[0,1].
B represents the curve, Px represents one of the four points which makes the curve. P0 and P3 are points which we know as anchor points, where P1 and P2 are the control points, t is the position of the curve which we want to calculate.A cubic Bezier curve is defined by four points. Two are endpoints. (x0,y0) is the origin endpoint. (x3,y3) is the destination endpoint. The points (x1,y1) and (x2,y2) are control points.
Two equations define the points on the curve. Both are evaluated for an arbitrary number of values of t between 0 and 1. One equation yields values for x, the other yields values for y. As increasing values for t are supplied to the equations, the point defined by x(t),y(t) moves from the origin to the destination. This is how the equations are defined in Adobe's PostScript references.
x(t) = axt3 + bxt2 + cxt + x0
x1 = x0 + cx / 3
x2 = x1 + (cx + bx) / 3
x3 = x0 + cx + bx + ax
y(t) = ayt3 + byt2 + cyt + y0
y1 = y0 + cy / 3
y2 = y1 + (cy + by) / 3
y3 = y0 + cy + by + ay
This method of definition can be reverse-engineered so that it'll give up the coefficient values based on the points described above:
cx = 3 (x1 - x0)
bx = 3 (x2 - x1) - cx
ax = x3 - x0 - cx - bx
cy = 3 (y1 - y0)
by = 3 (y2 - y1) - cy
ay = y3 - y0 - cy - by
Now, simply by knowing coordinates for any four points, you can create the equations for a simple Bézier curve:
//loop
t = 0; // t->1
P0 = new Point(10, 200);
P1 = new Point(70, 50);
P2 = new Point(200, 50);
P3 = new Point(260, 200);
//.....
var xp:Number = Math.pow(t,3)*(P3.x+3*(P1.x-P2.x)-P0.x) +3*Math.pow(t,2)*(P0.x-2*P1.x+P2.x) +3*t*(P1.x-P0.x)+P0.x;
var yp:Number = Math.pow(t,3)*(P3.y+3*(P1.y-P2.y)-P0.y) +3*Math.pow(t,2)*(P0.y-2*P1.y+P2.y) +3*t*(P1.y-P0.y)+P0.y;
| Cubic bezier - click and move red point |
So, back to our formulas, given 4 control points (P0, P1, P2, P3), we can derive the mathematical formula of the cubic bezier as follow:

We can use a nice optimization in term of number of operations, let the formula be:
B(t) = αt3 + βt2 + γt + P0, t ∈[0,1].
Then the parameters can be calculated as:α = P3 - P0 - γ - β
β =3(P2 - P1) - β
γ =3(P2 - P1)
Cubic bezier with degree n
Given n + 1 control Points Pj with j=0 to n, The bezier parametric curve is given by B(t) as follow:

Bezier curves are parametric curves, it means the formula above is applied independently to the x and y coordinate of the points for a 2D curve. The following shows a hybrid between a Math formula and a ActionScript dot syntax to make the formula easier to grab (hopefully it does):

There are a lot of very interesting property for bezier curves. Below are the fews that are relevant to us in this article:
- At t=0, B(t) is P0 and at t=1, B(t) is Pn. That means that the bezier curves begins at the first control point(j=0) and finishes at the last (j=n).
- At t=0 the curve is tangent to the line (P0, P1) and at t=1, the curve is tangent to the line (Pn, Pn-1)
- The curve is always contained within the convex shape described by the control points.
- It is possible to ensure continuity of two bezier curves by making sure that the tangent to the last control point of the first curve is the same as the tangent to the first control point of the second curve. Which means that if P1,j(j=0 to n) are the control points for the first curve and P2,i (j=0 to m) are the control points for the second one, first order continuity of the two curves can be achieved if P1,n is the same point as P2,0 and if P1,(n-1), P1,n and P2,1 belong to the same line.
//loop
t = 0;
P0 = new Point(88, 213);
P1 = new Point(10, 103);
P2 = new Point(82, 21);
P3 = new Point(178, 20);
P4 = new Point(242, 107);
P5 = new Point(174, 210);
var xp:Number = Math.pow(1 - t, 5) * P0.x
+5 * t * Math.pow(1 - t, 4) * P1.x
+10 * Math.pow(t, 2) * Math.pow(1 - t, 3) * P2.x
+10 * Math.pow(t, 3) * Math.pow(1 - t, 2) * P3.x
+ 5 * Math.pow(t, 4) * (1 - t) * P4.x + Math.pow(t, 5) * P5.x;
var yp:Number = Math.pow(1 - t, 5) * P0.y
+5 * t * Math.pow(1 - t, 4) * P1.y
+10 * Math.pow(t, 2) * Math.pow(1 - t, 3) * P2.y
+10 * Math.pow(t, 3) * Math.pow(1 - t, 2) * P3.y
+ 5 * Math.pow(t, 4) * (1 - t) * P4.y + Math.pow(t, 5) * P5.y;
| With degree n=5 - click and move red point |
Bézier curves can be defined for any degree n, you try to write a function with degree n and send to me, I'll very happy! :P
Here my processed for degree n:
//loop
t = 0;
P0 = new Point(112, 216);
P1 = new Point(216, 149);
P2 = new Point(50, 51);
P3 = new Point(140, 35);
P4 = new Point(228, 51);
P5 = new Point(57, 149);
P6 = new Point(154, 216);
Pn = ...
var ax:Array = [P0.x, P1.x, P2.x, P3.x, P4.x, P5.x, P6.x, Pn.x ...];
var ay:Array = [P0.y, P1.y, P2.y, P3.y, P4.y, P5.y, P6.y, Pn.y ...];
function bezierCurvesN(n:Number, t:Number, k:Array):Number {
var b:Number = 0; //binomial
var p:Number = 0; //position
var e:Number = 0; //exponent
var f:Number = 0; //floor
var c:Number = 0; //curves
var z:Number = n - 1; //floor 0-5 = 6
for (var i:int = 0, j:int = 1; i <= (z - 1); i++, j++ ) {
//b = new Binomial().coef(z, i); // 1 5 10 10 5 1
b = Pascal(z,i); // 1 5 10 10 5 1
p = k[i]; // P0 P1 P2 P3 P4
e = z - i; // 5 4 3 2 1
f = b * Math.pow(t, i) * Math.pow(1 - t, e) * p; // see wiki
c = c + f;
}
c = c + Math.pow(t, n) * k[n - 1]; // k[n =5] => k[n-1 =4] that of the end list
return c;
}
public function Pascal(n:Number, r:Number):Number{
if (n > 1 && r > 0 && r < n){
return Pascal(n - 1, r - 1) + Pascal(n - 1, r)
}
return 1;
}
| With degree n - click and move red point |
Download class demo
https://drive.google.com/open?id=0B8jxLPprSFg1VlFwbklhaFFuUTQClass reference
http://code.google.com/p/ruochi/source/browse/trunk/Singularity/Numeric/Binomial.asReference
http://ru.wikipedia.org/wiki/Числовой_рядhttp://en.wikipedia.org/wiki/Binomial_coefficient
http://en.wikipedia.org/wiki/Pascal's_triangle
http://en.wikipedia.org/wiki/Series_(mathematics)
http://en.wikipedia.org/wiki/Triangular_number
http://www.paultondeur.com/2008/03/09/drawing-a-cubic-bezier-curve-using-actionscript-3/
http://andywoodruff.com/blog/continuous-curves-with-actionscript-3/
http://blog.organa.ca/?p=38
http://www.algorithmist.net/as3pc.html
http://blog.onebyonedesign.com/actionscript/animating-bezier-curves/
http://code.google.com/p/bezier/
http://kelsocartography.com/blog/?p=2081
http://www.plus1coins.com/2010/06/drawing-bezier-curves-in-flash/
http://www.farmcode.org/post/2009/07/06/Fast-2D-Bezier-Library-for-ActionScript-3.aspx
Useful mathematical formulas in ActionScript 3
We have listed 12 very simple,basic but useful function source in Flex in the previous article. The mathematical calculation will be used regularly in our Flash applications, we can easily find the open source libraries like 30+ useful as3 open source projects, but it’s superfluous when we only need calculate the distance between two points, or only want to get the circle area. Here is the list of 18 useful AS3 arithmetic & formulas. Have any proudly and recommendable? Leave your comments to share please.
1. Distance Between Two Points


2. Inching Formulas
3. Elastic Formulas
5. Rotation With Mouse Formulas
6. Waveform Formulas
7. Heartthrob Formulas
8. Circle Rotation Formulas
9. Get Circle Area
10. Get Circumference Ratio
11. Elliptic Rotation Formulas
12. Color operations
13. Hex to Decimal
14. Decimal to Hex
15. Pick Up Color
16. Color Bit Arithmetic
17. Percent of a Number

18. Number of a percent

For demo 17 - 18:
19. Number of factorial
21. Pascal's Triangle
1. Distance Between Two Points

dx = x2 – x1;
dy = y2 – y1;
dist = Math.sqrt(dx*dx + dy*dy);

2. Inching Formulas
sprite.x += (targetX – sprite.x) * easing;//easing: inching coefficient
sprite.y += (targetY – sprite.y) * easing;
3. Elastic Formulas
vx += (targetX – sprite.x) * spring; //spring: elastic coefficient4. Flexible Partial Shifts Formulas
vy += (targetY – sprite.y) * spring;
sprite.x += (vx *= friction); //friction: friction force
sprite.y += (vy *= friction);
var dx:Number = sprite.x – fixedX;
var dy:Number = sprite.y – fixedY;
var angle:Number = Math.atan2(dy, dx);
var targetX:Number = fixedX + Math.cos(angle) * springLength;
var targetY:Number = fixedX + Math.sin(angle) * springLength;
5. Rotation With Mouse Formulas
dx = mouseX – sprite.x;
dy = mouseY – sprite.y;
sprite.rotation = Math.atan2(dy, dx) * 180 / Math.PI;
6. Waveform Formulas
public function onEnterFrame1(event:Event):void {
ball.y=centerScale+Math.sin(angle)*range;
angle+=speed;
}
7. Heartthrob Formulas
public function onEnterFrame1(event:Event):void {
ball.scaleX=centerScale+Math.sin(angle)*range;
ball.scaleY=centerScale+Math.sin(angle)*range;
angle+=speed;
}
8. Circle Rotation Formulas
public function onEnterFrame(event:Event):void {
ball.x=centerX+Math.cos(angle)*radius;
ball.y=centerY+Math.sin(angle)*radius;
angle+=speed;
}
9. Get Circle Area
public function getArea():Number
{
// The formula is Pi times the radius squared.
return Math.PI * Math.pow((width / 2), 2);
}
10. Get Circumference Ratio
public function getCircumference():Number
{
// The formula is Pi times the diameter.
return Math.PI * width;
}
11. Elliptic Rotation Formulas
public function onEnterFrame(event:Event):void {
ball.x=centerX+Math.cos(angle)*radiusX;
ball.y=centerY+Math.sin(angle)*radiusY;
angle+=speed;
}
12. Color operations
var t:uint=0×77ff8877
var s:uint=0xff000000
var h:uint=t&s
var m:uint=h>>>24
trace(m);
13. Hex to Decimal
trace(hexValue);
14. Decimal to Hex
decimalValue.toString(16);
15. Pick Up Color
red = color24 >> 16;
green = color24 >> 8 & 0xFF;
blue = color24 & 0xFF;
alpha = color32 >> 24;
red = color32 >> 16 & 0xFF;
green = color32 >> 8 & 0xFF;
blue = color232 & 0xFF;
16. Color Bit Arithmetic
color24 = red << 16 | green << 8 | blue;
color32 = alpha << 24 | red << 16 | green << 8 | blue;
17. Percent of a Number
/**
* Comparing the present with a series of numbers, provided the per cent over the range of those
* @param start
* @param end
* @param current
* @return percent of the number 0 - 100 if the start
*/
public static function coPercent(c:Number, s:Number = 0, e:Number = 100):Number {
return (((e - s) - (e - c))/(e - s)) * 100;
}
//50 -> 400 ~ 100%
//50 -> 200 ~ ? %
// cal: 42.8%
//percent = NumberUtilities.coPercent(200, 50, 400);
//trace(percent); // 42.857142857142854

18. Number of a percent
/**
* Percentage change from the current number
* @param percent
* @param start
* @param end
* @return
*/
public static function dePercent(p:Number, s:Number = 0, e:Number = 100):Number {
return (e - ((e - s) - ((p/100) * (e - s))));
}
//100% ~ 50 - 400
//42.8%~ 50 - ?
// cal: 200
//number = NumberUtilities.dePercent(42.8, 50, 400);
//trace(number); // ~200

For demo 17 - 18:
19. Number of factorial
/**20. Number of factorial
* The term n! (pronounced n factorial) means multiply together all the whole numbers from 1 to n
* @param n, remember 0! = 1
* @return n!
*/
public function factorial(n:Number):Number{
var k:Number=1;
for (var i:int = 1; i <= n; i++) k = k * i;
return k;
}
//5! = 1 x 2 x 3 x 4 x 5 = 120
/**
* The number of ways of selecting r objects from a total of n is written as
* @param n
* @param r
* @return
*/
public function combinatorics(n:Number, r:Number):Number {
return factorial(n) / (factorial(r) * factorial(n - r));
}
//5C0 = 1
//5C1 = 5
//5C2 = 10
//5C3 = 10
//5C4 = 5
//5C5 = 1
21. Pascal's Triangle
/**
* Pascal's Triangle
* @param n
* @param r
* @return
*/
public function pascal(n:Number, r:Number):Number{
if (n > 1 && r > 0 && r < n) {
var a:Number = pascal(n - 1, r - 1);
var b:Number = pascal(n - 1, r);
var c:Number = a + b;
return c;
}
return 1;
}
//(1 + x)3 = 3C0 + 3C1x + 3C2x2 + 3C3x3
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | |
|---|---|---|---|---|---|---|---|
| 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| 1 | 1 | 2 | 3 | 4 | 5 | 6 | |
| 2 | 1 | 3 | 6 | 10 | 15 | ||
| 3 | 1 | 4 | 10 | 20 | |||
| 4 | 1 | 5 | 15 | ||||
| 5 | 1 | 6 | |||||
| 6 | 1 |
Functions of Any Angle
Summary: The six trig functions were originally defined for acute angles in triangles, but now we define them for any angle (or any number). If you want any of the six function values for an angle that’s not between 0 and 90° (π/2), you just find the function value for the reference angle that is within that interval, and then possibly apply a minus sign.
Contents:
Suppose you draw the triangle in a circle this way, with angle A at the origin and the circle’s radius equal to the hypotenuse of the triangle. The hypotenuse ends at the point on the circle with coordinates (x,y), where x and y are the lengths of the two legs of the triangle. Then using the standard definitions of the trig functions, you have
sin A = opposite/hypotenuse = y/r
cos A = adjacent/hypotenuse = x/r
This is the key to extending the trig functions to any angle.
Not Just Triangles Any More
In the diagram, the general angle A is drawn in standard position, just as we did above for an acute angle. Just as before, its vertex is at the origin and its initial side lies along the positive x axis. The point where the terminal side of the angle cuts the circle is labeled (x,y).
(This particular angle happens to be between 90° and 180° (π/2 and π), and we say it lies in Quadrant II. But you could draw a similar diagram for any angle, even a negative angle or one >360°.)
Now let’s define sine and cosine of angle A, in terms of the coordinates (x,y) and the radius r of the circle:
(21) sin A = y/r, cos A = x/r
This is nothing new. As you saw above when A was in Quadrant I, this is exactly the definition you already know from equation 1: sin A = opposite/hypotenuse, cos A = adjacent/hypotenuse. We’re just extending it to work for any angle.
The other function definitions don’t change at all. From equation 3 we still have
tan A = sin A / cos A
which means that
tan A = y/x
and the other three functions are still defined as reciprocals (equation 5).
Once again, there’s nothing new here: we’ve just extended the original definitions to a larger domain.
Why Bother?
So why go through this? Well, for openers, not every triangle is an acute triangle. Some have an angle greater than 90°. Even in down-to-earth physical triangles, you’ll have to be concerned with functions of angles greater than 90°.
Beyond that, it turns out that all kinds of physical processes vary in terms of sines and cosines as functions of time: height of the tide; length of the day over the course of a year; vibrations of a spring, or of atoms, or of electrons in atoms; voltage and current in an AC circuit; pressure of sound waves, Nearly every periodic process can be described in terms of sines and cosines.
And that leads to a subtle shift of emphasis. You started out thinking of trig functions of angles, but really the domain of trig functions is all real numbers, just like most other functions. How can this be? Well, when you think of an “angle” of so-and-so many radians, actually that’s just a pure number. For instance, 30°=π/6. We customarily say “radians” just to distinguish from degrees, but really π/6 is a pure number. When you take sin(π/6), you’re actually evaluating the function sin(x) at x = π/6 (about 0.52), even though traditionally you’re taught to think of π/6 as an angle.
We won’t get too far into that in these pages, but here’s an example. If the average water depth is 8 ft in a certain harbor, and the tide varies by ±3 ft, then the height at time t is given by a function that resembles y = 8 + 3 cos(0.52t). (It’s actually more complicated, because high tides don’t come at the same time every day, but that’s the idea.)
Reference Angles
Coming back from philosophy to the nitty-gritty of computation, how do we find the value of a function when the angle (or number) is outside the range [0;90°] (which is 0 to π/2)? The key is to define a reference angle.
What good does the reference angle do you? Simply this: the six function values for any angle equal the function values for its reference angle, give or take a minus sign.
That’s an incredibly powerful statement, if you think about it. In the drawing, A is about 150° and the reference angle is therefore about 30°. Let’s say they’re exactly 150° and 30°, just for discussion. Then sine, cosine, tangent, cotangent, secant, and cosecant of 150° are equal to those same functions of 30°, give or take a minus sign.
What’s this “give or take” business? That’s what the next section is about.
Signs of Function Values
Remember the extended definitions from equation 21:
sin A = y/r, cos A = x/r
The radius r is always taken as positive, and therefore the signs of sine and cosine are the same as the signs of y and x. But you know which quadrants have positive or negative y and x, so you know for which angles (or numbers) the sine and cosine are positive or negative. And since the other functions are defined in terms of the sine and cosine, you also know where they are positive or negative.
Spend a few minutes thinking about it, and draw some sketches. For instance, is cos 300° positive or negative? Answer: 300° is in Q IV, which is in the right-hand half of the circle. Therefore x is positive, and the cosine must be positive as well. The reference angle is 60° (draw it!), so cos 300° equals cos 60° and not −cos 60°.
You can check your thinking against the chart that follows. Whatever you do, don’t memorize the chart! Its purpose is to show you how to reason out the signs of the function values whenever you need them, not to make you waste storage space in your brain.
| Signs of Function Values | ||||
|---|---|---|---|---|
| Q I 0 to 90° 0 to π/2 | Q II 90 to 180° π/2 to π | Q III 180 to 270° π to 3π/2 | Q IV 270 to 360° 3π/2 to 2π | |
| x | positive | negative | negative | positive |
| y | positive | positive | negative | negative |
| sin A (= y/r) | positive | positive | negative | negative |
| cos A (= x/r) | positive | negative | negative | positive |
| tan A (= y/x) | positive | negative | positive | negative |
You can analyze negative angles the same way. Take −45°. That occupies the same place on the circle as +315° (360°−45°). −45° is in Q IV.
Examples: Function Values
As you’ve seen, for any function you get the numeric value by considering the reference angle and the positive or negative sign by looking where the angle is.
Example: What’s cos 240°? Solution: Draw the angle and see that the reference angle is 60°; remember that the reference angle always goes to the x axis, even if the y axis is closer. cos 60° = ½, and therefore cos 240° will be ½, give or take a minus sign. The angle is in Q III, where x is negative, and therefore cos 240° is negative. Answer: cos 240° = −½.
Example: What’s tan(−225°)? Solution: Draw the angle and find the reference angle of 45°. tan 45° = 1. But −225° is in Q II, where x is negative and y is positive; therefore y/x is negative. Answer: tan(−225°) = −1.
Identities for Related Angles
The techniques we worked out above can be generalized into a set of identities. For instance, if two angles are supplements then you can write one as A and the other as 180°−A. You know that one will be in Q I and the other in Q II, and you also know that one will be the reference angle of the other. Therefore you know at once that the sines of the two angles will be equal, and the cosines of the two will be numerically equal but have opposite signs.
This diagram may help:
Here you see a unit circle (r = 1) with four identical triangles. Their angles A are at the origin, arranged so that they’re mirror images of each other, and their hypotenuses form radii of the unit circle. Look at the triangle in Quadrant I. Since its hypotenuse is 1, its other two sides are cos A and sin A.
The other three triangles are the same size as the first so their sides must be the same length as the sides of the first triangle. But you can also look at the other three radii as belonging to angles 180°−A in Quadrant II, 180°+A in Quadrant III, and −A or 360°−A in Quadrant IV. All the others have a reference angle equal to A. From the symmetry, you can immediately see things like sin(180°+A) = −sin A and cos(−A) = cos A.
The relations are summarized below. Don’t memorize them! Just draw a diagram whenever you need them — it’s easiest if you use a hypotenuse of 1. Soon you’ll find that you can quickly visualize the triangles in your mind and you won’t even need to draw a diagram. The identities for tangent are easy to derive: just divide sine by cosine as usual.
| sin(180°−A) = sin A sin(π−A) = sin A | cos(180°−A) = −cos A cos(π−A) = −cos A | tan(180°−A) = −tan A tan(π−A) = −tan A | (22) |
| sin(180°+A) = −sin A sin(π+A) = −sin A | cos(180°+A) = −cos A cos(π+A) = −cos A | tan(180°+A) = tan A tan(π+A) = tan A | |
| sin(−A) = −sin A | cos(−A) = cos A | tan(−A) = −tan A |
Periodic Functions
You should be able to see that 360° brings you all the way around the circle. That means that an angle of 360°+A or 2π+A is the same as angle A. Therefore the function values are unchanged when you add 360° or a multiple of 360° (or 2π or a multiple) to the angle. Also, if you move in the opposite direction for angle A, that’s the same angle as 360°−A or 2π−A, so the function values of −A and 360°−A (or 2π−A) are the same.
For this reason we say that sine and cosine are periodic functions with a period of 360° or 2π. Their values repeat over and over again. Of course secant and cosecant, being reciprocals of cosine and sine, must have the same period.
What about tangent and cotangent? They are periodic too, but their period is 180° or π: they repeat twice as fast as the others. You can see this from equation 22: tan(180°+A) = tan A says that the function values repeat every 180°.
Rotated Oval Tutorial
Making the transition from drawing circles to drawing ovals is pretty simple but when you need to go from drawing ovals to drawing rotated ovals, you might run into a few problems. This article documents some of the pitfalls I encountered and presents them as a learning experience. If you just want some solid code to draw rotated ovals or twisted ellipses, skip ahead to the end of the article and copy the last block of code. If you think you might gain from my experience then by all means… read on.
In the simplest of terms, the goal is to plot the points of the rotated oval just like you would plot the points of a normal oval, but you also want to add a “twist” to each point so the whole oval ends up being rotated. “No duh!” right? If you want to rotate the whole oval, you have to rotate each and every point in the oval. Thanks for the tip Captain Obvious, Commander of the S.S. A’Durrrrrrr.
While the concept of rotating each point may be a no-brainer, simply adding “twist” won’t do the trick.
Here’s the standard oval drawing code (for comparison purposes):
//
//
function drawOval(centerX, centerY, xRadius, yRadius, sides){
this.moveTo(centerX + xRadius, centerY);
for(var i=0; i<=sides; i++){
var pointRatio = i/sides;
var radians = pointRatio * 2 * Math.PI;
var xSteps = Math.cos(radians);
var ySteps = Math.sin(radians);
var pointX = centerX + xSteps * xRadius;
var pointY = centerY + ySteps * yRadius;
this.lineTo(pointX, pointY);
}
}
//
lineStyle(0);
//
// X, Y, W, H, steps.
drawOval(250, 200, 200, 150, 100);
//
//
function drawOval(centerX, centerY, xRadius, yRadius, sides){
this.moveTo(centerX + xRadius, centerY);
for(var i=0; i<=sides; i++){
var pointRatio = i/sides;
var radians = pointRatio * 2 * Math.PI;
var xSteps = Math.cos(radians);
var ySteps = Math.sin(radians);
var pointX = centerX + xSteps * xRadius;
var pointY = centerY + ySteps * yRadius;
this.lineTo(pointX, pointY);
}
}
//
lineStyle(0);
//
// X, Y, W, H, steps.
drawOval(250, 200, 200, 150, 100);
//
//
// Add "twist" argument.
function drawOval(centerX, centerY, xRadius, yRadius, twist, sides){
//
// Convert "twist" to radians.
var twistRadians = twist * 2*Math.PI;
this.moveTo(centerX + xRadius, centerY);
for(var i=0; i<=sides; i++){
var pointRatio = i/sides;
var radians = pointRatio * 2 * Math.PI;
//
// Add "twist" to "radians" .
radians += twistRadians;
var xSteps = Math.cos(radians);
var ySteps = Math.sin(radians);
var pointX = centerX + xSteps * xRadius;
var pointY = centerY + ySteps * yRadius;
//
this.lineTo(pointX, pointY);
}
}
//
lineStyle(0);
//
// X, Y, W, H, twist, steps.
drawOval(250, 200, 200, 150, 45/360, 100);
//
// Add "twist" argument.
function drawOval(centerX, centerY, xRadius, yRadius, twist, sides){
//
// Convert "twist" to radians.
var twistRadians = twist * 2*Math.PI;
this.moveTo(centerX + xRadius, centerY);
for(var i=0; i<=sides; i++){
var pointRatio = i/sides;
var radians = pointRatio * 2 * Math.PI;
//
// Add "twist" to "radians" .
radians += twistRadians;
var xSteps = Math.cos(radians);
var ySteps = Math.sin(radians);
var pointX = centerX + xSteps * xRadius;
var pointY = centerY + ySteps * yRadius;
//
this.lineTo(pointX, pointY);
}
}
//
lineStyle(0);
//
// X, Y, W, H, twist, steps.
drawOval(250, 200, 200, 150, 45/360, 100);
//
FAIL!
All that did was find a point on the circle, spin said point around the circle (by adding twist), and THEN scale the X and Y axis to make it an oval. Twisting or spinning the points on a circle before they are scaled is useless, you must scale first and then twist.
*NOTE: The straight line is caused by the “moveTo” command sending the pen to the standard oval’s starting point (3 O’clock) and then jumping to the (supposedly) “rotated” oval’s new starting point 45 degrees around.
It might be clearer now that one possible solution is to:
- Plot the point as if you were drawing a standard non-rotated oval being sure to scale X and Y (by multiplying times the xRadius and yRadius).
- After the point has been scaled, find its new distance from center.
- Find the point’s new angle from center.
- Add “twist” to the new angle.
- Use distance and rotation values to plot the point at its new “spun” location.
//
function drawOval(centerX, centerY, xRadius, yRadius, spin, steps){
var ratio, scaledAngle, ratioRadians, scaledRadius, angl, i;
var spinRadians = spin * 2 * Math.PI;
var xx = centerX + Math.cos(spinRadians) * xRadius;
var yy = centerY + Math.sin(spinRadians) * xRadius;
moveTo(xx, yy);
for(i=1; i<=steps; i++){
ratio = i/steps;
ratioRadians = ratio * 2 * Math.PI;
//
// Scale the points like you would with a standard oval.
xx = Math.cos(ratioRadians) * xRadius;
yy = Math.sin(ratioRadians) * yRadius;
//
// Find the scaled point's new distance from center.
scaledRadius = Math.sqrt(xx*xx + yy*yy);
//
// Find the scaled point's new angle from center.
scaledAngle = Math.atan2(yy, xx);
//
// Spin the point.
scaledAngle += spinRadians;
//
// Plot the point with its new scaled and rotated values.
xx = centerX + Math.cos(scaledAngle) * scaledRadius;
yy = centerY + Math.sin(scaledAngle) * scaledRadius;
lineTo(xx, yy);
}
}
//
lineStyle(0);
drawOval(250, 200, 200, 100, 45/360, 100);
//
function drawOval(centerX, centerY, xRadius, yRadius, spin, steps){
var ratio, scaledAngle, ratioRadians, scaledRadius, angl, i;
var spinRadians = spin * 2 * Math.PI;
var xx = centerX + Math.cos(spinRadians) * xRadius;
var yy = centerY + Math.sin(spinRadians) * xRadius;
moveTo(xx, yy);
for(i=1; i<=steps; i++){
ratio = i/steps;
ratioRadians = ratio * 2 * Math.PI;
//
// Scale the points like you would with a standard oval.
xx = Math.cos(ratioRadians) * xRadius;
yy = Math.sin(ratioRadians) * yRadius;
//
// Find the scaled point's new distance from center.
scaledRadius = Math.sqrt(xx*xx + yy*yy);
//
// Find the scaled point's new angle from center.
scaledAngle = Math.atan2(yy, xx);
//
// Spin the point.
scaledAngle += spinRadians;
//
// Plot the point with its new scaled and rotated values.
xx = centerX + Math.cos(scaledAngle) * scaledRadius;
yy = centerY + Math.sin(scaledAngle) * scaledRadius;
lineTo(xx, yy);
}
}
//
lineStyle(0);
drawOval(250, 200, 200, 100, 45/360, 100);
//
SUCCESS!
That’s pretty sweet but there’s still room for improvement because “Math.atan2″ and “Math.sqrt” are redundant and use more resources than necessary. There’s a way to reduce the calculations above into a nice and compact formula but I must admit that the logic of the Math is a bit beyond me.
For an oval where…
- h = centerX;
- k = centerY;
- a = xRadius;
- b = yRadius;
- Φ = spin angle
- t = initial angle (point ratio)
Here’s what the above formula looks like after it’s been adapted to ActionScript:
//
function drawOval(centerX, centerY, radiusX, radiusY, spin, steps) {
var i, radian, radianSin, radianCos;
var spinRadians = spin * 2 * Math.PI;
var spinSin = Math.sin(spinRadians);
var spinCos = Math.cos(spinRadians);
var xx = centerX + spinCos * radiusX;
var yy = centerY + spinSin * radiusX;
moveTo(xx, yy);
for (i=1; i<=steps; i++) {
radian = i/steps * 2 * Math.PI;
radianSin = Math.sin(radian);
radianCos = Math.cos(radian);
//
// Apply the compact and efficient oval formula.
xx = centerX+(radiusX*radianCos*spinCos-radiusY*radianSin*spinSin);
yy = centerY+(radiusX*radianCos*spinSin+radiusY*radianSin*spinCos);
lineTo(xx, yy);
}
}
//
lineStyle(0);
drawOval(250, 200, 200, 100, 45/360, 100);
//
function drawOval(centerX, centerY, radiusX, radiusY, spin, steps) {
var i, radian, radianSin, radianCos;
var spinRadians = spin * 2 * Math.PI;
var spinSin = Math.sin(spinRadians);
var spinCos = Math.cos(spinRadians);
var xx = centerX + spinCos * radiusX;
var yy = centerY + spinSin * radiusX;
moveTo(xx, yy);
for (i=1; i<=steps; i++) {
radian = i/steps * 2 * Math.PI;
radianSin = Math.sin(radian);
radianCos = Math.cos(radian);
//
// Apply the compact and efficient oval formula.
xx = centerX+(radiusX*radianCos*spinCos-radiusY*radianSin*spinSin);
yy = centerY+(radiusX*radianCos*spinSin+radiusY*radianSin*spinCos);
lineTo(xx, yy);
}
}
//
lineStyle(0);
drawOval(250, 200, 200, 100, 45/360, 100);
//
Fish Curve
var xp:Number = 0;
var yp:Number = 0;
var t:Number = 0;
var a:Number = 200;
x = stage.stageWidth / 2;
y = stage.stageHeight / 2;
graphics.lineStyle(0,0x000000);
addEventListener(Event.ENTER_FRAME, onRun);
function onRun(evt:Event):void {
xp = a * Math.cos(t) - (a * Math.pow(Math.sin(t),2))/Math.sqrt(2);
yp = a * Math.cos(t) * Math.sin(t);
if (t == 0){
graphics.moveTo(xp, yp);
}else{
graphics.lineTo(xp, yp);
}
t += 0.05;
}
var yp:Number = 0;
var t:Number = 0;
var a:Number = 200;
x = stage.stageWidth / 2;
y = stage.stageHeight / 2;
graphics.lineStyle(0,0x000000);
addEventListener(Event.ENTER_FRAME, onRun);
function onRun(evt:Event):void {
xp = a * Math.cos(t) - (a * Math.pow(Math.sin(t),2))/Math.sqrt(2);
yp = a * Math.cos(t) * Math.sin(t);
if (t == 0){
graphics.moveTo(xp, yp);
}else{
graphics.lineTo(xp, yp);
}
t += 0.05;
}
The fish curve is a term coined in this work for the ellipse negative pedal curve with pedal point at the focus for the special case of the eccentricity
. For an ellipse with parametric equations
(1) | |||
(2) |
the corresponding fish curve has parametric equations
(3) | |||
(4) |
The Cartesian equation is
(5) |
which, when the origin is translated to the node, can be written
(6) |
(Lockwood 1957).
The area of a curve is given by
(7) | |||
(8) |
so the areas of the tail and head are given by
(9) | |||
(10) |
giving an overall area for the fish as
(11) |
(Lockwood 1957).
The arc length of the curve is given by
(12) | |||
(13) | |||
(14) |
(Lockwood 1957).
The curvature and tangential angle are given by
(15) | |||
(16) |
where
is the complex argument.
The Tschirnhausen cubic, illustrated above, also resembles a fish, as does the trefoil curve.
REFERENCES:
Lockwood, E. H. "Negative Pedal Curve of the Ellipse with Respect to a Focus." Math. Gaz. 41, 254-257, 1957.
Lockwood, E. H. A Book of Curves. Cambridge, England: Cambridge University Press, p. 157, 1967.
CITE THIS AS:
Weisstein, Eric W. "Fish Curve." From MathWorld--A Wolfram Web Resource. http://mathworld.wolfram.com/FishCurve.html
Subscribe to:
Posts (
Atom)