Calculate the area of a contour
by ericlin

Area of a curveTo block

Before we go to discuss the area of a contour, we need to discuss area of a curveTo block.

Give 3 points as start point S , control point C, end point E, the area of the curveTo block can be calculated by:

AreaOfCurveTo=((S.x*C.y-S.y*C.x)+(C.x*E.y-C.y*E.x)+(E.x*S.y-E.y-S.x))/3;

If we break it apart, the formula can be written as:

function vectorArea(A, B){
return (A.x*B.y+A.y*B.x)/2;
}
AreaOfCurveTo=(2/3)*(vectorArea(S,C)+vectorArea(C,E)+vectorArea(E, S));

The formula is nearly the same for calculate the polygon area defined by S, C and E but with a ratio of 2/3;

Area of a orthodoxical parabolic curve¡@

The curveTo in Flash is a quadratic bezier, It is a parabolic curve. I plan to solve the parabolic curve in orthodox coordinate first before we handle the Flash curveTo which is a parabolic curve in rotated coordinates.

The figure shows an orthodixical parabolic curve the path when an object get thrown. We are familiar with the formula:

Initial upward velocity: vy
initial forward velocity: vx;
gravity acceleration: g;
time passed:t;

Then we get the formula to calculate the position of an object:

x=vx*t;
y=vy*t+(1/2)*g*t^2;

I would like to tell the answer first : The area of the red color region when t=1 is  :

Area=g*vx/12;

The math process about parabolic curve

To calculate the area down to X axis when t goes from 0 to 1, we need an equation as y=fun(x); We replace t by (x/vx);

y=vy*(x/vx)+(1/2)*g*(x/vx)^2;
y=vy*x/vx+(1/2)*g*(1/vx)^2*x^2;

The Zigma will be:

Zigma(x)=(1/2)*(vy/vx)*x^2+(1/3)*(1/2)*g*(1/vx)^2* x^3;

This equation is horrible. But what we want is the Zigma when t=1; That is x=vx;

Zigma(vx)=(1/2)*vy*vx+(1/6)*g*vx;;

This is the area limited by X axis. We want the area of red region, so we need to subtract the area of triangle.

areaOfTriangle=(x*y)/2=vx*(vy+(1/2)*g)/2;
Area=Zigma(vx)-areaOfTriangle;
Area=(1/2)*vy*vx+(1/6)*g*vx-(1/2)*(vx*vy+(vx*g)/2);
Area=(1/6)*g*vx-(1/4)*g*vx;

Area=g*vx/12;

Wow, the equation is so simple. What surprised me is that, the area does not depend on vy !

Math about the area of CurveTo

A curve can be defined by 3 control points: the start point, the control point and the end point. The curve is drawn by moveTo(start.x,start.y);curveTo(control.x, control.y, end.x, end.y);

From the formula : Area=g*vx/12 , we need to find out the gravity-acceleration and the vx - the initial forward vector that points vertical to gravity.

First, the start vector and end vector are the vecotr connecting start point and end point to the control point.

startVector={x:(control.x-start.x)*2, y:(control.y-start.y)*2};
endVector={x:(end.x-control.x)*2, y:(end.y-control.y)*2};

The accelerator is the difference between them.

g={x:endVector.x-startVector.x, y:endVector.y-startVector.y};

If we rotate g 90 degree clockwise to make g point along X direction, then

gx={x:g.y, y=-g.x};
gx={x:endVector.y-startVector.y, y:-(endVector.x-startVector.x)};

Lets try to calculate the vx - the project of startVector along gx vector.

According to the dot product, we get the projection vx as:

vx=dotProduct(gx,startVector)/(length of gx);

Remember the formula : Area=g*vx/12; and since g amplitude is the same as length of gx; we get

Area=dotProduct(gx, startVector)/12;
dotProduct=(endVector.y-startVector.y)*startVector.x-(endVector.x-startVector.x)*startVector.y;

Lets short the variable name

dotProduct=(Ey-Sy)*Sx-(Ex-Sx)*Sy;
dotProduct=Ey*Sx-Sy*Sx-Ex*Sy+Sx*Sy;
dotProduct=Ey*Sx-Ex*Sy;

The conclusion:

Area=(endVector.y*startVector.x-endVector.x*startVector.y)/12;

Lets replace endVector and startVector with startPoint, controlPoint and endPoint coordinates and get this:

Area=((start.x*control.y-start.y*control.x)+(control.x*end.y-control.y-end.x)+(end.x*start.y-end.y-start.x))/3;

This formula is easy. We just pick two neighbor points clockwisely to calculate the result.

Conclusion: The area of curveTo region is (2/3) of the area of the polygon defined by those 3 points.

The area of a contour

A contour is composed of sequential halfEdges. Each edge contains the start point, control point and end point. First we omit the control point and calculate the area of the polygon defined by serial start point and end point. Finally, we add the result with the sum of serial curtTo block area.

Please note that, when the contour is clockwisely defined, the calculated area for outward curve will be positive. While the inward curveTo will has a negative area value. So, we need not worry about the inward or outward curve.

To calculate the area of polygon:  http://ericlin2.tripod.com/polygon/polygon.html

Lets begin the calculation.

To calculate the first curveTo edge  start S, control C, end E, we need add the polygon area and the curveTo area.

function vectorArea(A, B){
return (A.x*B.y+A.y*B.x)/2;
}
AreaOfCurveTo=(2/3)*(vectorArea(S,C)+vectorArea(C,E)+vectorArea(E, S));
AreaOfPolygonEdge=vectorArea(S, E);

result=AreaOfCurveTo+AreaOfPolygonEdge;

result=(1/3)(2*vectorArea(S,C)+2*vectorArea(C, E)-vectorArea(E,S));

So, we can loop the edges and finish the calculation