home *** CD-ROM | disk | FTP | other *** search
- /*
- Routine to measure area of selected objects. (Based on the routine to export Ishapes for ImageMaster).
- Written by Don Cox, Apr '94. Copyright. Not Public Domain.
- */
- /* $VER: MeasureArea April 94 */
-
-
- msg = PDSetup.rexx(2,0) /* load gdarexxsupport.library */
- units = getclip(pds_units)
- if msg ~= 1 then exit_msg(msg)
- call pdm_SetWireFrame(1)
- if units = 3 then call pdm_SetUnits(2) /* work in cm */
-
- numeric digits 7
-
- cr = '0a'x
-
- call pdm_ShowStatus(" Analysing objects...")
- success = open("Output","ram:tempfile","W")
- if success = 0 then exit_msg("Temporary file could not be opened")
-
-
- string = ""
-
- /* First go through getting rough size, for setting point intervals for curve conversion */
- object = pdm_SelFirstObj()
- objectnumber = 1
- totalpoints = 0
-
- if object = 0 then exit_msg("No objects selected")
- do until object = 0
- if pdm_IsEllipse(object) = 1 then call pdm_EllipseToGraphic(object)
- if pdm_IsText(object) = 1 then do
- textobject = pdm_SelectObj(object)
- call pdm_TextToGraphic()
- end
- if pdm_IsBezier(object)=1 then do
- numpoints = pdm_GetObjOrder(object)
- totalpoints = totalpoints+numpoints
- VisSize = pdm_GetObjVisSize(object)
- VisPos = pdm_GetObjVisPosn(object)
- parse var VisSize VisWidth VisHeight
- parse var VisPos Xcoord Ycoord
- if objectnumber = 1 then do
- smallestY = Ycoord /* pick up first Y value in file */
- smallestX = Xcoord
- biggestX = Xcoord
- biggestY = Ycoord
- end
- if Ycoord>biggestY then biggestY = Ycoord
- if Ycoord<smallestY then smallestY = Ycoord
- if Xcoord>biggestX then biggestX = Xcoord
- if Xcoord<smallestX then smallestX = Xcoord
-
- Ycoord = Ycoord+VisHeight /* Look at bottom right corner */
- Xcoord = Xcoord+VisWidth
- if Ycoord>biggestY then biggestY = Ycoord
- if Ycoord<smallestY then smallestY = Ycoord
- if Xcoord>biggestX then biggestX = Xcoord
- if Xcoord<smallestX then smallestX = Xcoord
-
- end
-
-
- /* Grid routines cannot be used yet due to bug in PDraw IsGrid command
- if pdm_IsGrid(object)=1 then do
- numpoints = 4
- totalpoints = totalpoints+numpoints
- VisSize = pdm_GetObjVisSize(object)
- VisPos = pdm_GetObjVisPosn(object)
- parse var VisSize VisWidth VisHeight
- parse var VisPos Xcoord Ycoord
- if objectnumber = 1 then do
- smallestY = Ycoord /* pick up first Y value in file */
- smallestX = Xcoord
- biggestX = Xcoord
- biggestY = Ycoord
- end
- if Ycoord>biggestY then biggestY = Ycoord
- if Ycoord<smallestY then smallestY = Ycoord
- if Xcoord>biggestX then biggestX = Xcoord
- if Xcoord<smallestX then smallestX = Xcoord
-
- Ycoord = Ycoord+VisHeight /* Look at bottom right corner */
- Xcoord = Xcoord+VisWidth
- if Ycoord>biggestY then biggestY = Ycoord
- if Ycoord<smallestY then smallestY = Ycoord
- if Xcoord>biggestX then biggestX = Xcoord
- if Xcoord<smallestX then smallestX = Xcoord
- end /* of grid */
-
- */
-
- object = pdm_SelNextObj(object)
- objectnumber = objectnumber+1
- end
-
- if objectnumber = 1 then exit_msg("No objects selected")
-
-
- /* This is what we really want but the sqrt function in the gdarexxsupport.library doesn't work.
- totalpoints = trunc(sqrt(totalpoints)*20) */
-
- totalpoints = totalpoints*2 /* will have to do instead */
- if totalpoints>300 then totalpoints=300 /* arbitrary limits */
- if totalpoints<40 then totalpoints=40
-
- resolution = pdm_GetForm("Set curve point resolution", 10,"Resolution number :"totalpoints)
- if ~datatype(resolution,n) then resolution = 60
-
-
-
- /* This time, convert curves and get accurate size */
- totalsize = (biggestX-smallestX)+(biggestY-smallestY)
- oldControl2X = 0
- oldControl2Y = 0
- oldXcoord = 0
- oldYcoord = 0
-
- object = pdm_SelFirstObj()
- objectnumber = 1
- gridflag = 0 /* grid as lines or dots requester flag */
-
-
- do until object = 0
- if pdm_IsBezier(object)=1 then do
- numpoints = pdm_GetObjOrder(object)
- numpoints = numpoints -1 /* Counts from zero */
- pointnumber = 0
- do until pointnumber > numpoints
- pointinfo = pdm_GetPoint(object, pointnumber)
- parse var pointinfo Xcoord Ycoord control1X control1Y control2X control2Y
- pointinfo = Xcoord" "Ycoord||cr /* default for straight lines */
-
- /* See if it's a curved line and add points if so */
- if (control1X~=0 | control1Y~=0 | oldControl2X~=0 | oldControl2Y~=0) & pointnumber ~=0 & resolution~=0 then call Bezier2
-
- oldControl2X = control2X
- oldControl2Y = control2Y
- oldXcoord = Xcoord
- oldYcoord = Ycoord
- string = string||pointinfo
- if length(string)>20000 then do
- call writech("Output",string)
- string = ""
- end
- pointnumber = pointnumber+1
- end
- end
-
-
- /* Grid routines cannot be used yet due to bug in PDraw IsGrid command
- if pdm_IsGrid(object)=1 then do
- if gridflag = 0 then do
- gridformat = pdm_Inform(2,"Save grid as lines or dots?","Lines","Dots")
- gridflag = 1 /* don't ask again */
- end
- numlines = pdm_GetGridOrder(object)
- numpoints = 4
- pointnumber = 0
- do until pointnumber > numpoints
- pointinfo = pdm_GetPoint(object, pointnumber)
- parse var pointinfo Xcoord Ycoord
- gridcoords.pointnumber.Xcoord = Xcoord
- gridcoords.pointnumber.Ycoord = Ycoord
- string = string||pointinfo
- if gridformat = 1 then string = string||cr
- if length(string)>20000 then do
- call writech("Output",string)
- string = ""
- end
- pointnumber = pointnumber+1
- call gridexpand
- end
- */
-
- object = pdm_SelNextObj(object)
- objectnumber = objectnumber+1
- string = string||cr /* Blank line between objects */
- end
-
- call writech("Output",string)
- call finalize
-
- n = 2.54*2.54
- if units = 2 then do
- total1 = totalarea
- total2 = totalarea/n
- end
- else if units = 1 then do
- total1 = totalarea*n
- total2 = totalarea
- end
- total1 = trunc(total1,3)
- total2 = trunc(total2,3)
-
- exit_msg(" Area is "total1" square cm, "total2" square ins ")
-
- /* +++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++ */
-
- exit_msg()
-
- exit_msg: procedure expose units
- do
- parse arg message
-
- if message ~= '' then call pdm_Inform(1,message,)
- call pdm_ClearStatus()
- call pdm_SetUnits(units)
- call pdm_AutoUpdate(1)
- exit
- end
-
-
- /* ++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++ */
-
- Bezier2:
- /* Bezier2.SUB
- From Fundamentals of Interactive Computer Graphics
- From article by Steve Enns in Byte, Dec. '86
- (2D version only)
-
- Calculates cubic parametric freeform Bezier curves
-
- XC.,YC. are the coords of the 4 hull points, which are the current and previous points and their inner control points. */
-
- XC.1 = oldXcoord
- XC.2 = oldControl2X+oldXcoord /* control handle coords are relative */
- XC.3 = control1X+Xcoord
- XC.4 = Xcoord
- YC.1 = oldYcoord
- YC.2 = oldControl2Y+oldYcoord
- YC.3 = control1Y+Ycoord
- YC.4 = Ycoord
- curvesize = abs(Xcoord-oldXcoord)+abs(Ycoord-oldYcoord)
- curveratio = curvesize/totalsize
- increment = 1/(resolution * curveratio)
- if increment>0.5 then increment = 0.5 /* just put 1 in the middle */
-
- /* Returns CurveXcoord. and CurveYcoord. as the points
- Returns XNS as the number of curve points
- */
-
- IS=1
- pointinfo = ""
-
- do T=increment to 0.98 by increment /* 0.98 so as not to do a point right at the end of the curve, too close to first poit of next curve */
- T2=T*T
- T3=T2*T
- NC1=1-3*T+3*T2-T3
- NC2=3*T3-6*T2+3*T
- NC3=3*T2-3*T3
- NC4=T3
- CurveXcoord=(NC1*XC.1)+(NC2*XC.2)+(NC3*XC.3)+(NC4*XC.4)
- CurveYcoord=(NC1*YC.1)+(NC2*YC.2)+(NC3*YC.3)+(NC4*YC.4)
- pointinfo = pointinfo||CurveXcoord" "CurveYcoord||cr
- IS=IS+1
- end
-
- pointinfo = pointinfo||Xcoord" "Ycoord||cr
- XNS = IS-1 /* number of points */
-
- RETURN
-
- /* +++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++ */
-
- gridexpand: /* do the other points of a grid */
-
- return
-
- /* ++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++ */
-
- finalize: /* Calculate area from file of coordinates. Algorithm from Stolk & Ettershank, Byte Feb. '87, pp.135-6. */
-
- call pdm_ShowStatus(" Calculating area...")
- call seek("Output",0,"B")
- area = 0
- totalarea = 0
- oldXnumber=0
- oldYnumber=0
- linecount = 1
- firstX = 0
- firstY = 0
-
- do until eof("Output")
- numbers = readln("Output")
- parse var numbers Xnumber Ynumber
- if datatype(Xnumber,n) & datatype(Ynumber,n) then do
- area = area + (oldXnumber*Ynumber) - (oldYnumber*Xnumber)
- if linecount = 1 then do /* for open/closed check */
- firstX = Xnumber
- firstY = Ynumber
- end
- linecount = linecount+1
- oldXnumber = Xnumber
- oldYnumber = Ynumber
- end
- else do /* blank line between objects */
- if ~(oldXnumber = firstX & oldYnumber = firstY) then area = 0 /* not a closed object */
- linecount = 1
- totalarea = totalarea+area
- area = 0
- oldXnumber=0
- oldYnumber=0
- end
- end
- totalarea = abs(totalarea)/2
- call close("Output")
- /*address command
- 'delete "ram:tempfile"'*/
- return
-
-
-