\ Original Date: November 4, 1985 \ Last Modified: January 2, 1989 \ Author: Jack W. Brown \ ANS/4tH port: October 14, 1997 \ Ported by: Hans L. Bezemer \ File name: L4P16.SEQ \ Function: Computes Area of a Polygon given the x,y \ coordinates of its verticies \ The following mathematical algorithm is often used to \ determine the area of cross-section provided it can be \ represented adequately by a finite number of straight line \ segments (this is almost always possible). The technique \ can also be applied to cross-sections with holes by moving \ around the hole in a counter clockwise direction and traversing \ to and from the hole along the same path. \ The general algorithm. \ p1 /---------\ p2 p1 = ( x1,y1 ) \ / \ p2 = ( x2,y2 ) \ / \ p3 p3 = ( x3,y3 ) \ / / p4 = ( x4,y4 ) \ p5 /--------------/ p4 p5 = ( x5,y5 ) \ AREA OF THE POLYGON = \ [(x1y5-x5y1)+(x2y1-x1y2)+(x3y2-x2y3)+(x4y3-x3y4)+(x5y4-x4y5)]/2 \ In general: \ i=n \ AREA = 0.5*SUM [ x(i)y(i-1) - x(i-1)y(i) ] \ i=1 \ where we define x0 to be x5 and y0 to be y5. \ Example without a hole. \ X Not drawn to scale!! \ | p1 = ( 8,4 ) \ | p2 = ( 6,1 ) \ | p4 ----------- p1 p3 = ( 2,1 ) \ | / / p4 = ( 5,4 ) \ | / / \ | / / \ | p3 ----------- p2 \ |-----------------------Y \ A = [(8*4-5*4)+(6*4-8*1)+(2*1-6*1)+(5*1-2*4)]/2 = 10.5 \ Example of a polygon with a hole removed \ Sorry but the diagram below is not to scale. units= centimeters \ Y \ p9 ---|-------------------------------- p1 p1 = (6,5) \ \ | p5 p4 / p2 = (2,0) = p8 \ \ | +----------+ / p3 = (3,3) = p7 \ \| |cut out | / p4 = (3,4) \ \ +----------+ / p5 = (1,4) \ |\ p6 p7,p2 / p6 = (1,3) \ | \ / p7 = (3,3) \ | \ / p8 = (2,0) \ | \ / p9 = (-1,5) \ | \ / \ | \ / \ | \/ p8,p2 \ ---+-------------------------- X \ Traverse outside clockwise and the cut out counter clockwise. \ A = [(6*5-(-1)*5)+(2*5-6*0)+(3*0-2*3)+(3*3-3*4)+(1*4-3*4) \ +(1*4-1*3)+(3*3-1*3)+(2*3-3*0)+(-1*0-2*5)]/2 \ A = 15.5 sq cm \ This should be replaced by the bullet proof version in the \ file JBINPUT.SEQ [NEEDS lib/enter.4th] 51 ARRAY X \ Array for x coordinates 51 ARRAY Y \ Array for y coordinates VARIABLE #POINTS \ Number of points in polygon VARIABLE AREA \ Sum of the x(i)y(i-1) - x(i-1)y(i) \ Fetch ith x component. : X@ ( i x{i} ) CELLS X + @ ; \ Fetch ith y component. : Y@ ( i y{i} ) CELLS Y + @ ; \ Store ith x component. : X! ( x i -- ) CELLS X + ! ; \ Store ith y component. : Y! ( y i -- ) CELLS Y + ! ; \ Move to the next tab stop. : TAB ( -- ) 9 emit ; \ Get number from keyboard. : GET# ENTER ; \ Prompt and fetch number of data points. : GET_#POINTS ( -- ) BEGIN CR ." Enter number of data points. " GET# DUP 3 < WHILE CR ." You need at least 3 data points!" REPEAT 50 MIN #POINTS ! ; \ Prompt and fetch all data points. : GET_DATA ( -- ) CR CR ." Point " CR #POINTS @ 1+ 1 DO CR I 3 .R TAB ." X = " GET# I X! TAB ." Y = " GET# I Y! LOOP #POINTS @ DUP X@ 0 X! Y@ 0 Y! ; \ Store last point in 0th slot \ Sum data points. : FIND_AREA ( -- ) 0 AREA ! #POINTS @ 1+ 1 ( n+1 so we loop n times ) DO I X@ I 1- Y@ * ( X{i}*Y{i-1} ) I 1- X@ I Y@ * ( X{i-1}*Y{i} ) - AREA +! LOOP ; \ Display computed area. : PUT_AREA ( -- ) AREA @ 2 /MOD CR ." AREA = " 6 .R [CHAR] . EMIT IF [CHAR] 5 EMIT ELSE [CHAR] 0 EMIT THEN SPACE ; \ Compute area of polygon. : POLY ( -- ) GET_#POINTS GET_DATA FIND_AREA PUT_AREA ; POLY