/3.0 (Extension.1 Name: "Create Thiessen Polygons" FirstRootClassName: "List" Roots: 2 Roots: 4 Roots: 3 Roots: 10 Roots: 11 Roots: 12 Roots: 13 Roots: 14 Roots: 15 Roots: 16 Version: 30 About: "Build thiessen polygons from a point theme\n\nCreated with \"X-10sion\" extension builder by Greg Ammon\nLos Angeles Dept. of Water & Power, gammon@dwp.ci.la.ca.us" InstallScript: 17 UninstallScript: 18 ExtVersion: 1 ) (List.2 Child: 3 Child: 3 ) (Nil.3 ) (List.4 Child: 5 ) (List.5 Child: 6 Child: 8 Child: 9 ) (Butn.6 Disabled: 1 Help: "Thiessen Polygons//Create thiessen polygons from active point theme" Update: "View.SinglePointThmUpdate" Icon: 7 Click: "View.MakePointPolygons" ) (AVIcon.7 Name: "thiesn.gif" Data: 4e442049 6d616765 00010014 00110000 Data: 01540000 00000000 00000000 00000000 Data: 01000000 00000000 00000202 00000000 Data: 00000000 01000000 00000000 00000202 Data: 00000000 00000001 00000202 00000000 Data: 00000000 00000000 00000001 00000202 Data: 00000100 00000000 00000000 00000100 Data: 00000000 00000001 01000000 00000000 Data: 00000100 00000000 01010000 00010101 Data: 01010101 01010000 00000101 00000000 Data: 00000100 00000000 00000100 01010000 Data: 00000000 00000001 00000002 02000001 Data: 00000000 00000000 00000000 01000002 Data: 02000001 00000000 00000002 02000000 Data: 00010000 00000001 00000000 02020002 Data: 02000000 00000101 01010101 00000000 Data: 02020000 00000000 00010000 00000000 Data: 01000000 00000000 00000000 01000000 Data: 00000000 00010000 00000000 00000001 Data: 00000000 00000000 00000100 00000000 Data: 00000100 00000000 02020000 00000001 Data: 00000000 00010000 00000000 02020000 Data: 00000000 01000000 000cffff ccff0000 Data: 00000000 00000002 00080005 00180000 Data: 00000000 00000000 0000 ) (Numb.8 ) (AVStr.9 S: "View" ) (Script.10 Name: "View.MakePointPolygons" SourceCode: "'*Script: View.MakePointPolygons\ntheView = av.GetActiveDoc\npointTheme = nil\n\n\n'*** define point input\nactThemes = theView.GetActiveThemes\nif (actThemes.Count = 1) then\n theTheme = actThemes.Get(0)\n if (theTheme.Is(FTheme)) then\n if (theTheme.GetFTab.GetShapeClass.GetClassName = \"Point\") then\n if (theTheme.GetFTab.GetNumRecords < 2) then\n MsgBox.Error(\"There must be at least 3 points in a theme for calculation!\", \"Build Thiessen Polygons\")\n return nil\n end\n pointTheme = theT heme\n end\n end\nend\n\nif (pointTheme = nil) then\n MsgBox.Error(\"Single active \"\"point\"\" theme not found!\", \"Build Thiessen Polygons\")\n return nil\nend\n\npointFTab = pointTheme.GetFTab\npointSelection = nil\nif (pointTheme.CanSelect) then\n pointSelection = pointFTab.GetSelection\n if (pointSelection.Count <= 0) then\n pointSelection = nil\n elseif (pointSelection.Count < 2) then\n MsgBox.Error(\"To calculate on a subset, a minimum of 2 points must be selected.\"++\n \"Please reselect or clea r the selection to use the entire theme.\",\n \"Build Thiessen Polygons\")\n return nil\n end\nend\n\n\n'*** define point-polygon ID link field\npointFieldList = List.Make\nfor each aField in pointFTab.GetFields\n if (aField.IsVisible and aField.IsTypeShape.Not) then\n pointFieldList.Add(aField)\n end\nend\n\nif (pointFieldList.Count = 0) then\n idField = nil\nelse\n idField = MsgBox.List(pointFieldList, \"Select point field for polygon ID link:\", \"Build Thiessen Polygons\")\nend\n\nbuildDictionary = True\n if (idField = nil) then\n if(MsgBox.YesNo(\"There was no point ID field was defined. Do you want to continue without an ID link?\", \"Build Thiessen Polygons\", False).Not) then\n return nil\n else\n buildDictionary = False\n pointIdDict = nil\n end\nend\n\n\n'*** define polygon boundry \npgThemeList = List.Make\nfor each aTheme in theView.GetThemes\n if (aTheme.Is(FTheme) and aTheme.CanSelect and (aTheme.GetFTab.GetShapeClass.GetClassName = \"Polygon\")) then\n pgThemeList.Add(aTheme)\n end\nend\n\nlimitsPG = Polygon.MakeNull\nif (pgThemeList.Count > 0) then\n pgTheme = MsgBox.List(pgThemeList, \"Select polygon theme for boundry or \"\"Cancel\"\" to use a buffered point area:\", \"Build Thiessen Polygons\")\n if (pgTheme <> nil) then\n pgFTab = pgTheme.GetFTab\n pgShapeField = pgFTab.FindField(\"Shape\")\n pgSelection = pgFTab.GetSelection\n if (pgFTab.GetNumRecords = 1) then\n for each pgRec in pgFTab\n limitsPG = pgFTab.ReturnValue(pgShapeField, pgRec)\n end\n elseif (pgSelection.Count = 1) then\n limitsPG = pgFTab.ReturnValue(pgShapeField, pgSelection.GetNextSet(-1))\n elseif (pgSelection.Count = 0) then\n if (MsgBox.YesNo(\"There are no selected records in the boundry theme. Would you like to merge all features and use the entire theme?\", \"Build Thiessen Polygons\", True)) then\n for each pgRec in pgFTab\n if (limitsPG.IsNull) then\n limitsPG = pgFTab.ReturnValue(pgShapeField, pgRec)\n else\n limitsPG = limitsPG.ReturnUnion(pgFTab.ReturnValue(pgS hapeField, pgRec))\n end\n end\n else\n return nil\n end\n else\n if (MsgBox.YesNo(\"There are multiple records selected in the boundry theme. Would you like to merge the selected features and continue?\", \"Build Thiessen Polygons\", True)) then\n pgRec = pgSelection.GetNextSet(-1)\n while (pgRec > -1)\n if (limitsPG.IsNull) then\n limitsPG = pgFTab.ReturnValue(pgShapeField, pgRec)\n else\n limitsPG = limitsPG.ReturnUnion(pgFTab .ReturnValue(pgShapeField, pgRec))\n end\n pgRec = pgSelection.GetNextSet(pgRec)\n end\n end\n end\n end\nend\n\nif (limitsPG.IsNull) then\n if (MsgBox.YesNo(\"There is no polygon boundry defined. Would you like to continue with a buffered point area?\", \"Build Thiessen Polygons\", False).Not) then\n return nil\n end\nend\n\n\n'*** build and verify point input list\npointList = List.Make\npointShapeField = pointFTab.FindField(\"Shape\")\n\nav.ClearStatus\nav.ShowMsg(\"Building point input list. ..\")\ncurrentElt = 0\nexcludeCount = 0\nif (pointSelection = nil) then\n if (buildDictionary) then\n pointIdDict = Dictionary.Make(pointFTab.GetNumRecords / 2)\n end\n \n eltCount = pointFTab.GetNumRecords\n for each pointRec in pointFTab\n aPoint = pointFTab.ReturnValue(pointShapeField, pointRec)\n\n if (limitsPG.IsNull) then\n pointList.Add(aPoint)\n if (buildDictionary) then\n pointIdDict.Add(aPoint, pointFTab.ReturnValue(idField, pointRec))\n end\n elseif (limitsPG.Contains(aPoint) ) then\n pointList.Add(aPoint)\n if (buildDictionary) then\n pointIdDict.Add(aPoint, pointFTab.ReturnValue(idField, pointRec))\n end\n else\n excludeCount = excludeCount + 1\n end\n\n currentElt = currentElt + 1\n av.SetStatus(currentElt / eltCount * 100)\n end\nelse\n if (buildDictionary) then\n pointIdDict = Dictionary.Make(pointSelection.Count / 2)\n end\n \n eltCount = pointSelection.Count\n pointRec = pointSelection.GetNextSet(-1)\n while (pointRec <> -1)\n aPoint = poin tFTab.ReturnValue(pointShapeField, pointRec)\n\n if (limitsPG.IsNull) then\n pointList.Add(aPoint)\n if (buildDictionary) then\n pointIdDict.Add(aPoint, pointFTab.ReturnValue(idField, pointRec))\n end\n elseif (limitsPG.Contains(aPoint)) then\n pointList.Add(aPoint)\n if (buildDictionary) then\n pointIdDict.Add(aPoint, pointFTab.ReturnValue(idField, pointRec))\n end\n else\n excludeCount = excludeCount + 1\n end\n\n pointRec = pointSelection.GetNextSet(pointRe c)\n currentElt = currentElt + 1\n av.SetStatus(currentElt / eltCount * 100)\n end \nend\nif (excludeCount > 0) then\n if (MsgBox.YesNo(\"There were\"++excludeCount.AsString++\"points excluded outside the boundry limits. Would you like to continue?\", \"Build Thiessen Polygons\", True).Not) then\n return nil\n end\nend\nav.ClearStatus\nav.ClearMsg\n\n\n'*** build buffered point area boundry\nif (limitsPG.IsNull) then\n buffPercent = MsgBox.Input(\"Enter percentage to buffer point area with for boundry:\", \"B uild Thiessen Polygons\", \"\")\n if (buffPercent = nil) then return nil end\n while (buffPercent.IsNumber.Not and (buffPercent.AsNumber > 0))\n buffPercent = MsgBox.Input(\"Buffer percentage must be a positive number:\", \"Build Thiessen Polygons\", buffPercent)\n if (buffPercent = nil) then return nil end\n end\n \n buffFactor = buffPercent.AsNumber / 100\n hullList = av.Run(\"Sub.GetConvexHull\", pointList)\n if (hullList = nil) then return nil end\n hullPG = Polygon.Make({hullList})\n hullExtent = hullPG.Ret urnExtent\n buffDistance = hullExtent.ReturnCenter.Distance(hullExtent.ReturnOrigin) * buffFactor\n limitsPG = hullPG.ReturnBuffered(buffDistance)\n\n if (limitsPG = nil) then return nil end\nend\n\n\n'*** define output theme file\ntype = \"Polygon\"\nclass = Polygon\n\noutThemeFile = FileName.GetCWD.MakeTmp(\"thiesn\", \"shp\")\noutThemeFile = FileDialog.Put(outThemeFile, \"*.shp\", \"Output Theme File\")\nif (outThemeFile = nil) then return nil end\noutTable = FTab.MakeNew(outThemeFile, class)\nif (outTable.HasError) then\n if (outTable.HasLockError) then\n MsgBox.Error(\"Unable to acquire write lock for file \" + outThemeFile.GetBaseName, \"Build Thiessen Polygons\")\n else\n MsgBox.Error(\"Unable to create \" + outThemeFile.GetBaseName, \"Build Thiessen Polygons\")\n end\n return nil\nend\n\n\n'*** build thiessen polygons\nthsnList = av.Run(\"Sub.GetThsnPolygons\", {pointList, limitsPG})\nif (thsnList = nil) then\n MsgBox.Error(\"Error in polygon calculation!\", \"Build Thiessen Polygons\")\n return nil\nend\npointIndex = thsnList.Get(1) \nthsnList = thsnList.Get(0)\n\n\n'*** write output theme file\noutShapeField = outTable.FindField(\"Shape\")\nareaField = Field.Make(\"Area\", #FIELD_DECIMAL, 16, 16)\npercentField = Field.Make(\"Prcnt_tot\", #FIELD_DECIMAL, 16, 16)\noutTable.AddFields({areaField, percentField})\ntotalArea = limitsPG.ReturnArea\nif (idField = nil) then\n for each thsnPolygon in thsnList\n addRec = outTable.AddRecord\n outTable.SetValue(outShapeField, addRec, thsnPolygon)\n outTable.SetValue(areaField, addRec, thsnPolygon.ReturnArea) \n outTable.SetValue(percentField, addRec, thsnPolygon.ReturnArea / totalArea * 100)\n end\nelse\n pgIDField = idField.Clone\n outTable.AddFields({pgIDField})\n currentElt = 0\n while (currentElt < thsnList.Count)\n thsnPolygon = thsnList.Get(currentElt)\n idValue = pointIdDict.Get(pointIndex.Get(currentElt))\n addRec = outTable.AddRecord\n outTable.SetValue(outShapeField, addRec, thsnPolygon)\n outTable.SetValue(pgIDField, addRec, idValue)\n outTable.SetValue(areaField, addRec, thsnPolygon.Ret urnArea)\n outTable.SetValue(percentField, addRec, thsnPolygon.ReturnArea / totalArea * 100)\n currentElt = currentElt + 1\n end\nend\n\n\n'*** add theme to view\noutTable.SetEditable(False)\noutTheme = FTheme.Make(outTable)\ntheView.AddTheme(outTheme)\noutTheme.SetVisible(True)" ) (Script.11 Name: "View.SinglePointThmUpdate" SourceCode: "'*Script: View.SinglePointThmUpdate\ntheView = av.GetActiveDoc\nactThemes = theView.GetActiveThemes\n\nenableIt = True\nif (actThemes.Count <> 1) then enableIt = False end\nif (enableIt) then\n if (actThemes.Get(0).GetFTab.GetShapeClass.GetClassName <> \"Point\") then\n enableIt = False\n end\nend\nSelf.SetEnabled(enableIt)" ) (Script.12 Name: "Sub.GetConvexHull" SourceCode: "'*Script: Sub.GetConvexHull\npointList = Self\n\n'*** geometry subroutines\nsubGet3PDirection = av.FindScript(\"Sub.Get3PDirection\")\nsubRadialPointSort = av.FindScript(\"Sub.RadialPointSort\")\n\n'*** input validation\nif (subGet3PDirection = nil) then\n MsgBox.Error(\"Subroutine not found: \"\"Sub.Get3PDirection\"\"\", \"Sub.GetConvexHull\")\n return nil\nelseif (subRadialPointSort = nil) then\n MsgBox.Error(\"Subroutine not found: \"\"Sub.RadialPointSort\"\"\", \"Sub.GetConvexHull\")\n return nil\nelseif (pointList.Is(List).Not) the n\n MsgBox.Error(\"Invalid point list\", \"Sub.GetConvexHull\")\n return nil\nelseif (pointList.Count < 3) then\n MsgBox.Error(\"Point list count < 3\", \"Sub.GetConvexHull\")\n return nil\nend\n\nav.ClearMsg\nav.ClearStatus\neltCount = pointList.Count\ncurrentElt = 0\nav.ShowMsg(\"Validating point input...\")\nfor each aPoint in pointList\n if (aPoint.Is(Point).Not) then\n av.ClearStatus\n av.ClearMsg\n MsgBox.Error(\"Input point invalid\", \"Sub.GetConvexHull\")\n return nil\n end\n currentElt = currentElt + 1\n av.SetS tatus(currentElt / eltCount * 100)\nend\nav.ClearStatus\n\n'*** begin calcs\nhullBase = Point.MakeNull\nhullTop = Point.MakeNull\nhullLeft = Point.MakeNull\nhullRight = Point.MakeNull\nfor each aPoint in pointList\n if (hullBase.IsNull) then\n hullBase = aPoint\n elseIf (aPoint.GetY < hullBase.GetY) then\n hullBase = aPoint\n end\n if (hullTop.IsNull) then\n hullTop = aPoint\n elseIf (aPoint.GetY > hullTop.GetY) then\n hullTop = aPoint\n end\n if (hullLeft.IsNull) then\n hullLeft = aPoint\n elseIf (aPoint. GetX < hullLeft.GetX) then\n hullLeft = aPoint\n end\n if (hullRight.IsNull) then\n hullRight = aPoint\n elseIf (aPoint.GetX > hullRight.GetX) then\n hullRight = aPoint\n end\nend\n\nexcludeBounds = {hullBase, hullRight, hullTop, hullLeft}\nexcludePoly = Polygon.Make({excludeBounds})\n\nav.ClearStatus\nav.ShowMsg(\"Excluding known interior points...\")\nstatusCount = pointList.Count\neltCount = 0\ncheckList = List.Make\nfor each aPoint in pointList\n if (\n (aPoint = hullBase) or \n (excludePoly.Contains(a Point) and (excludeBounds.Find(aPoint) = -1))\n ) then\n continue\n end\n checkList.Add(aPoint)\n eltCount = eltCount + 1\n av.SetStatus(eltCount / statusCount * 100)\nend\ncheckList = subRadialPointSort.DoIt({checkList, hullBase})\nav.ClearStatus\nav.ClearMsg \n\nav.ClearStatus\nav.ShowMsg(\"Locating convex hull...\")\nstatusCount = checkList.Count\neltCount = 0\nhullList = {hullBase}\nfor each checkPoint in checkList\n if (hullList.Count < 2) then\n hullList.Add(checkPoint)\n continue\n end\n hullDir = subGe t3PDirection.DoIt({hullList.Get(hullList.Count -2), hullList.Get(hullList.Count -1), checkPoint})\n if (hullDir = 0) then\n colinerBase = hullList.Get(hullList.Count -2)\n colinerLast = hullList.Get(hullList.Count -1)\n if (colinerBase.Distance(checkPoint) < colinerBase.Distance(colinerLast)) then\n hullList.Set(hullList.Count -1, checkPoint)\n checkPoint = colinerLast\n end\n end\n while ((hullDir < 0) and (hullList.Count > 1))\n hullList.Remove(hullList.Count -1)\n hullDir = subGet3PDi rection.DoIt({hullList.Get(hullList.Count -2), hullList.Get(hullList.Count -1), checkPoint})\n end\n hullList.Add(checkPoint)\n eltCount = eltCount + 1\n av.SetStatus(eltCount / statusCount * 100)\nend\nav.ClearStatus\nav.ClearMsg \n\nreturn hullList" ) (Script.13 Name: "Sub.GetThsnPolygons" SourceCode: "'*Script: Sub.GetThsnPolygons\npointList = Self.Get(0)\nlimitsPG = Self.Get(1)\nlimitsPL = limitsPG.AsPolyLine\n\n'*** geometry subroutines\nsubGet3PCircle = av.FindScript(\"Sub.Get3PCircle\")\nsubRadialPointSort = av.FindScript(\"Sub.RadialPointSort\")\n\n'*** input validation\nif (subGet3PCircle = nil) then\n MsgBox.Error(\"Subroutine not found: \"\"Sub.Get3PCircle\"\"\", \"Sub.GetThsnPolygons\")\n return nil\nelseif (subRadialPointSort = nil) then\n MsgBox.Error(\"Subroutine not found: \"\"Sub.RadialPointSort\"\"\", \"Sub.GetThsnPoly gons\")\n return nil\nelseif (pointList.Is(List).Not) then\n MsgBox.Error(\"Invalid point list\", \"Sub.GetThsnPolygons\")\n return nil\nelseif (pointList.Count < 2) then\n MsgBox.Error(\"Point list count < 2\", \"Sub.GetThsnPolygons\")\n return nil\nelseif (limitsPG.Is(Polygon).Not) then\n MsgBox.Error(\"Invalid limits polygon\", \"Sub.GetThsnPolygons\")\n return nil\nend\n\nav.ClearMsg\nav.ClearStatus\neltCount = pointList.Count\ncurrentElt = 0\nav.ShowMsg(\"Validating point input...\")\nfor each aPoint in pointList\n if (aPoint.I s(Point).Not or limitsPG.Contains(aPoint).Not) then\n av.ClearStatus\n av.ClearMsg\n MsgBox.Error(\"Input point invalid or outside limits\", \"Sub.GetThsnPolygons\")\n return nil\n end\n currentElt = currentElt + 1\n av.SetStatus(currentElt / eltCount * 100)\nend\nav.ClearStatus\n\n'*** begin calcs\nlimitsRect = limitsPG.ReturnExtent\nlimitsCenter = limitsRect.ReturnCenter\nlimitsRadius = limitsCenter.Distance(limitsRect.ReturnOrigin) * 2\nworldTop = Point.Make(limitsCenter.GetX, limitsCenter.GetY + (limitsRadi us * 2))\nworldLeft = Point.Make(limitsCenter.GetX - (limitsRadius * 3.Sqrt), limitsCenter.GetY - limitsRadius)\nworldRight = Point.Make(limitsCenter.GetX + (limitsRadius * 3.Sqrt), limitsCenter.GetY - limitsRadius)\n\nworldList = {worldTop, worldLeft, worldRight}\ntinCirList = {{Circle.Make(limitsCenter, limitsRadius * 3.Sqrt), worldList}}\n\nav.ClearStatus\nav.ShowMsg(\"Generating tin...\")\nstatusCount = pointList.Count\neltCount = 0\nfor each insPoint in pointList\n buildList = List.Make\n for each tinSet in tinCirL ist.Clone\n tinCircle = tinSet.Get(0)\n insDist = insPoint.Distance(tinCircle.ReturnCenter)\n if (insDist > tinCircle.GetRadius) then\n continue\n end\n if (insDist = tinCircle.GetRadius) then\n pointError = False\n for each aPoint in tinSet.Get(1)\n if ((aPoint.GetX = insPoint.GetX) and (aPoint.GetY = insPoint.GetY)) then\n av.ClearStatus\n av.ClearMsg\n MsgBox.Error(\"Duplicate input points at:\"++aPoint.GetX.AsString+\",\"++aPoint.GetY.AsString, \"Sub.GetThs nPolygons\")\n return nil\n end\n end\n end\n buildList.Merge(tinSet.Get(1))\n tinCirList.RemoveObj(tinSet)\n end\n buildList.RemoveDuplicates\n buildList = subRadialPointSort.DoIt({buildList, insPoint})\n lastPoint = Point.MakeNull\n for each buildPoint in buildList\n if (lastPoint.IsNull) then\n lastPoint = buildPoint\n continue\n end\n tinDef = {insPoint, lastPoint, buildPoint}\n tinCircle = subGet3PCircle.DoIt(tinDef)\n tinCirList.Add({tinCircle, tinDef})\n las tPoint = buildPoint\n end\n tinDef = {insPoint, buildList.Get(buildList.Count -1), buildList.Get(0)}\n tinCircle = subGet3PCircle.DoIt(tinDef)\n tinCirList.Add({tinCircle, tinDef})\n eltCount = eltCount + 1\n av.SetStatus(eltCount / statusCount * 100)\nend\nav.ClearStatus\nav.ClearMsg \n\nav.ClearStatus\nav.ShowMsg(\"Calculating polygons...\")\nstatusCount = pointList.Count\neltCount = 0\n\nthsnList = List.Make\npointIndex = List.Make\nfor each aPoint in pointList\n thsnSet = List.Make\n clipLimits = False\n for each ti nSet in tinCirList\n tinDef = tinSet.Get(1)\n if (tinDef.Find(aPoint) > -1) then\n tinCircle = tinSet.Get(0)\n thsnVertex = tinCircle.ReturnCenter\n thsnSet.Add(thsnVertex)\n if (clipLimits.Not and limitsPG.Contains(thsnVertex).Not) then\n clipLimits = True\n end\n end\n end\n thsnSet = subRadialPointSort.DoIt({thsnSet, aPoint})\n thsnPolygon = Polygon.Make({thsnSet})\n \n if (clipLimits or thsnPolygon.Intersects(limitsPL)) then\n thsnPolygon = limitsPG.ReturnIntersection(t hsnPolygon)\n end\n\n thsnList.Add(thsnPolygon)\n pointIndex.Add(aPoint)\n eltCount = eltCount + 1\n av.SetStatus(eltCount / statusCount * 100)\nend\nav.ClearStatus\nav.ClearMsg \n\nreturn {thsnList, pointIndex}" ) (Script.14 Name: "Sub.Get3PCircle" SourceCode: "'*Script: Sub.Get3PCircle\na_Point = Self.Get(0)\na_X = a_Point.GetX\na_Y = a_Point.GetY\nb_Point = Self.Get(1)\nb_X = b_Point.GetX\nb_Y = b_Point.GetY\nc_Point = Self.Get(2)\nc_X = c_Point.GetX\nc_Y = c_Point.GetY\ncalcA = b_X - a_X\ncalcB = b_Y - a_Y\ncalcC = c_X - a_X\ncalcD = c_Y - a_Y\ncalcG = 2 * ((calcA * (c_Y - b_Y)) - (calcB * (c_X - b_X)))\nif (calcG = 0) then\n theCircle = Circle.MakeNull\nelse \n calcE = (calcA * (a_X + b_X)) + (calcB * (a_Y + b_Y))\n calcF = (calcC * (a_X + c_X)) + (calcD * (a_Y + c_Y))\n cent erX = ((calcD * calcE) - (calcB * calcF)) / calcG\n centerY = ((calcA * calcF) - (calcC * calcE)) / calcG\n centerPoint = Point.Make(centerX, centerY)\n theRadius = a_Point.Distance(centerPoint)\n theCircle = Circle.Make(centerPoint, theRadius)\nend\nreturn theCircle" ) (Script.15 Name: "Sub.Get3PDirection" SourceCode: "'*Script: Sub.Get3PDirection\na_Point = Self.Get(0)\na_X = a_Point.GetX\na_Y = a_Point.GetY\nb_Point = Self.Get(1)\nb_X = b_Point.GetX\nb_Y = b_Point.GetY\nc_Point = Self.Get(2)\nc_X = c_Point.GetX\nc_Y = c_Point.GetY\nxStartMid = b_X - a_X 'dx1\nyStartMid = b_Y - a_Y 'dy1\nxStartEnd = c_X - a_X 'dx2\nyStartEnd = c_Y - a_Y 'dy2\n'slopes multiplied by \"xStartMid * xStartEnd\" to avoid divide by 0\nslopeStartMid = xStartEnd * yStartMid\nslopeStartEnd = xStartMid * yStartEnd\nif (slopeStartEnd > slopeStartMid) then\n return 1 ' counterclockwise\nelseif (slopeStartEnd < slopeStartMid) then\n return -1 'clockwise\nelse\n return 0 'coliner\nend" ) (Script.16 Name: "Sub.RadialPointSort" SourceCode: "'*Script: Sub.RadialPointSort\npointList = Self.Get(0)\nsortCenter = Self.Get(1)\n\nsortList = List.Make\nfor each aPoint in pointList\n distX = aPoint.GetX - sortCenter.GetX\n distY = aPoint.GetY - sortCenter.GetY\n if (distX.Abs + distY.Abs = 0) then\n sortKey = 0\n else\n sortKey = distY / (distX.Abs + distY.Abs)\n end\n if (distX < 0) then\n sortKey = 2 - sortKey\n elseif (distY < 0) then\n sortKey = 4 + sortKey\n end\n sortKey = sortKey * 90\n\n if (sortList.IsEmpty) then\n sortList.Add({sortKey, aPoint})\n continue\n end\n\n newSet = {sortKey, aPoint}\n\n if (sortKey < sortList.Get(0).Get(0)) then\n sortList.Insert(newSet)\n elseif (sortKey = sortList.Get(0).Get(0)) then\n sortList.Insert(sortList.Get(0))\n sortList.Set(1, newSet)\n elseif (sortKey >= sortList.Get(sortList.Count -1).Get(0)) then\n sortList.Add(newSet)\n else\n indexBase = 0\n indexBound = sortList.Count -1\n addIndex = Number.MakeNull\n while (addIndex.IsNull)\n searchCount = indexBound - indexBase\n if (sea rchCount < 4) then\n for each idxVector in 0 .. searchCount\n binIndex = indexBound - idxVector\n binValue = sortList.Get(binIndex).Get(0)\n if (sortKey >= binValue) then\n addIndex = binIndex + 1\n break\n end\n end\n if (addIndex.IsNull) then\n addIndex = indexBase\n end\n else\n binIndex = indexBase + (searchCount / 2).Round\n binValue = sortList.Get(binIndex).Get(0)\n if (sortKey = binValue) then\n addIndex = binIndex + 1\n elseif (sortKey < binValue) then\n indexBound = binIndex\n elseif (sortKey > binValue) then\n indexBase = binIndex\n end\n end\n end\n sortList.Add(newSet)\n sortList.Shuffle(newSet, addIndex)\n end\nend\n\nradialList = List.Make\nfor each sortSet in sortList\n radialList.Add(sortSet.Get(1))\nend\n\nreturn radialList" ) (Script.17 Name: "X-10sion.Install" SourceCode: "'Script: X-10sion.Install\nif (av.GetProject = nil) then\n return nil\nend\ntheProject = av.GetProject\n\nextOptions = Self.Get(0)\nextObjList = Self.Get(1)\n\n'*** add objects to project\nfor each objItem in extObjList\n if (objItem.Is(Doc)) then\n \n theProject.AddDoc(objItem)\n \n elseif (objItem.Is(List)) then\n \n if (objItem.Get(0).Is(Choice)) then\n\n choiceObj = objItem.Get(0)\n choiceIndex = objItem.Get(1)\n menuLabel = objItem.Get(2)\n menuIndex = objItem.Get(3)\n guiName = objItem .Get(4)\n \n guiObj = theProject.FindGUI(guiName)\n if (guiObj = nil) then \n MsgBox.Error(\"The GUI \"+guiName+\" cannot be found in the current project.\",\"X-10sion.Install\")\n return nil\n end\n guiMenuBar = guiObj.GetMenuBar\n menuObj = guiMenuBar.FindByLabel(menuLabel)\n if (menuObj = nil) then\n menuObj = Menu.Make\n menuObj.SetLabel(menuLabel)\n guiMenuBar.Add(menuObj, menuIndex)\n end\n menuObj.add(choiceObj, choiceIndex)\n \n els eif (objItem.Get(0).Is(Button)) then\n \n buttonObj = objItem.Get(0)\n buttonIndex = objItem.Get(1)\n guiName = objItem.Get(2)\n \n guiObj = theProject.FindGUI(guiName)\n if (guiObj = nil) then \n MsgBox.Error(\"The GUI \"+guiName+\" cannot be found in the current project.\",\"X-10sion.Install\")\n return nil\n end\n guiButtonBar = guiObj.GetButtonBar\n guiButtonBar.Add(buttonObj, buttonIndex)\n\n elseif (objItem.Get(0).Is(Tool)) then\n\n toolObj = objItem.G et(0)\n toolIndex = objItem.Get(1)\n guiName = objItem.Get(2)\n \n guiObj = theProject.FindGUI(guiName)\n if (guiObj = nil) then \n MsgBox.Error(\"The GUI \"+guiName+\" cannot be found in the current project.\",\"X-10sion.Install\")\n return nil\n end\n guiToolBar = guiObj.GetToolBar\n guiToolBar.Add(toolObj, toolIndex)\n\n else\n MsgBox.Error(\"Unrecognized object in extension object list\", \"X-10sion.Install\")\n return nil\n end\n \n else\n MsgBox.Error (\"Unrecognized object in extension object list\", \"X-10sion.Install\")\n return nil\n end\nend\n\nif (extOptions.Get(0) <> nil) then\n extOptions.Get(0).DoIt(Self)\nend\n\ntheProject.setmodified(True)" ) (Script.18 Name: "X-10sion.Uninstall" SourceCode: "'*Script: X-10sion.Uninstall\nif (av.GetProject = nil) then\n return nil\nend\ntheProject = av.GetProject\n\nextOptions = Self.Get(0)\nextObjList = Self.Get(1)\n\nif (extOptions.Get(1) <> nil) then\n extOptions.Get(1).DoIt(Self)\nend\n\nfor each objItem in extObjList\n if (objItem.Is(Doc)) then\n \n if (theProject.FindDoc(objItem.GetName) <> nil) then \n if (MsgBox.YesNo(\"Remove document: \"+objItem.GetName+\"?\", \"X-10sion.Uninstall\", True)) then\n theProject.RemoveDoc(objItem)\n end\n end\n \n elsei f (objItem.Is(List)) then\n \n if (objItem.Get(0).Is(Choice)) then\n\n choiceObj = objItem.Get(0)\n menuLabel = objItem.Get(2)\n guiName = objItem.Get(4)\n \n guiObj = theProject.FindGUI(guiName)\n if (guiObj = nil) then \n MsgBox.Warning(\"The docGUI \"\"\"+guiName+\"\"\" has been renamed or removed.\"+NL\n +\"All associated controls cannot be removed.\", \"X-10sion.Uninstall\")\n continue\n end\n guiMenuBar = guiObj.GetMenuBar\n menuObj = guiMenuB ar.FindByLabel(menuLabel)\n if (menuObj = nil) then\n menuName = menuLabel.Substitute(\"&\", \"\")\n MsgBox.Warning(\"The menu \"\"\"+menuName+\"\"\" in docGUI \"\"\"+guiName+\"\"\" has been renamed\"+NL\n +\"or removed. All associated controls cannot be removed.\", \"X-10sion.Uninstall\")\n continue\n end\n menuObj.Remove(choiceObj)\n if (menuObj.GetControls.Count < 1) then\n guiMenuBar.Remove(menuObj)\n end\n \n elseif (objItem.Get(0).Is(Button)) then\n \n buttonObj = objItem.Get(0)\n guiName = objItem.Get(2)\n \n guiObj = theProject.FindGUI(guiName)\n if (guiObj = nil) then \n MsgBox.Warning(\"The docGUI \"\"\"+guiName+\"\"\" has been renamed or removed.\"+NL\n +\"All associated controls cannot be removed.\", \"X-10sion.Uninstall\")\n continue\n end\n guiButtonBar = guiObj.GetButtonBar\n if (guiButtonBar.GetControls.Find(buttonObj) <> nil) then\n guiButtonBar.Remove(buttonObj)\n end\n\n elsei f (objItem.Get(0).Is(Tool)) then\n\n toolObj = objItem.Get(0)\n guiName = objItem.Get(2)\n \n guiObj = theProject.FindGUI(guiName)\n if (guiObj = nil) then \n MsgBox.Warning(\"The docGUI \"\"\"+guiName+\"\"\" has been renamed or removed.\"+NL\n +\"All associated controls cannot be removed.\", \"X-10sion.Uninstall\")\n continue\n end\n guiToolBar = guiObj.GetToolBar\n if (guiToolBar.GetControls.Find(toolObj) <> nil) then\n guiToolBar.Remove(toolObj)\n guiToolBar.SelectDefault\n end\n\n else\n MsgBox.Error(\"Unrecognized object in extension object list\", \"X-10sion.Uninstall\")\n return nil\n end\n \n else\n MsgBox.Error(\"Unrecognized object in extension object list\", \"X-10sion.Uninstall\")\n return nil\n end\nend\n\ntheProject.setmodified(True)" )