#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 #pragma version=1.03 #include static constant kCHECK_FOR_UPDATES=1 // set to 1 to check for updates on init static constant kFREQUENCY=604800 // (seconds). updater won't check more frequently than this. weekly=604800. static strconstant ksVERSION="1.03" static strconstant ksPROJECT="Encircle" static strconstant ksLOCATION="http://www.igorexchange.com/node/7895/release" static strconstant ksSHORTNAME="Encircle" static strconstant ksPREFSFILE="EncirclePrefs.bin" // by tony.withers@uwo.ca // Description // draws a polgon around a cloud of data points on a plot. // How to use // Right click on a data point to invoke the trace menu and select // "Encircle points". // If you reshape the graph window you can repeat this procedure to // update the shape of the polygon. // Selecting "Remove Encircled Region" deletes the shaded region. // Polygons are drawn in the user back layer and can be edited with the // drawing tools. // Details // Polygon surrounds all of the data in the wave. // It makes most sense to apply this to x-y data. // Version history // 1.03 if Package Updater is installed, will check IgorExchange for new releases // 1.02 deal with offsets // 1.01 bug fix: remove gratuitous print statement Menu "TracePopup" "Encircle points", /Q, DrawCatmullRomBoundingSpline() "Remove encircled region", /Q, RemoveBoundingSpline() end function DrawCatmullRomBoundingSpline() #if (exists("Updater#CheckForUpdates")==6) if(Updater#CheckForUpdates(kCHECK_FOR_UPDATES,kFREQUENCY,ksVERSION,ksPROJECT,ksLOCATION,ksSHORTNAME,ksPREFSFILE)) return 0 // allow user to reload new version of this file before continuing endif #endif // initialize (or reinitialize) the package data folder NewDataFolder /O root:Packages NewDataFolder /O root:Packages:Encircle // Create a data folder reference variable DFREF dfr = root:Packages:Encircle // figure out graph and trace names GetLastUserMenuInfo string s_info=traceinfo(S_graphName, S_traceName, 0) //print s_info if(numtype(NumberByKey("AXISZ",s_info))==0) doalert 1, "you've selected a contour trace. Continue?" if (v_flag==2) return 0 endif endif if(strlen(stringbykey("XWAVE",s_info))==0) duplicate /free tracenametowaveref(S_graphName, S_traceName), xdata xdata=x else wave xdata=XWaveRefFromTrace(S_graphName, S_traceName) endif wave ydata=tracenametowaveref(S_graphName, S_traceName) // number of points to calculate between nodes variable nPoints=20 variable alpha=0.5 // alpha=0 for standard (uniform) Catmull-Rom spline // alpha=0.5 for centripetal Catmull-Rom spline // alpha=1 for chordal Catmull-Rom spline if (numpnts(ydata)<3) doalert 0, "must have more than two data points" return 0 endif Convexhull xdata,ydata wave W_XHull=W_XHull, W_YHull=W_YHull // deal with offsets W_XHull+=GetNumFromModifyStr(s_info,"offset","{",0) W_YHull+=GetNumFromModifyStr(s_info,"offset","{",1) variable vertices=numpnts(W_XHull) make /free/n=(vertices+3) x_hull, y_hull x_hull=W_XHull[p-(vertices)*(p>(vertices-1))] y_hull=W_YHull[p-(vertices)*(p>(vertices-1))] // find the centroid of the hull variable x0=0, y0=0, varA=0 variable i, factor for(i=0;i(np-1))] y_temp=ydata[p-(np-1)*(p>(np-1))] make /free /n=(segPoints) x_out, y_out make /free /n=4 x_in, y_in variable i for(i=1;i-1) v_end= strsearch(webPageText, "", v_start) v_start+=strlen(ksPROJECT)+6 v_end-=1 v_success=v_success&&(v_end>v_start)&&((v_end-v_start)<30) if(v_success) s_releaseVersion=webPageText[v_start, v_end] else sprintf cmd, "%s: Could not find packages at %s.\r", ksPROJECT, ksLOCATION cmd+="Please check for new versions at http://www.igorexchange.com/" if (chatty) doalert 0, cmd endif print cmd return 0 endif variable ReleaseIgorMajor, ReleaseIgorMinor, ReleaseMajor, ReleaseMinor, IgorCurrent, IgorCurrentMinor sscanf s_releaseVersion, "%d.%d.x-%d.%d", ReleaseIgorMajor, ReleaseIgorMinor, ReleaseMajor, ReleaseMinor s_currentIgor=StringByKey("IGORFILEVERSION", igorinfo(3)) sscanf s_currentIgor, "%d.%d", IgorCurrent, IgorCurrentMinor if (IgorCurrent200)) sprintf cmd, "%s: Could not resolve download location", ksSHORTNAME print cmd if (chatty) doalert 0, cmd endif return 0 endif v_end+=3 s_url=webPageText[v_start, v_end] if (chatty) sprintf cmd, "%s: Found version %d.%d. Download now?", ksSHORTNAME, ReleaseMajor, ReleaseMinor doalert 1, cmd if (v_flag==2) return 0 endif endif webPageText=FetchURL(s_url) killwindow /Z UpdaterTempNB NewNotebook /N=UpdaterTempNB/F=0/OPTS=3/V=0/ENCG=1 as "Updater Temp File" // create a hidden notebook notebook UpdaterTempNB text=replacestring("\r\n",webPageText,"\r") // strip newlines from FetchURL output v_start= strsearch(s_releaseVersion, "-", 0) printf "%s: loaded %s%s from %s\r", ksPROJECT, ksSHORTNAME, s_releaseVersion[v_start+1,strlen(s_releaseVersion)-1], s_url // try to find current location of procedure file pathinfo IgorUserFiles s_path=FindFile(s_path, s_filename) // look in subfolders of user files folder for this procedure file if (strlen(s_path)) // s_path will be "" if file not found cmd="" if (!chatty) sprintf cmd, "New update found for %s\r", ksPROJECT endif sprintf cmd, "%sOverwrite %s%s with new version?\r\r", cmd, s_path, s_filename doalert 1, cmd if(v_flag==2) printf "%s: update cancelled\r", ksPROJECT return 0 endif newPath /O/Q/Z ipfPath, s_path SaveNotebook /O/S=6/P=ipfPath UpdaterTempNB as s_filename else sprintf cmd, "Select location of %s and click Save to overwrite", s_filename SaveNotebook /M=cmd/I/S=6/P=IgorUserFiles UpdaterTempNB as s_filename endif if (strlen(s_path)) printf "%s: saved release to %s\r", ksPROJECT, s_path sprintf cmd, "Allow Igor to reload %s to complete installation", s_filename doalert 0, cmd else printf "%s: update failed\r", ksPROJECT endif // clean up killwindow /Z UpdaterTempNB killpath /Z ipfPath return 1 end // search recursively for s_file within folder described by s_path. // don't expect this to be quick. static function /T FindFile(s_path, s_file) String s_path, s_file variable folderLimit=5000 // quits after looking in this many folders. Variable folderIndex, fileIndex, i, startFolder, stopFolder, folderCount string s_folderList, fileName if (strlen(s_path)==0) // it would be nice to default to the current save location, but I couldn't find a way to do that s_path=SpecialDirPath("Documents", 0, 0, 0) endif make /o/T/n=1 w_folders w_folders={s_path} folderCount=1 startFolder=0 do stopFolder=numpnts(w_folders) for(folderIndex=startFolder;folderIndexfolderLimit) break endif startFolder=stopFolder while(1) for(folderIndex=0;folderIndex