Does anyone have a skill routine which will calculate the area of
odd shaped polygons? In particular, manhattan polygons, S-shaped,
and hollow areas are needed.
In addition, it would be nice to have a routine to calculate the
number of squares in an S-shaped geometry. It can be assumed the width
of the path will not fluctuate in an S-shaped geometry.
For those who may or may not know:
Area will of course translate into capacitance.
Squares (area/width) will translate into a resistance.
I was thinking of a fairly simple algorithm until I found an example of a
shape like:
_______________________
| |
| |
| |
| ___________ |
| |_________ |____|
| |
| |
| |
| |
|______________|
Thanks,
Joe Amato
j...@philabs.philips.com | Some go up, Some go down. | First things First --
| Some go thirsty, | but not necessarily
| Some just drown. | in that order.
My Idea != Company Idea | -Marillion | -"Dr. Who"
--
j...@philabs.philips.com | Some go up, Some go down. | First things First --
| Some go thirsty, | but not necessarily
| Some just drown. | in that order.
My Idea != Company Idea | -Marillion | -"Dr. Who"
-W
/*
Function Name : area
Title : Calculate the area of selected shapes.
Author : Terry Maness [Cadence, San Jose, CA]
Date : 11/18/93
Revision : 1.0
SW Release : 4.x
Prerequisites : None
Synopsis : area() => nil
Users guide : None
Modification history :
(name) (date) (changes)
Description : Preselect your shapes and issue the area command.
*/
procedure(area()
prog((REP lselset scount areat areac news1 news p1x p1y p2x p2y width height
polycoords lpcoords)
if(selectedSet() then
REP=getEditRep()
lselset=length(selectedSet())
scount=0
areat=0.0
foreach(shape selectedSet()
scount++
news=nil
areac=0.0
news1=layerTile(REP shape~>layerName list(shape))
foreach(ns1 news1
dbMoveFig(ns1 nil list(0:0 "90"))
news2=layerTile(REP shape~>layerName list(ns1))
foreach(ns2 news2
dbMoveFig(ns2 nil list(0:0 "270"))
);end foreach
news=append(news2 news)
dbDeleteObject(ns1)
);end foreach
foreach(nshape news
case(nshape~>shape
("rectangle"
p1x=xCoord(lowerLeft(nshape~>bBox))
p1y=yCoord(lowerLeft(nshape~>bBox))
p2x=xCoord(upperRight(nshape~>bBox))
p2y=yCoord(upperRight(nshape~>bBox))
if(p1x<p2x then
width=p2x-p1x
else
width=p1x-p2x
);end if
if(p1y<p2y then
height=p2y-p1y
else
height=p1y-p2y
);end if
areac=areac+{width*height}
)
("polygon"
polycoords=nshape~>path
lpcoords=length(polycoords)
if(lpcoords==3 then
p1x=xCoord(nthelem(1 polycoords))
p1y=yCoord(nthelem(1 polycoords))
p2x=xCoord(nthelem(2 polycoords))
p2y=yCoord(nthelem(2 polycoords))
p3x=xCoord(nthelem(3 polycoords))
p3y=yCoord(nthelem(3 polycoords))
; check p1 against p2
if(p1x==p2x then
; vert seg between p1 and p2
if(p1y<p2y then
height=p2y-p1y
else
height=p1y-p2y
);end if
else
if(p1y==p2y then
; horz seg between p1 and p2
if(p1x<p2x then
width=p2x-p1x
else
width=p1x-p2x
);end if
);end if
);end if
; check p1 against p3
if(p1x==p3x then
; vert seg between p1 and p3
if(p1y<p3y then
height=p3y-p1y
else
height=p1y-p3y
);end if
else
if(p1y==p3y then
; horz seg between p1 and p3
if(p1x<p3x then
width=p3x-p1x
else
width=p1x-p3x
);end if
);end if
);end if
; check p3 against p2
if(p3x==p2x then
; vert seg between p3 and p2
if(p3y<p2y then
height=p2y-p3y
else
height=p3y-p2y
);end if
else
if(p3y==p2y then
; horz seg between p3 and p2
if(p3x<p2x then
width=p2x-p3x
else
width=p3x-p2x
);end if
);end if
);end if
areac=areac+{{width*height}*.5}
else
printf("unexpected shape, please call cad support.\n")
);end if
)
(t printf("unexpected shape, please call cad support.\n"))
(nil printf("nil shape, please call cad support.\n"))
);end case
dbDeleteObject(nshape)
);end foreach
printf("area of shape %d = ", scount) println(areac)
areat=areat+areac
);end foreach
if(lselset > 1 then
printf("total area = ") println(areat)
);end if
);end if
));end procedure and prog
/*
Cadence polygon~>path is coded thusly:
((x1 y1) (x2 y2) ... (xn yn))
Use trapizodial rule
| ____ |
| \ (xi + xi+1) * (yi - yi+1) |
| / ------------------------- |
| ---- 2 |
i:1...n
(use 1 for n+1)
Construct lists and apply trapizodial rule:
(x2 ...... xn x1) (y2 ...... yn y1) /
+ \/ - / 2
(x1 x2 ... xn-1 xn) /\ (y1 y2 ... yn-1 yn) /
*/
;; usage: polyarea(obj~>path)
;;
(procedure polyarea(s)
(let ((X (mapcar 'car s)) (Y (apply 'nconc (mapcar 'cdr s))))
(abs
(quotient
(apply 'plus
(mapcar 'times
(mapcar 'plus X (append (cdr X) (ncons (car X))))
(mapcar 'difference Y (append (cdr Y) (ncons (car Y))))
)
)
2
)
)
)
)
;; john