procedure tvpolygon (image,ncorner,plength,pheight) char image ="" {prompt="Image to overlay polygon on"} int ncorner =4 {prompt="Number of vertices"} real plength =1. {prompt="Length of polygon (pixels)"} real pheight =1. {prompt="Height of polygon (pixels)"} real xcen =INDEF {prompt="Center position x (pixels)"} real ycen =INDEF {prompt="Center position y (pixels)"} real posang =0. {prompt="Position angle (degrees wrt. x-axis)"} bool doublew =no {prompt="Double width of lines?"} bool redispl =yes {prompt="(Re)display image first?"} real zlow =INDEF {prompt="Lower cut-level for displaying"} real zhigh =INDEF {prompt="Upper cut-level for displaying"} bool mkmask =no {prompt="Create mask image using polygon?"} char mask =".msk" {prompt="Name of output mask image"} bool outside =yes {prompt="Mask pixels outside polygon?"} int color =255 {prompt="Color for ellipse (0-255)"} # @(#) task tvpolygon Author: R.A. Jansen -- 27 April 1997 # @(#) # @(#) task to calculate and overlay polygons on a loaded image. The # @(#) shape of the polygons is determined by the number of vertices, # @(#) and by the width (plength) and height (pheight) in pixels. The # @(#) position and orientation are determined by xcen,ycen, and posang. # @(#) Default is the middle of the image and posang=0. This task can be # @(#) used to create a mask image if 'mask=yes' and one can select # @(#) whether the pixels inside or outside the polygon be masked (value # @(#) is 0. for masked, 1. for unmasked pixels). # @(#) # @(#) Feb 9 1998 -- General rewrite of this task. All mask features # @(#) are new. Above documentation is new. At this time # @(#) masking is only implemented for ncorner=4. # @(#) Jun 14 2000 -- Added support for multi-extension / N-dim. images. # @(#) Feb 8 2002 -- Added 'doublew' switch to better render lines on # @(#) displays with a poor match of data/screen pixels. begin char img, outimg, tmp, tmp2, cstr int clr, nsam, isam, i, j, npix1, npix2, xmin, xmax, ymin, ymax real cenx, ceny, da, db, pa, pi, cospa, sinpa, phi, cosphi real sinphi, x, y, lo, hi img = image nsam = ncorner da = plength db = pheight cenx = xcen ceny = ycen pa = posang lo = zlow hi = zhigh outimg = mask clr = color pi = 3.141592654 # Check whether required tv-package is loaded... if ( !defpac("tv") ) { error(1,"Please load \"image.tv\" first!") } # Check existence input and output images... unlearn chkimg chkimg (img, action="access", verbose=yes) if (!chkimg.ok) { return } img = chkimg.imroot//chkimg.imtype//chkimg.imrpstr if (mkmask) { if ( substr(outimg,1,1) == "." ) { outimg = chkimg.imroot//chkimg.imtype//outimg } chkimg (outimg, action="noaccess", verbose=yes) if (!chkimg.ok) { return } } # Check whether plength, pwidth and posang are default... if ( da == INDEF || da < 0. ) { da = 2.*nsam } if ( db == INDEF || db < 0. ) { db = 2.*nsam } if ( pa == INDEF ) { pa = 0. } # Get image size and check whether center is default... imgets (img, "i_naxis1") ; npix1 = int(imgets.value) imgets (img, "i_naxis1") ; npix1 = int(imgets.value) imgets (img, "i_naxis2") ; npix2 = int(imgets.value) if ( cenx == INDEF || cenx == 0. ) { cenx = nint(0.5*npix1) } if ( ceny == INDEF || ceny == 0. ) { ceny = nint(0.5*npix2) } # (Re) display image... if (redispl) { xdispl (img, z1=lo, z2=hi, zmode="linear", verbose=yes) } # Calculate x,y coordinates for the 'nsam' vertices... tmp = mktemp("tvplgn") sinpa = -sin(pa*pi/180.) cospa = cos(pa*pi/180.) for ( isam = 0 ; isam <= nsam ; isam = isam + 1 ) { phi = 2.0*pi*(isam+0.5)/nsam cosphi = cos(phi) sinphi = sin(phi) x = cenx + ((sinpa*cosphi*da) - (cospa*sinphi*db)) y = ceny + ((cospa*cosphi*da) + (sinpa*sinphi*db)) print (x," ",y," 101 s", >> tmp) } # Draw line segments, connecting all vertices... tvmark (1, coords="", commands=tmp, inter=no, color=clr, pointsize=1, txsize=1) if (doublew) { # Calculate x,y coordinates for the 'nsam' vertices... tmp2 = mktemp("tvplgn2") sinpa = -sin(pa*pi/180.) cospa = cos(pa*pi/180.) for ( isam = 0 ; isam <= nsam ; isam = isam + 1 ) { phi = 2.0*pi*(isam+0.5)/nsam cosphi = cos(phi) sinphi = sin(phi) x = cenx + ((sinpa*cosphi*(da-1)) - (cospa*sinphi*(db-1))) y = ceny + ((cospa*cosphi*(da-1)) + (sinpa*sinphi*(db-1))) print (x," ",y," 101 s", >> tmp2) } for ( isam = 0 ; isam <= nsam ; isam = isam + 1 ) { phi = 2.0*pi*(isam+0.5)/nsam cosphi = cos(phi) sinphi = sin(phi) x = cenx + ((sinpa*cosphi*(da-2)) - (cospa*sinphi*(db-2))) y = ceny + ((cospa*cosphi*(da-2)) + (sinpa*sinphi*(db-2))) print (x," ",y," 101 s", >> tmp2) } # Draw line segments, connecting all vertices... tvmark (1, coords="", commands=tmp2, inter=no, color=clr, pointsize=1, txsize=1) } if ( mkmask && ncorner == 4 ) { # Create a mask image ... print ("Creating mask image "//outimg//" ...") imcreate (outimg, 2, npix1, npix2, INDEF, INDEF, INDEF, INDEF, INDEF, header="copy", pixtype="real", reference=img) xmin = nint(cenx-0.5*da) xmax = nint(cenx+0.5*da) ymin = nint(ceny-0.5*db) ymax = nint(ceny+0.5*db) cstr = "["//str(xmin)//":"//str(xmax)//","//str(ymin)//":"//str(ymax)//"]" imreplace (outimg//cstr, 1., lower=INDEF, upper=INDEF) if (!outside) { imarith (outimg, "*", "-1.", outimg, title="", divzero=0., hparams="", pixtype="real", calctype="real", verbose=no, noact=no) } pa = pa + 90. if ( pa > 180. ) { pa = pa - 180. } rotate (outimg, outimg, pa, xin=cenx, yin=ceny, xout=INDEF, yout=INDEF, ncols=npix1, nlines=npix2, interpolant="linear", boundary="constant", constant=0., nxblock=512, nyblock=512, verbose=no) } else { if (mkmask) { print ("Sorry; the masking option is not yet implemented for ncorner!=4.") } } # Clean-up... delete (tmp, yes, verify=no) if (doublew) { delete (tmp2,yes, verify=no) } print ("Finished.") end