darkshark Posted April 10, 2016 Share Posted April 10, 2016 (edited) hi, guys, okay?Can anyone give me a light?I need to sort the coordinates of the vertices of a non-convex polygon, no matter whether it is clockwise, counterclockwise, from where or where it goes, just follow the "path" correctly!I have here the image to exemplify and an array with the coordinates of the polygon in order "not correct". Local $XY[12][3] = [[0,0], [15,0], [15,3], [0,3], [6,3], [9,3], [9,12], [6,12], [0,12], [15,12], [15,15], [0,15]] Here's what I tried to do, I tried to make the arctangent, arctangent 2, order from the center of the box that catches all vertices from the source and nothing has worked, since I drew on paper several times and I can not think in nothing! Local $XY[12][3] = [[0,0], [15,0], [15,3], [0,3], [6,3], [9,3], [9,12], [6,12], [0,12], [15,12], [15,15], [0,15]] _SortCoords($XY) _ArrayDisplay($XY) Func _SortCoords(ByRef $XY) Local $xcenter = (_ArrayMax($XY, 1, -1, -1, 0) - _ArrayMin($XY, 1, -1, -1, 0)) / 2 Local $ycenter = (_ArrayMax($XY, 1, -1, -1, 1) - _ArrayMin($XY, 1, -1, -1, 1)) / 2 For $i = 0 To UBound($XY) -1 $XY[$i][2] = atan2(($ycenter - $XY[$i][1]),($xcenter - $XY[$i][0])) Next EndFunc ;==>_SortCoords Func atan2($y, $x) Return (2 * ATan($y / ($x + Sqrt($x * $x + $y * $y)))) EndFunc If anyone can help me with this I would be immensely gratefulAlready thanks! Edited April 10, 2016 by darkshark Link to comment Share on other sites More sharing options...
UEZ Posted April 10, 2016 Share Posted April 10, 2016 (edited) 13 minutes ago, darkshark said: I need to sort the coordinates of the vertices of a non-convex polygon What do you mean with sorting in this particular case and why you want to sort it? How should the sorted array look like? Edited April 10, 2016 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
darkshark Posted April 10, 2016 Author Share Posted April 10, 2016 (edited) I need the points are ordered because I want to calculate the moment of inertia of the second order, the product of inertia, area, centroid, etc. in this section, this is for structural analysis! I need the coordinates follow a logical order, that part of point 1 (blue) and go to 2,3,4,5,6,7,8,9,10,11 and finish in 12 it is not necessary start from the point 1 may from another point but following the same logic! Edit: Here's The Coordinates of the vertices! Edited April 10, 2016 by darkshark Link to comment Share on other sites More sharing options...
czardas Posted April 10, 2016 Share Posted April 10, 2016 (edited) If the path always turns a corner, then you can set up some rules. One of the coordinates (x or y) must always repeat, but never more than once in a contiguous sequence. That prevents travelling in a straight line. eg between points 3, 4, 11, and 12. Write the code to always turn a corner et voila. You also have to select the coordinates closest to the current position when following these rules, and avoid visiting the same position twice. If the polygon has corners that are not right angles, this approach won't work. Edited April 10, 2016 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
UEZ Posted April 10, 2016 Share Posted April 10, 2016 (edited) I think that's not possible because you don't know how the path between the points is really. If you draw your polygons how you have provided the draw looks like this here: expandcollapse popup#include <Array.au3> #include <GDIPlus.au3> $fScale = 15 _GDIPlus_Startup() Local $XY[13][2] = [[12], [0 * $fScale,0 * $fScale], [15 * $fScale,0 * $fScale], [15 * $fScale,3 * $fScale], [0 * $fScale,3 * $fScale], _ [6 * $fScale,3 * $fScale], [9 * $fScale,3 * $fScale], [9 * $fScale,12 * $fScale], [6 * $fScale,12 * $fScale], _ [0 * $fScale,12 * $fScale], [15 * $fScale,12 * $fScale], [15 * $fScale,15 * $fScale], [0 * $fScale,15 * $fScale]] Local $hGUI = GUICreate("", 300, 300) GUISetState() $hGfx = _GDIPlus_GraphicsCreateFromHWND($hGUI) Local $hPen = _GDIPlus_PenCreate(0xFFFF0000) $hPath = _GDIPlus_PathCreate() $hMatrix = _GDIPlus_MatrixCreate() _GDIPlus_MatrixTranslate($hMatrix, 30, 30) For $i = 1 To $XY[0][0] _GDIPlus_PathAddRectangle($hPath, $XY[$i][0] - 2, $XY[$i][1] - 2, 4, 4) Next _GDIPlus_PathTransform($hPath, $hMatrix) _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen) _GDIPlus_PenSetColor($hPen, 0xFF000000) _GDIPlus_PathReset($hPath) _GDIPlus_PathAddPolygon($hPath, $XY) _GDIPlus_PathTransform($hPath, $hMatrix) _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen) _GDIPlus_MatrixDispose($hMatrix) _GDIPlus_PenDispose($hPen) _GDIPlus_PathDispose($hPath) _GDIPlus_GraphicsDispose($hGfx) _GDIPlus_Shutdown() Do Until GUIGetMsg() = -3 The red squares are the coordinates and the black line represents the polygon. Edited April 10, 2016 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
czardas Posted April 10, 2016 Share Posted April 10, 2016 14 minutes ago, UEZ said: I think that's not possible I agree. I thought I had figured it out, but it just dawned on me now after watching The X Files LOL. There isn't enough information for a general case. You beat me to it. operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
UEZ Posted April 10, 2016 Share Posted April 10, 2016 (edited) I should also watch more X-Files for some "dawn moments". Currently I'm playing also with polygons by trying to transform a 2d world map to a 3d sphere incl. rotating "the world". It runs currently with 2 fps... Edited April 10, 2016 by UEZ czardas 1 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Gianni Posted April 10, 2016 Share Posted April 10, 2016 just out of curiosity I tried to process the given points with the traveling salesman algorithm using and adapting this script by @RTFC , to see what would come out, but the resulting shape is far from the desired one (of course... ) expandcollapse popup; the Travelling Salesman Problem (https://en.wikipedia.org/wiki/Travelling_salesman_problem) ; a Simulated Annealing example (combinatorial minimisation), by RTFC (22 Feb 2016) ; Adapted from Press et al. Numerical Recipes, 2nd ed., pp.438-443. ; Note that the algorithm converges on A local minimum (in terms of the ; user-defined cost-function(s)), which is not necessarily THE global minimum. ; Note also that the search path, duration, and final result may differ from run to run (city coordinates change every time). ; Several parameters and weights can be tweaked to adjust this. #include <Array.au3> #include <GUIConstants.au3> #include <GDIplus.au3> #include <Math.au3> Global Const $GUIwidth = 600 Global Const $GUIheight = 400 Global Const $citysize = 10 Global Const $halfcitysize = $citysize / 2 $hwnd = GUICreate("Travelling Salesman Problem (using Simulated Annealing), by RTFC", $GUIwidth, $GUIheight) GUISetState() ; Load GDI+ resources _GDIPlus_Startup() Global $graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd) Global $bitmap = _GDIPlus_BitmapCreateFromGraphics($GUIwidth, $GUIheight, $graphics) Global $backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap) Global $hPenLine = _GDIPlus_PenCreate(0xFF0000FF, 4) Global $hPenCircle = _GDIPlus_PenCreate(0xFFFF0000, 4) ; Simulated Annealing vars Global $temperat, $path, $kk, $nswap, $nswapstep, $cost, $tempstep, $absimp, $lowestcost ; initialise SRandom(@SEC + @AutoItPID); initialise randomising seed $verbose = True ; T: write regular progress updates to console Local $XY[12][2] = [[0, 0],[15, 0],[15, 3],[0, 3],[6, 3],[9, 3],[9, 12],[6, 12],[0, 12],[15, 12],[15, 15],[0, 15]] ; define cities Global $ncity = UBound($XY) ; 20 ; if $ncity<10 then Exit ; we need something to work with Global $maxcity = $ncity * 50 Global $n[7], $xx[7], $yy[7] ; base-1 indexed Global $x[$ncity + 1], $y[$ncity + 1], $iorder[$ncity + 1], $jorder[$maxcity + 1] ; base-1 indexed ;______START OF ANNEALING ROUTINE____________ $nover = 100 * $ncity ; maximum number of paths at any temperature $nlimit = 10 * $ncity ; maximum number of successful path changes before continuing $nwrite = Int($nover / 5) ; default status update interval if verbose=.t. $tempsteps = 100 ; number of temperature steps to try $tfactor = 0.90 ; annealing schedule: temperature is reduced by this factor after each step $path = 0 While True $temperat = 0.5 ; initial temperature; smaller = more aggressive + more myopic search $absimp = 0 ; counter $nswapstepzero = 0 ; counter ; prep the buffers For $cc = 1 To 6 $n[$cc] = 0 Next For $cc = 0 To $ncity - 1 $x[$cc] = 0.2 + $XY[$cc][0] * 0.020 ; Random() $y[$cc] = 0.2 + $XY[$cc][1] * 0.020 ; Random() $iorder[$cc] = $cc $jorder[$cc] = 0 Next For $cc = $ncity + 1 To $maxcity $jorder[$cc] = 0 Next ; prep the cost vars _CalcPathLength() $initcost = $path $lowestcost = $path ; main loop starts here For $tempstep = 1 To $tempsteps ; try up to N temperature steps $nswap = 0 $nswapstep = 0 For $kk = 1 To $nover $n[1] = Random(1, $ncity, 1) ; choose beginning and end of segment $n[2] = Random(1, $ncity, 1) If $n[2] >= $n[1] Then $n[2] = 1 + Mod(($n[2] + 1), $ncity) ; count number of cities not on segment ($nn) $nn = 1 + Mod(($n[1] - $n[2] + $ncity - 1), $ncity) If $nn < 3 Then ContinueLoop ; decide whether to do a segment transport or reversal (equal chances) $doTransport = (Random() <= 0.5) If $doTransport Then ; try a segment transport $n[3] = $n[2] + Int(Abs($nn - 2) * Random()) + 1 $n[3] = 1 + Mod($n[3] - 1, $ncity) ; transport to a location not on the path _TransportCost() Else ; try a reversal instead _ReversalCost() EndIf ; Listen to the wind, talk to the trees... Switch _AskOracle() Case True $nswap += 1 $path += $cost If $doTransport Then _DoTransport() Else _DoReversal() EndIf If $lowestcost > $path Then $nswapstep += 1 $absimp += 1 $lowestcost = $path EndIf If $nswap >= $nlimit Then ExitLoop EndSwitch Next If $verbose Then _ScreenOut() If $nswapstep = 0 Then $nswapstepzero += 1 If $nswapstepzero = 30 Then ExitLoop ; no more improvements in the last N temperature steps ; reduce temperature = likelihood of following a trajectory away from the nearest LOCAL optimum (in the hope of getting nearer to the GLOBAL optimum) $temperat *= $tfactor Next ; show final result MsgBox($MB_OKCANCEL, "Simulated Annealing Test Result", "Shortest Path Length: " & $lowestcost) Exit WEnd _GDIclose() Exit Func _AskOracle() If $cost < 0 Then Return True Else ; this is where all the magic happens! Return (Random() < Exp(-($cost / $temperat))) EndIf EndFunc ;==>_AskOracle Func _CalcPathLength() $path = 0 ; Global var Local $cc, $index1, $index2 For $cc = 1 To $ncity - 1 $index1 = $iorder[$cc] $index2 = $iorder[$cc + 1] $path += _Distance($x[$index1], $x[$index2], $y[$index1], $y[$index2]) Next $index1 = $iorder[$ncity] ; close the loop by tying path ends together $index2 = $iorder[1] $path += _Distance($x[$index1], $x[$index2], $y[$index1], $y[$index2]) EndFunc ;==>_CalcPathLength Func _Distance($x1, $x2, $y1, $y2) Return Sqrt((($x1 - $x2) ^ 2) + (($y1 - $y2) ^ 2)) EndFunc ;==>_Distance Func _ReversalCost() $n[3] = 1 + Mod(($n[1] + $ncity - 2), $ncity) ; find the city before n[1]... $n[4] = 1 + Mod($n[2], $ncity) ; and after n[2] ; find coordinates of the four cities Local $ii, $jj, $dex For $jj = 1 To 4 $dex = $n[$jj] $ii = $iorder[$dex] $xx[$jj] = $x[$ii] $yy[$jj] = $y[$ii] Next ; calculate the cost of disconnecting the segment at both ends and reconnecting in the opposite order $cost = -_Distance($xx[1], $xx[3], $yy[1], $yy[3]) $cost -= _Distance($xx[2], $xx[4], $yy[2], $yy[4]) $cost += _Distance($xx[1], $xx[4], $yy[1], $yy[4]) $cost += _Distance($xx[2], $xx[3], $yy[2], $yy[3]) EndFunc ;==>_ReversalCost Func _DoReversal() Local $mm = (1 + Mod(($n[2] - $n[1] + $ncity), $ncity)) * .5 Local $ii, $jj, $ll, $itmp For $jj = 1 To $mm $ii = 1 + Mod(($n[1] + $jj - 2), $ncity) $ll = 1 + Mod(($n[2] - $jj + $ncity), $ncity) $itmp = $iorder[$ii] $iorder[$ii] = $iorder[$ll] $iorder[$ll] = $itmp Next EndFunc ;==>_DoReversal Func _TransportCost() $n[4] = 1 + Mod($n[3], $ncity) ; find the city following n[3] $n[5] = 1 + Mod(($n[1] + $ncity - 2), $ncity) ; find the city before n[1]... $n[6] = 1 + Mod($n[2], $ncity) ; and after n[2] ; find coordinates of the six cities Local $jj, $dex For $jj = 1 To 6 $dex = $n[$jj] $ii = $iorder[$dex] $xx[$jj] = $x[$ii] $yy[$jj] = $y[$ii] Next ; calculate the cost of disconnecting the path segment n1->n2, opening a space between n3-n4, connecting the segment in the space, and conencting n5 to n6 $cost = -_Distance($xx[2], $xx[6], $yy[2], $yy[6]) $cost -= _Distance($xx[1], $xx[5], $yy[1], $yy[5]) $cost -= _Distance($xx[3], $xx[4], $yy[3], $yy[4]) $cost += _Distance($xx[1], $xx[3], $yy[1], $yy[3]) $cost += _Distance($xx[2], $xx[4], $yy[2], $yy[4]) $cost += _Distance($xx[5], $xx[6], $yy[5], $yy[6]) EndFunc ;==>_TransportCost Func _DoTransport() Local $m1, $m2, $m3, $pp $m1 = 1 + Mod(($n[2] - $n[1] + $ncity), $ncity) ; find # cities from n1->n2 $m2 = 1 + Mod(($n[5] - $n[4] + $ncity), $ncity) ; find # cities from n4->n5 $m3 = 1 + Mod(($n[3] - $n[6] + $ncity), $ncity) ; find # cities from n6->n3 Local $mm = 1 For $pp = 1 To $m1 $jj = 1 + Mod($pp + $n[1] - 2, $ncity) $jorder[$mm] = $iorder[$jj] $mm += 1 Next For $pp = 1 To $m2 $jj = 1 + Mod($pp + $n[4] - 2, $ncity) $jorder[$mm] = $iorder[$jj] $mm += 1 Next For $pp = 1 To $m3 $jj = 1 + Mod($pp + $n[6] - 2, $ncity) $jorder[$mm] = $iorder[$jj] $mm += 1 Next For $pp = 1 To $ncity $iorder[$pp] = $jorder[$pp] Next EndFunc ;==>_DoTransport Func _ScreenOut() ConsoleWrite("Simulated Annealing. Initial Path length: " & $initcost & @CRLF) ConsoleWrite("Step: " & $tempstep & " of " & $tempsteps & "; Temperature: " & $temperat & @CRLF) ConsoleWrite("Executed Swaps: " & $nswap & "; shortest Path length: " & $lowestcost & @CRLF) ConsoleWrite("Total Improvements: " & $absimp & "; Improvements this step: " & $nswapstep & @CRLF & @CRLF) _DrawTSroute() EndFunc ;==>_ScreenOut Func _DrawTSroute() _GDIPlus_GraphicsClear($backbuffer) For $cc = 1 To $ncity - 1 $index1 = $iorder[$cc] $index2 = $iorder[$cc + 1] _DrawLine($x[$index1], $x[$index2], $y[$index1], $y[$index2]) Next $index1 = $iorder[$ncity] ; close the loop by tying path ends together $index2 = $iorder[1] _DrawLine($x[$index1], $x[$index2], $y[$index1], $y[$index2]) _GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $GUIwidth, $GUIheight) EndFunc ;==>_DrawTSroute Func _DrawLine($x1, $x2, $y1, $y2) Local $x1scaled = Round($GUIwidth * $x1, 0) Local $y1scaled = Round($GUIheight * $y1, 0) Local $x2scaled = Round($GUIwidth * $x2, 0) Local $y2scaled = Round($GUIheight * $y2, 0) _GDIPlus_GraphicsDrawArc($backbuffer, $x1scaled - $halfcitysize, $y1scaled - $halfcitysize, $citysize, $citysize, 0, 360, $hPenCircle) _GDIPlus_GraphicsDrawLine($backbuffer, $x1scaled, $y1scaled, $x2scaled, $y2scaled, $hPenLine) EndFunc ;==>_DrawLine Func _GDIclose() _GDIPlus_PenDispose($hPenLine) _GDIPlus_PenDispose($hPenCircle) _GDIPlus_GraphicsDispose($backbuffer) _GDIPlus_BitmapDispose($bitmap) _GDIPlus_GraphicsDispose($graphics) _GDIPlus_Shutdown() EndFunc ;==>_GDIclose Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
czardas Posted April 10, 2016 Share Posted April 10, 2016 (edited) I think the given case is solvable, but the general case is not. My idea is to always try to turn back the way you came (clockwise or anticlockwise). As soon as you add a few more coordinates though, the problem will acquire multiple solutions and become unsolvable. How to differentiate those patterns which only have one solution (given a set of rules) is unclear to me. The rules are not clearly defined anyway, but it's still interesting. Edited April 10, 2016 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
czardas Posted April 10, 2016 Share Posted April 10, 2016 43 minutes ago, UEZ said: 2 fps Gee that's a bit clunky. operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
darkshark Posted April 10, 2016 Author Share Posted April 10, 2016 Got it, guys, I also was not finding a solution so I decided to ask for help here to see if anyone could help me!But the way I have to think of another way to do it!But anyway, thank you all! @ChimpI loved this script, I had never seen, he makes clear my problem hahaha.@UEZ and @czardasThank you for trying to help me! Link to comment Share on other sites More sharing options...
UEZ Posted April 10, 2016 Share Posted April 10, 2016 (edited) 5 minutes ago, czardas said: Gee that's a bit clunky. Well, that's the limit of AutoIt. Have a look to the alpha version. expandcollapse popup;coded by UEZ build 2016-04-08 #pragma compile(Icon, "c:\Program Files (x86)\AutoIt3\Icons\au3.ico") #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/so /pe /rm #AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_stripped.au3"5 #include <GDIPlus.au3> #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> _GDIPlus_Startup() Global $hGUI, $iFPS = 0, $iShowFPS = 0, $bExit, $i Global Const $iW = 947, $iH = 620, $iWh = $iW / 2, $iHh = $iH / 2, $sTitle = "GDI+ 3D Object Rotation v1.2 alpha" Global Const $fPi = ACos(-1), $fRad = $fPi / 180, $fDeg = 180 / $fPi AutoItSetOption("GUIOnEventMode", 1) GDIPlus_3DRotation() AutoItSetOption("GUIOnEventMode", 0) _GDIPlus_Shutdown() Func GDIPlus_3DRotation() $bExit = False $hGUI = GUICreate($sTitle, $iW, $iH) ;, -1, -1, $WS_POPUP) GUISetState(@SW_SHOW, $hGUI) ;create canvas elements Local Const $hDC = _WinAPI_GetDC($hGUI) Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC) Local Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap) Local Const $hCanvas = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer) _GDIPlus_GraphicsSetSmoothingMode($hCanvas, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsSetPixelOffsetMode($hCanvas, $GDIP_PIXELOFFSETMODE_HIGHQUALITY) Local Const $hBrush_Clr = _GDIPlus_BrushCreateSolid(0xFF303030), _ $hBrush_FPS = _GDIPlus_BrushCreateSolid(0xFFA0A0A0), _ $hBrush_Fill = _GDIPlus_BrushCreateSolid(0xFFFFFFFF), _ $hBrush_Fill2 = _GDIPlus_BrushCreateSolid(0x10FFFFFF), _ $hPen_Line = _GDIPlus_PenCreate(0xFF40B040, 1), _ $hFormat_FPS = _GDIPlus_StringFormatCreate(), _ $hFamily_FPS = _GDIPlus_FontFamilyCreate("Arial"), _ $hFont_FPS = _GDIPlus_FontCreate($hFamily_FPS, 8), _ $tLayout_FPS = _GDIPlus_RectFCreate(0, 0, 60, 16) _GDIPlus_PenSetLineJoin($hPen_Line, 2) $iFPS = 0 Local Const $hPath = _GDIPlus_PathCreate(), $sPolygon = BinaryToString(_Polygons()) Add_Polygon($sPolygon, $hPath) Local $aData = _GDIPlus_PathGetData($hPath) ConsoleWrite($aData[0][0] & @CRLF) Local $aSphere = CreateSphere($aData, $iWh, $iHh, 130) Local $iAmountDots = $aSphere[0], $tCoords = $aSphere[1], $tTypes = $aSphere[2] Local $fRotX = 0 * $fDeg, $fRotY = 0, $fRotZ = 10 * $fDeg, $iFillMode = 0, $i Local $tPoints = DllStructCreate("float dots[" & 2 * $iAmountDots & "]") GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_About") AdlibRegister("CalcFPS", 1000) Do DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush_Clr, "float", 0, "float", 0, _ "float", $iW, "float", $iH) ;erase canvas background For $i = 1 To $iAmountDots Translate3Dto2D($tCoords, $i, $fRotX, $fRotY, $fRotY - $fRotX, $iWh, $iHh, 1000) $tPoints.dots((2 * $i - 1)) = $tCoords.fX(($i)) $tPoints.dots((2 * $i)) = $tCoords.fY(($i)) Next $hPath2 = DllCall($__g_hGDIPDll, "int", "GdipCreatePath2", "struct*", $tPoints, "struct*", $tTypes, "int", $iAmountDots, "int", $iFillMode, "handle*", 0)[5] DllCall($__g_hGDIPDll, "int", "GdipFillPath", "handle", $hCanvas, "handle", $hBrush_Fill2, "handle", $hPath) DllCall($__g_hGDIPDll, "int", "GdipFillPath", "handle", $hCanvas, "handle", $hBrush_Fill, "handle", $hPath2) DllCall($__g_hGDIPDll, "int", "GdipDrawPath", "handle", $hCanvas, "handle", $hPen_Line, "handle", $hPath2) DllCall($__g_hGDIPDll, "int", "GdipDeletePath", "handle", $hPath2) $fRotX += 0.025 $fRotY += 0.033 _GDIPlus_GraphicsDrawStringEx($hCanvas, "FPS: " & $iShowFPS, $hFont_FPS, $tLayout_FPS, $hFormat_FPS, $hBrush_FPS) ;draw background message text _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hDC_backbuffer, 0, 0, $SRCCOPY) ;blit drawn bitmap to GUI $iFPS += 1 If $bExit Then ExitLoop Until Not Sleep(10) AdlibUnRegister("CalcFPS") ;release resources _GDIPlus_PathDispose($hPath) _GDIPlus_PathDispose($hPath2) _GDIPlus_FontDispose($hFont_FPS) _GDIPlus_FontFamilyDispose($hFamily_FPS) _GDIPlus_StringFormatDispose($hFormat_FPS) _GDIPlus_BrushDispose($hBrush_Clr) _GDIPlus_BrushDispose($hBrush_FPS) _GDIPlus_BrushDispose($hBrush_Fill) _GDIPlus_BrushDispose($hBrush_Fill2) _GDIPlus_PenDispose($hPen_Line) _GDIPlus_GraphicsDispose($hCanvas) _WinAPI_SelectObject($hDC_backbuffer, $DC_obj) _WinAPI_DeleteDC($hDC_backbuffer) _WinAPI_DeleteObject($hHBitmap) _WinAPI_ReleaseDC($hGUI, $hDC) GUIDelete($hGUI) EndFunc ;==>GDIPlus_3DRotation Func Translate3Dto2D(ByRef $tStruct, $iPos, $fRotX, $fRotY, $fRotZ, $fCenterX = 0, $fCenterY = 0, $fZDeepCorrection = 1000) Local Const $fCosRotX = Cos($fRotX), $fSinRotX = Sin($fRotX), _ $fCosRotY = Cos($fRotY), $fSinRotY = Sin($fRotY), _ $fCosRotZ = Cos($fRotZ), $fSinRotZ = Sin($fRotZ), _ $f1 = $fCosRotY * $tStruct.x(($iPos)), _ $f2 = $fSinRotX * $tStruct.y(($iPos)), _ $f3 = $fCosRotX * $tStruct.z(($iPos)), _ $f4 = $fCosRotX * $tStruct.y(($iPos)), _ $f5 = $fSinRotX * $tStruct.z(($iPos)), _ $f6 = $f1 - $fSinRotY * ($f2 + $f3), _ $fXPos = $fCosRotZ * $f6 - $fSinRotZ * ($f4 - $f5), _ $fYPos = $fSinRotZ * $f6 + $fCosRotZ * ($f4 - $f5), _ $fZPos = $fSinRotY * $tStruct.x(($iPos)) + $fCosRotY * ($f2 + $f3), _ $fZPerspCorrection = 1 / ($fZPos / $fZDeepCorrection + 1) $tStruct.fX(($iPos)) = $fXPos * $fZPerspCorrection + $fCenterX $tStruct.fY(($iPos)) = $fYPos * $fZPerspCorrection + $fCenterY EndFunc ;==>Translate3Dto2D Func _Exit_About() $bExit = True EndFunc ;==>_Exit_About Func CalcFPS() ;display FPS $iShowFPS = $iFPS $iFPS = 0 EndFunc ;==>CalcFPS Func CreateSphere($aData, $iWh, $iHh, $fRadius = 200) Local $iAmountDots = $aData[0][0] Local $tCoords = DllStructCreate("struct;float x[" & $iAmountDots & "];float y[" & $iAmountDots & "];float z[" & $iAmountDots & "];float fX[" & $iAmountDots & "];float fY[" & $iAmountDots & "];float fZ[" & $iAmountDots & "];endstruct") Local $tTypes = DllStructCreate("byte type[" & $iAmountDots & "]") Local $i, $fLongitude, $fLatitude For $i = 1 To $iAmountDots $fLongitude = ($iWh - $aData[$i][0]) / $fRadius $fLatitude = 2 * ATan(2.718281828^(($iHh - $aData[$i][1]) / $fRadius)) - ($fPi / 2) $tCoords.x(($i)) = $fRadius * Cos($fLatitude) * Cos($fLongitude) $tCoords.y(($i)) = $fRadius * Cos($fLatitude) * Sin($fLongitude) $tCoords.z(($i)) = $fRadius * Sin($fLatitude) $tTypes.type(($i)) = $aData[$i][2] Next Local $aResult[3] = [$iAmountDots, $tCoords, $tTypes] Return $aResult EndFunc Func Add_Polygon($sPolygon, $hPath, $fScale = 1.0) Local $aPolygons = StringRegExp($sPolygon, "(?mi)polygon\((.*)\)", 3), $i, $j, $k, $aPolygon, $tPoints For $i = 0 To UBound($aPolygons) - 1 $aPolygon = StringRegExp($aPolygons[$i], "\d*\.?\d+", 3) $tPoints = DllStructCreate("float coordinates[" & UBound($aPolygon) & "]") $k = 1 For $j = 0 To UBound($aPolygon) - 2 Step 2 $tPoints.coordinates((2 * $k - 1)) = $aPolygon[$j] * $fScale $tPoints.coordinates((2 * $k)) = $aPolygon[$j + 1] * $fScale $k += 1 Next DllCall($__g_hGDIPDll, "int", "GdipAddPathPolygon", "handle", $hPath, "struct*", $tPoints, "int", UBound($aPolygon) / 2) $tPoints = 0 Next EndFunc ;Code below was generated by: 'File to Base64 String' Code Generator v1.20 Build 2015-09-19 Func _Polygons($bSaveBinary = False, $sSavePath = @ScriptDir) Local $Polygons $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= 'CrwGBslmOJlACiA1wD1ACDg2QW+7gFfBAjKAKMAFQSg3QRtVxQI1wQI4wgs3QUg2f0BgwQtBfsACwQjDDgNBOGeBOsALATc4MwA3xQsy3UB+NkNnwAjABTjDDoAWqCA2MkJgOQFdNQAl5cECMMALNTXDFMksxQJDCTUACzMgNDZCbjj3ADyADwIROEBcBTgAFwAOt8QCAJMFODmCvYBULACy+UDCIDVALcECwB5AAUFcnDUwwIFAE4FiNTCABHvBGkFiOUCBwRoBJsARMfuASMMUNcEIANfBAsG/wBH7AT7AIDLBEcIgwRrAEYF378kvxgIKOEF5NcOPABRCXm9GTEBPAg4BNTZAGwMgNPdBWwImYVQ2w2egbCI44gW/gRdgCuIC6QtlAQgQNYAZqDggM2JjNQAeNQB2f6IkgRmgWIEIZAFgO2EBNefgBaAYoSo0MwAKZQHhXW9gBIAXYQGgJzLjAsFDNP+iJGEHoCRkAekOZQEJE6A4uDQgM8IxZAHCMTUhOruBCKAhNcFRYQGBDjbhVn+ACEAwZAFkB2FvZQFBOTN/4EJhAUE54AJiCm4NC581faAvMgEHIRqgL4IRYUY29SIXOaIYNqQnYgSEDmIEv8F1YAGCFOkIZQEJDTcBl3IzYjo1NyAoYQEBBzflgZMz4j41NyGdAArBKP9gAQIQ4gJiB4JTYQGAEQKo/2sKZQGJDsJ2IGiBCGABgET9gk01QIFgAWK6AQ2CSiId/aC0IKEQYQFBgaENhRRgjK2CDjFhAWNAN8KFNaIh30CNwIXgiuELws85Yw3gGf/Bi+EFQ4FpASCrYxPpFGMB28o0QYE3oqTBLjlhAQIW9+FEoA0iIzIAE2CJAQqAFOwxIOByRDY2ZgFBNmAEz4EagGrmBWAVMyAgDyEp/2MBAMhhBGIKom9rEGUBiBSaNqE4IOC6AA02MwLQ+eKDNjNgD2UBYNogzoJZXDYyARmAwiAmNuDjOM4goMUAEGEBNCDhbPMC/DMgQG2QEfsFtQAJCAAz6xBsQk828SogsGiBBvEq+7EAhAk5AQVBB2B0QAcSENg2MzSBBrQANUAKcHkv8gIRZHABEBM2ID8wILdQC3EBEUEgkAqQFzbgQu8AC7MGMAJwbzlzAfgItgDvCgtwLFUP4EY1QQcBCHBJ/wAFkxGBWEEHwQUiPDQCswD5glQ2NYIMkl87BbUASAfuN1E9kHmBAzfQCsB8kg7+NxAN0HdgELMA4X9zASCVviAACaAAwBAgAqIkN4AU3VAdMMENtABSaDfxjLEA6/AHtAA4wRA3sDmwCCJx/jfxO7EL8QKAF+AI4nekCe+CPrEGsACCPjewP1GPOAL/4wu2APkNkW5FChFwhQNwUb+xigILsD9gKPJVsQAx8A3T4QIgAjIgEi43MXVQAf9RDFJiAkK7BbUAzAfQGqAO/wECUWRQDpETQhTQD/IE8TD/IyWBFiIoxArSHUEJegS1ANWIBjgyLTNBCTiQFTAEpcEfOKA2NCBSgjhgoew3IJKJUQE5AAxwCGED/xBLswIxELJLygSkAGkq4FL/MFewnoEvwACAWXAPgSegQfNQV9MYNjexPaG3wTpgAr4zwACDM9BEAASUMDjyaf/wQMQAAwQyA+EXoQWxLjADv5ABwKLCABwIxABICjJgLrtQEMFRLEAXwwCSJzLAM3egOsAAkAQyYhFhAhALMv8gNpAYsG4xAxNAwG4xA2Q//eJZMpASwQCgGpMB0RtSaq4yYB2RAVIOMhKEMuCn/YANMqB/QBtRaZMB0B8AWtuRAcIyMlBjsAwyYSDAAP+CIS8MwwBZDhAvoUnCeKEI/wEjYhXBAOELwmthAsEDAwf/8CZACpcBCATGADkGAY7CA/9hCAGJwAACU5EBAVAif8EA/2EFcww7A8YAagUgw6IOMgn/QSB1D5GWkgTxFWACAQfyxf4yIDEAClFrkwEIBMYAOgb/MTmRB/ICMbBxDwIK4kezd/oyok4yQUCj' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= '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' $Polygons &= 'OQIMMgMM9QEzMgMZNgRaAmcKgQYMACk=' $Polygons = _WinAPI_Base64Decode($Polygons) If @error Then Return SetError(1, 0, 0) Local $tSource = DllStructCreate('byte[' & BinaryLen($Polygons) & ']') DllStructSetData($tSource, 1, $Polygons) Local $tDecompress _WinAPI_LZNTDecompress($tSource, $tDecompress, 69852) If @error Then Return SetError(3, 0, 0) $tSource = 0 Local Const $bString = Binary(DllStructGetData($tDecompress, 1)) If $bSaveBinary Then Local Const $hFile = FileOpen($sSavePath & "\Polygon.txt", 18) If @error Then Return SetError(2, 0, $bString) FileWrite($hFile, $bString) FileClose($hFile) EndIf Return $bString EndFunc ;==>_Polygons Func _WinAPI_Base64Decode($sB64String) Local $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0) If @error Or Not $aCrypt[0] Then Return SetError(1, 0, "") Local $bBuffer = DllStructCreate("byte[" & $aCrypt[5] & "]") $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "struct*", $bBuffer, "dword*", $aCrypt[5], "ptr", 0, "ptr", 0) If @error Or Not $aCrypt[0] Then Return SetError(2, 0, "") Return DllStructGetData($bBuffer, 1) EndFunc ;==>_WinAPI_Base64Decode Func _WinAPI_LZNTDecompress(ByRef $tInput, ByRef $tOutput, $iBufferSize) $tOutput = DllStructCreate("byte[" & $iBufferSize & "]") If @error Then Return SetError(1, 0, 0) Local $aRet = DllCall("ntdll.dll", "uint", "RtlDecompressBuffer", "ushort", 0x0002, "struct*", $tOutput, "ulong", $iBufferSize, "struct*", $tInput, "ulong", DllStructGetSize($tInput), "ulong*", 0) If @error Then Return SetError(2, 0, 0) If $aRet[0] Then Return SetError(3, $aRet[0], 0) Return $aRet[6] EndFunc ;==>_WinAPI_LZNTDecompress The background map is the original map saved as polygons. The rotating world is the transformation of that map. Edited April 10, 2016 by UEZ Danyfirex, Gianni and czardas 3 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
czardas Posted April 10, 2016 Share Posted April 10, 2016 (edited) @UEZ that's beautiful. Edited April 10, 2016 by czardas UEZ 1 operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
darkshark Posted April 10, 2016 Author Share Posted April 10, 2016 Wow, that's Fantastic, UEz *-* Link to comment Share on other sites More sharing options...
InunoTaishou Posted April 10, 2016 Share Posted April 10, 2016 I just... I don't even know how you do what you do UEZ Lol 4-5 fps on my computer. Link to comment Share on other sites More sharing options...
jchd Posted April 10, 2016 Share Posted April 10, 2016 @darkshark, There is of course no unique "solution" to the question asked, at least in the general case (even as simple as your I-beam). To convince you, try to persuade yourself that the "most logical path" could well be the following (code freely borrowed to UEZ): expandcollapse popup#include <Array.au3> #include <GDIPlus.au3> Local $nPoints = 12 Local $fScale = 20 _GDIPlus_Startup() Local $XY[$nPoints + 1][2] = [ _ [$nPoints], _ [ 0, 0], _ [15, 0], _ [ 9, 3], _ [15, 3], _ [ 9, 12], _ [15, 12], _ [15, 15], _ [ 0, 15], _ [ 6, 12], _ [ 0, 12], _ [ 6, 3], _ [ 0, 3] _ ] For $i = 1 To $nPoints $XY[$i][0] = $XY[$i][0] * $fScale + 50 $XY[$i][1] = $XY[$i][1] * $fScale + 50 Next Local $hGUI = GUICreate("", 20 * $fScale + 25, 20 * $fScale + 25) GUISetState() $hGfx = _GDIPlus_GraphicsCreateFromHWND($hGUI) Local $hPen = _GDIPlus_PenCreate(0xFFFF0000) $hPath = _GDIPlus_PathCreate() $hMatrix = _GDIPlus_MatrixCreate() ;~ _GDIPlus_MatrixTranslate($hMatrix, 30, 30) For $i = 1 To $nPoints _GDIPlus_PathAddRectangle($hPath, $XY[$i][0] - 2, $XY[$i][1] - 2, 4, 4) Next _GDIPlus_PathTransform($hPath, $hMatrix) _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen) _GDIPlus_PenSetColor($hPen, 0xFF000000) _GDIPlus_PathReset($hPath) _GDIPlus_PathAddPolygon($hPath, $XY) _GDIPlus_PathTransform($hPath, $hMatrix) _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen) _GDIPlus_MatrixDispose($hMatrix) _GDIPlus_PenDispose($hPen) _GDIPlus_PathDispose($hPath) _GDIPlus_GraphicsDispose($hGfx) _GDIPlus_Shutdown() Do Until GUIGetMsg() = -3 Even with simples vertice clouds, there are many possible variations, each of them being as "logical" or plausible than the others. Note that the section area is bigger in my example than the original I-beam, hence section area is not a valid criterion. Possible very dangerous structures could be built from most variants. This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
RTFC Posted April 11, 2016 Share Posted April 11, 2016 9 hours ago, Chimp said: tried to process the given points with the traveling salesman algorithm That approach might work, but you'd have to adjust the cost functions to define the desired result as the optimum to be achieved. Off the top of my head (without trying), I'd say, maybe impose additional cost conditions (for this particular case!) of every vertex angle being 90 degrees, and minimising total enclosed surface area. Defining appropriate cost functions is always the hardest part. My Contributions and Wrappers Spoiler BitMaskSudokuSolver BuildPartitionTable CodeCrypter CodeScanner DigitalDisplay Eigen4AutoIt FAT Suite HighMem MetaCodeFileLibrary OSgrid Pool RdRand SecondDesktop SimulatedAnnealing Xbase I/O Link to comment Share on other sites More sharing options...
RTFC Posted April 11, 2016 Share Posted April 11, 2016 (edited) It would look something like this (with thanks to Chimp for the initial adaptation): expandcollapse popup#include <Array.au3> #include <GUIConstants.au3> #include <GDIplus.au3> #include <Math.au3> Global Const $GUIwidth = 600 Global Const $GUIheight = 400 Global Const $citysize = 10 Global Const $halfcitysize = $citysize / 2 $hwnd = GUICreate("Straight-Angle Travelling Salesman Problem (using Simulated Annealing), by RTFC", $GUIwidth, $GUIheight) GUISetState() ; Load GDI+ resources _GDIPlus_Startup() Global $graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd) Global $bitmap = _GDIPlus_BitmapCreateFromGraphics($GUIwidth, $GUIheight, $graphics) Global $backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap) Global $hPenLine = _GDIPlus_PenCreate(0xFF0000FF, 4) Global $hPenCircle = _GDIPlus_PenCreate(0xFFFF0000, 4) ; Simulated Annealing vars Global $temperat, $path, $kk, $nswap, $nswapstep, $cost, $tempstep, $absimp, $lowestcost ; initialise SRandom(@MSEC + @AutoItPID); initialise randomising seed $verbose = True ; T: write regular progress updates to console ; define cities Global $XY[12][2] = [[0, 0],[15, 0],[15, 3],[0, 3],[6, 3],[9, 3],[9, 12],[6, 12],[0, 12],[15, 12],[15, 15],[0, 15]] Global $ncity = UBound($XY) ; 20 Global $wrongAnglePenalty=10 Global $maxcity = $ncity * 50 Global $n[7], $xx[7], $yy[7] ; base-1 indexed Global $x[$ncity + 1], $y[$ncity + 1], $iorder[$ncity + 1], $jorder[$maxcity + 1] ; base-1 indexed ;______START OF ANNEALING ROUTINE____________ $nover = 100 * $ncity ; maximum number of paths at any temperature $nlimit = 10 * $ncity ; maximum number of successful path changes before continuing $nwrite = Int($nover / 5) ; default status update interval if verbose=.t. $tempsteps = 100 ; number of temperature steps to try $tfactor = 0.90 ; annealing schedule: temperature is reduced by this factor after each step $path = 0 While True $temperat = 0.5 ; initial temperature; smaller = more aggressive + more myopic search $absimp = 0 ; counter $nswapstepzero = 0 ; counter ; prep the buffers For $cc = 1 To 6 $n[$cc] = 0 Next For $cc = 0 To $ncity - 1 $x[$cc] = 0.2 + $XY[$cc][0] * 0.020 ; Random() $y[$cc] = 0.2 + $XY[$cc][1] * 0.020 ; Random() $iorder[$cc] = $cc $jorder[$cc] = 0 Next For $cc = $ncity + 1 To $maxcity $jorder[$cc] = 0 Next ; prep the cost vars $path=_CalcPathLength() $prevpath=$path $initcost = $path $lowestcost = $path ; main loop starts here For $tempstep = 1 To $tempsteps ; try up to N temperature steps $nswap = 0 $nswapstep = 0 For $kk = 1 To $nover $n[1] = Random(1, $ncity, 1) ; choose beginning and end of segment $n[2] = Random(1, $ncity, 1) If $n[2] >= $n[1] Then $n[2] = 1 + Mod(($n[2] + 1), $ncity) ; count number of cities not on segment ($nn) $nn = 1 + Mod(($n[1] - $n[2] + $ncity - 1), $ncity) If $nn < 3 Then ContinueLoop ; store original situation $oldiorder=$iorder $oldjorder=$jorder ; decide whether to do a segment transport or reversal (equal chances) $doTransport = (Random() <= 0.5) If $doTransport Then ; try a segment transport $n[3] = $n[2] + Int(Abs($nn - 2) * Random()) + 1 $n[3] = 1 + Mod($n[3] - 1, $ncity) ; transport to a location not on the path _DoTransport() Else _DoReversal() EndIf $cost=_CalcPathLength()-$prevpath ; Listen to the wind, talk to the trees... Switch _AskOracle() Case True $nswap += 1 $path += $cost $prevpath=$path If $lowestcost > $path Then $nswapstep += 1 $absimp += 1 $lowestcost = $path EndIf If $nswap >= $nlimit Then ExitLoop case Else ;restore $path=$prevpath $iorder=$oldiorder $jorder=$oldjorder EndSwitch Next If $verbose Then _ScreenOut() If $nswapstep = 0 Then $nswapstepzero += 1 If $nswapstepzero = 30 Then ExitLoop ; no more improvements in the last N temperature steps ; reduce temperature = likelihood of following a trajectory away from the nearest LOCAL optimum (in the hope of getting nearer to the GLOBAL optimum) $temperat *= $tfactor Next ; show final result MsgBox($MB_OKCANCEL, "Simulated Annealing Test Result", "Shortest Path Length: " & $lowestcost) Exit WEnd _GDIclose() Exit Func _AskOracle() If $cost < 0 Then Return True Else ; this is where all the magic happens! Return (Random() < Exp(-($cost / $temperat))) EndIf EndFunc ;==>_AskOracle Func _CalcPathLength() Local $path = 0 Local $cc, $index1, $index2 For $cc = 1 To $ncity - 1 $index1 = $iorder[$cc] $index2 = $iorder[$cc + 1] $path += _Distance($x[$index1], $x[$index2], $y[$index1], $y[$index2]) Next $index1 = $iorder[$ncity] ; close the loop by tying path ends together $index2 = $iorder[1] $path += _Distance($x[$index1], $x[$index2], $y[$index1], $y[$index2]) For $cc = 1 To $ncity - 2 $index1 = $iorder[$cc] $index2 = $iorder[$cc + 1] $index3 = $iorder[$cc + 2] Switch $x[$index1]=$x[$index2] case True Switch $y[$index1]<>$y[$index2] case False $path += $wrongAnglePenalty EndSwitch case Else Switch $y[$index1]=$y[$index2] case False $path += $wrongAnglePenalty EndSwitch EndSwitch Switch $x[$index2]=$x[$index3] case True Switch $y[$index2]<>$y[$index3] case False $path += $wrongAnglePenalty EndSwitch case Else Switch $y[$index2]=$y[$index3] case False $path += $wrongAnglePenalty EndSwitch EndSwitch If $x[$index1]=$x[$index2] And $x[$index2]=$x[$index3] Then $path += $wrongAnglePenalty If $y[$index1]=$y[$index2] And $y[$index2]=$y[$index3] Then $path += $wrongAnglePenalty Next $index1 = $iorder[$ncity-1] $index2 = $iorder[$ncity] $index3 = $iorder[1] Switch $x[$index1]=$x[$index2] case True Switch $y[$index1]<>$y[$index2] case False $path += $wrongAnglePenalty EndSwitch case Else Switch $y[$index1]=$y[$index2] case False $path += $wrongAnglePenalty EndSwitch EndSwitch Switch $x[$index2]=$x[$index3] case True Switch $y[$index2]<>$y[$index3] case False $path += $wrongAnglePenalty EndSwitch case Else Switch $y[$index2]=$y[$index3] case False $path += $wrongAnglePenalty EndSwitch EndSwitch If $x[$index1]=$x[$index2] And $x[$index2]=$x[$index3] Then $path += $wrongAnglePenalty If $y[$index1]=$y[$index2] And $y[$index2]=$y[$index3] Then $path += $wrongAnglePenalty $index1 = $iorder[$ncity] $index2 = $iorder[1] $index3 = $iorder[2] Switch $x[$index1]=$x[$index2] case True Switch $y[$index1]<>$y[$index2] case False $path += $wrongAnglePenalty EndSwitch case Else Switch $y[$index1]=$y[$index2] case False $path += $wrongAnglePenalty EndSwitch EndSwitch Switch $x[$index2]=$x[$index3] case True Switch $y[$index2]<>$y[$index3] case False $path += $wrongAnglePenalty EndSwitch case Else Switch $y[$index2]=$y[$index3] case False $path += $wrongAnglePenalty EndSwitch EndSwitch If $x[$index1]=$x[$index2] And $x[$index2]=$x[$index3] Then $path += $wrongAnglePenalty If $y[$index1]=$y[$index2] And $y[$index2]=$y[$index3] Then $path += $wrongAnglePenalty return $path EndFunc ;==>_CalcPathLength Func _Distance($x1, $x2, $y1, $y2) Return Sqrt((($x1 - $x2) ^ 2) + (($y1 - $y2) ^ 2)) EndFunc ;==>_Distance Func _DoReversal() $n[3]=1+Mod(($n[1]+$ncity-2),$ncity) ; find the city before n[1]... $n[4]=1+Mod($n[2],$ncity) ; and after n[2] ; find coordinates of the four cities local $ii,$jj,$dex For $jj=1 to 4 $dex=$n[$jj] $ii=$iorder[$dex] $xx[$jj]=$x[$ii] $yy[$jj]=$y[$ii] Next Local $mm = (1 + Mod(($n[2] - $n[1] + $ncity), $ncity)) * .5 Local $ii, $jj, $ll, $itmp For $jj = 1 To $mm $ii = 1 + Mod(($n[1] + $jj - 2), $ncity) $ll = 1 + Mod(($n[2] - $jj + $ncity), $ncity) $itmp = $iorder[$ii] $iorder[$ii] = $iorder[$ll] $iorder[$ll] = $itmp Next EndFunc ;==>_DoReversal Func _DoTransport() $n[4]=1+Mod($n[3],$ncity) ; find the city following n[3] $n[5]=1+Mod(($n[1]+$ncity-2),$ncity) ; find the city before n[1]... $n[6]=1+Mod($n[2],$ncity) ; and after n[2] ; find coordinates of the six cities local $jj,$dex For $jj=1 to 6 $dex=$n[$jj] $ii=$iorder[$dex] $xx[$jj]=$x[$ii] $yy[$jj]=$y[$ii] Next Local $m1, $m2, $m3, $pp $m1 = 1 + Mod(($n[2] - $n[1] + $ncity), $ncity) ; find # cities from n1->n2 $m2 = 1 + Mod(($n[5] - $n[4] + $ncity), $ncity) ; find # cities from n4->n5 $m3 = 1 + Mod(($n[3] - $n[6] + $ncity), $ncity) ; find # cities from n6->n3 Local $mm = 1 For $pp = 1 To $m1 $jj = 1 + Mod($pp + $n[1] - 2, $ncity) $jorder[$mm] = $iorder[$jj] $mm += 1 Next For $pp = 1 To $m2 $jj = 1 + Mod($pp + $n[4] - 2, $ncity) $jorder[$mm] = $iorder[$jj] $mm += 1 Next For $pp = 1 To $m3 $jj = 1 + Mod($pp + $n[6] - 2, $ncity) $jorder[$mm] = $iorder[$jj] $mm += 1 Next For $pp = 1 To $ncity $iorder[$pp] = $jorder[$pp] Next EndFunc ;==>_DoTransport Func _ScreenOut() ConsoleWrite("Simulated Annealing. Initial Path length: " & $initcost & @CRLF) ConsoleWrite("Step: " & $tempstep & " of " & $tempsteps & "; Temperature: " & $temperat & @CRLF) ConsoleWrite("Executed Swaps: " & $nswap & "; shortest Path length: " & $lowestcost & @CRLF) ConsoleWrite("Total Improvements: " & $absimp & "; Improvements this step: " & $nswapstep & @CRLF & @CRLF) _DrawTSroute() EndFunc ;==>_ScreenOut Func _DrawTSroute() _GDIPlus_GraphicsClear($backbuffer) For $cc = 1 To $ncity - 1 $index1 = $iorder[$cc] $index2 = $iorder[$cc + 1] _DrawLine($x[$index1], $x[$index2], $y[$index1], $y[$index2]) Next $index1 = $iorder[$ncity] ; close the loop by tying path ends together $index2 = $iorder[1] _DrawLine($x[$index1], $x[$index2], $y[$index1], $y[$index2]) _GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $GUIwidth, $GUIheight) EndFunc ;==>_DrawTSroute Func _DrawLine($x1, $x2, $y1, $y2) Local $x1scaled = Round($GUIwidth * $x1, 0) Local $y1scaled = Round($GUIheight * $y1, 0) Local $x2scaled = Round($GUIwidth * $x2, 0) Local $y2scaled = Round($GUIheight * $y2, 0) _GDIPlus_GraphicsDrawArc($backbuffer, $x1scaled - $halfcitysize, $y1scaled - $halfcitysize, $citysize, $citysize, 0, 360, $hPenCircle) _GDIPlus_GraphicsDrawLine($backbuffer, $x1scaled, $y1scaled, $x2scaled, $y2scaled, $hPenLine) EndFunc ;==>_DrawLine Func _GDIclose() _GDIPlus_PenDispose($hPenLine) _GDIPlus_PenDispose($hPenCircle) _GDIPlus_GraphicsDispose($backbuffer) _GDIPlus_BitmapDispose($bitmap) _GDIPlus_GraphicsDispose($graphics) _GDIPlus_Shutdown() EndFunc ;==>_GDIclose Of course, the new cost function as crudely implemented here is favouring right angles and non-overlapping line segments as additional constraints (through var $wrongAnglePenalty). A more general solution to close polygons would need more sophisticated cost functions. The problem is how to define a generic optimal solution; that'll still depend on your specific requirements. So this specific solution won't work for angles other than 90/270 degrees, for example. Edited April 15, 2016 by RTFC typo Gianni 1 My Contributions and Wrappers Spoiler BitMaskSudokuSolver BuildPartitionTable CodeCrypter CodeScanner DigitalDisplay Eigen4AutoIt FAT Suite HighMem MetaCodeFileLibrary OSgrid Pool RdRand SecondDesktop SimulatedAnnealing Xbase I/O Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now