Nutz mal als Editor >>Scite4AutoIt<<.
Dort einfach mal Strg-F5 bzw. Strg-T drücken und du weißt sofort das ein "Then" fehlt.
Beiträge von AspirinJunkie
-
-
Nimm eine eigene Funktion welche die AutoIt-Regfunktionen nutzt.
Dann sollte auch die Sache mit "HKLM64" funktionieren.Beispiel:
Spoiler anzeigen
[autoit]#include <Array.au3>
[/autoit] [autoit][/autoit] [autoit]$reg_schluessel100 = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages"
[/autoit] [autoit][/autoit] [autoit]$subkeys = _GetRegSubKeys($reg_schluessel100)
[/autoit] [autoit][/autoit] [autoit]
_ArrayDisplay($subkeys); by AspirinJunkie
[/autoit] [autoit][/autoit] [autoit]
; needs .Net
Func _GetRegSubKeys($HKEY)
Local $iCount = 1, $sSubKey
Local $cRetQueue = ObjCreate("System.Collections.Queue")
If @error Then Return SetError(1, 0, -1)While 1
[/autoit]
$sSubKey = RegEnumKey($HKEY, $iCount)
If @error <> 0 Then ExitLoop
$iCount += 1
$cRetQueue.Enqueue($sSubKey)
WEnd
Return $cRetQueue.ToArray
EndFunc -
-
Wo definierst du die Variable $ij ?
Wenn du dafür $j meintest dann kommt es unweigerlich zum Überlauf da die Zeilennummer ja nicht größer werden kann als die Gesamtanzahl der Zeilen (_FileCountLines).
Das wäre aber der Fall da du auf $i immer etwas addierst und das würde die Grenzen der Datei überschreiten.Edit: Ich muss mich korrigieren - wenn $file nicht der kamera_jpg.txt entspricht könnte es theoretisch klappen aber ich denk mal es ist wirklich nur der Fehler das die 100000 nicht abgezogen wurden.
-
SEuBo
Eigentlich mag ich Kollektiv-Bashing nicht wirklich aber das Ding hat echt Niveau -
[autoit]
$line = FileReadLine ($file, $i)
[/autoit]
Das wär dann ab Zeile 100000 im kleinsten Fall.
Denke mal da musst du die 100000 wieder abziehen sonst kann ich mir das schwer vorstellen. -
Das Problem ist das es extrem viele Bilder sind [...], d.h das Array wird ziemlich gross, was mein Computer glaube ich nicht speichern kann, bzw Verarbeiten kann. Gibt es nicht ne möglichkeit die Bilder direkt zu kopieren?
Ich glaube zwar weniger das das Array dermaßen groß wird aber natürlich gibt es eine spezielle Lösung für diesen Fall.
Wenn es tatsächlich nur eine Verzeichnisebene gibt dann lässt sich das z.B. der Einfachheit halber folgendermaßen lösen:Spoiler anzeigen
[autoit]MoveFilePics("E:\Temp\Test", "C:\Windows")
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Func MoveFilePics($sStartdir, $sTargDir)
[/autoit] [autoit][/autoit] [autoit]
Local $iFFFFDirs, $iFFFFFiles, $sFFNFDirs, $sFFNFFiles, $iCounter = 1If StringRight($sStartdir, 1) = '\' Then $sStartdir = StringTrimRight($sStartdir, 1)
[/autoit] [autoit][/autoit] [autoit]
If Not FileExists($sStartdir) Then Return SetError(1, 0, 0)$iFFFFDirs = FileFindFirstFile($sStartdir & '\*')
[/autoit] [autoit][/autoit] [autoit]
If $iFFFFDirs = -1 Then Return SetError(2, 0, 0)While True
[/autoit] [autoit][/autoit] [autoit]
$sFFNFDirs = FileFindNextFile($iFFFFDirs)
If @error Then ExitLoop
If @extended Then
$iFFFFFiles = FileFindFirstFile($sStartdir & '\' & $sFFNFDirs & '\E00000.jpg')
If $iFFFFFiles <> -1 Then
While True
$sFFNFFiles = FileFindNextFile($iFFFFFiles)
If @error Then ExitLoopConsoleWrite('FileMove("' & $sStartdir & '\' & $sFFNFDirs & '\E00000.jpg, "' & $sTargDir & '\' & StringFormat('%06d.jpg")', $iCounter) & @CRLF)
[/autoit] [autoit][/autoit] [autoit]
$iCounter += 1
WEnd
EndIf
EndIfWEnd
[/autoit] [autoit][/autoit] [autoit]EndFunc ;==>MoveFilePics
[/autoit]Wenn es doch mehr Verzeichnisebenen sind wäre eine Möglichkeit das rekursiv zu lösen:
Spoiler anzeigen
[autoit]MoveFilePicsRek("E:\Temp\Test", "C:\Windows")
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Func MoveFilePicsRek($sStDir, $sTargDir, $sPat = 'E00000.jpg', $iCounter = 1)
[/autoit] [autoit][/autoit] [autoit]
Local $FFFF, $FFNFIf StringRight($sStDir, 1) = '\' Then $sStDir = StringTrimRight($sStDir, 1)
[/autoit] [autoit][/autoit] [autoit]
If Not FileExists($sStDir) Then Return SetError(2, 0, 0)$FFFF = FileFindFirstFile($sStDir & '\*')
[/autoit]
If $FFFF <> -1 Then
Do
$FFNF = FileFindNextFile($FFFF)
If @error Then ExitLoop
If @extended Then
$iCounter = MoveFilePicsRek($sStDir & '\' & $FFNF, $sTargDir, $sPat, $iCounter)
Else
If $FFNF = $sPat Then
ConsoleWrite('FileMove("' & $sStDir & '\' & $sPat & '", "' & $sTargDir & '\' & StringFormat('%06d.jpg")', $iCounter) & @CRLF)
$iCounter += 1
EndIf
EndIf
Until 0
EndIf
Return $iCounter
EndFunc ;==>MoveFilePicsRekund eine weitere es iterativ zu lösen (Wäre die bessere Lösung je mehr Verzeichnisebenen es gibt - ansonsten halt rekursiv):
Spoiler anzeigen
[autoit]MoveFilePicsIt("E:\Temp\Test", "C:\Windows")
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Func MoveFilePicsIt($sStDir, $sTargDir, $sPat = 'E00000.jpg')
[/autoit] [autoit][/autoit] [autoit]
Local $cSQueue = ObjCreate("System.Collections.Queue")
If @error Then Return SetError(1, 1, -1)
Local $FFFF, $FFNF, $sDir, $iCounter = 1If StringRight($sStDir, 1) = '\' Then $sStDir = StringTrimRight($sStDir, 1)
[/autoit] [autoit][/autoit] [autoit]
If Not FileExists($sStDir) Then Return SetError(2, 0, "")$cSQueue.Enqueue($sStDir)
[/autoit] [autoit][/autoit] [autoit]While $cSQueue.Count > 0
[/autoit]
$sDir = $cSQueue.Dequeue
$FFFF = FileFindFirstFile($sDir & '\*')
If $FFFF <> -1 Then
Do
$FFNF = FileFindNextFile($FFFF)
If @error Then ExitLoop
If @extended Then
$cSQueue.Enqueue($sDir & '\' & $FFNF)
Else
If $FFNF = $sPat Then
ConsoleWrite('FileMove("' & $sDir & '\' & $sPat & '", "' & $sTargDir & '\' & StringFormat('%06d.jpg")', $iCounter) & @CRLF)
$iCounter += 1
EndIf
EndIf
Until 0
EndIf
WEnd
EndFunc ;==>MoveFilePicsItIch hab dir statt einem FileMove mal nur ein Consolewrite eingebaut so dass du dir dein FileMove entsprechend selbst einbauen kannst.
-
Meinst du bei der md5-Berechnung oder den Vergleich allgemein?
Weil bei der reinen Namensvergleichmethode bin ich mit der Performance erstmal recht zufrieden und hab auf Anhieb jetzt auch nicht mehr so viele Ansätze das noch wesentlich zu steigern.
Wär natürlich über Hinweise deinerseits dazu erfreut. -
Um nicht nur anhand der Dateinamen zu vergleichen bietet sich die Berechnung des Hashwertes mit der Crypt.au3 an.
Das sollte aber ziemlich langwierig werden da für jede Datei der Hashwert berechnet werden muss.
Wenn es, in kleinem Maße, doch mal jemand braucht hab ich mal 2 Funktionen geschrieben welche Dubletten anhand des Dateinamens bzw. anhand ihrer md5-Hash finden können:Spoiler anzeigen
[autoit]#include <Array.au3>
[/autoit] [autoit][/autoit] [autoit]
#include <Crypt.au3>$Array = FindeDublettesByName(@SystemDir)
[/autoit] [autoit][/autoit] [autoit]
_ArrayDisplay($Array, "Dubletten anhand Name")$Array = FindeDublettesByHash(@SystemDir)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
_ArrayDisplay($Array, "Dubletten nach Hash-Wert"); #FUNCTION# ;===============================================================================
[/autoit] [autoit][/autoit] [autoit]
;
; Name...........: FindeDublettesByName
; Description ...: Findet Dateien deren Name mehrmals vorkommt
; Syntax.........: FindeDublettesByName($sStDir)
; Parameters ....: $sStDir - Startverzeichnis
; Return values .: Erfolg - 2D-Array mit Dateiname und Verzeichnissen getrennt durch |
; Fehler - Gibt -1 zurück und setzt @error:
; |1 - Fehler beim erstellen der Collections
; |2 - Startverzeichnis existiert nicht
; Author ........: AspirinJunkie
; Modified.......:
; Remarks .......: Benötigt .Net für Collections
; Related .......:
; Link ..........;
; Example .......; No
;
; ;==========================================================================================
Func FindeDublettesByName($sStDir)
Local $cSQueue = ObjCreate("System.Collections.Queue")
If @error Then Return SetError(1, 1, -1)
Local $cRetQu = ObjCreate("System.Collections.Queue")
If @error Then Return SetError(1, 2, -1)
Local $cFiles = ObjCreate("Scripting.Dictionary")
If @error Then Return SetError(1, 3, -1)
Local $cRet = ObjCreate("Scripting.Dictionary")
If @error Then Return SetError(1, 3, -1)Local $FFFF, $FFNF, $sDir, $sTemp, $iCount = 1
[/autoit] [autoit][/autoit] [autoit]If StringRight($sStDir, 1) = '\' Then $sStDir = StringTrimRight($sStDir, 1)
[/autoit] [autoit][/autoit] [autoit]
If Not FileExists($sStDir) Then Return SetError(2, 0, "")$cSQueue.Enqueue($sStDir)
[/autoit] [autoit][/autoit] [autoit]While $cSQueue.Count > 0
[/autoit] [autoit][/autoit] [autoit]
$sDir = $cSQueue.Dequeue
$FFFF = FileFindFirstFile($sDir & '\*')
If $FFFF <> -1 Then
Do
$FFNF = FileFindNextFile($FFFF)
If @error Then ExitLoop
If @extended Then
$cSQueue.Enqueue($sDir & '\' & $FFNF)
Else
If $cFiles.Exists($FFNF) Then
If $cRet.Exists($FFNF) Then
$sTemp = $cRet($FFNF)
$cRet.Remove($FFNF)
$cRet.Add($FFNF, $sTemp & '|' & $sDir)
Else
$cRet.Add($FFNF, $cFiles($FFNF) & '|' & $sDir)
EndIf
Else
$cFiles.Add($FFNF, $sDir)
EndIf
EndIf
Until 0
EndIf
WEndLocal $aRet[$cRet.Count + 1][2]
[/autoit] [autoit][/autoit] [autoit]
$aRet[0][0] = $cRet.Count
For $i In $cRet.Keys
$aRet[$iCount][0] = $i
$aRet[$iCount][1] = $cRet($i)
$iCount += 1
NextReturn $aRet
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
EndFunc ;==>FindeDublettesByName; #FUNCTION# ;===============================================================================
[/autoit] [autoit][/autoit] [autoit]
;
; Name...........: FindeDublettesByHash
; Description ...: Findet doppelte Dateien anhand ihres Hash-Wertes
; Syntax.........: FindeDublettesByHash($sStDir)
; Parameters ....: $sStDir - Startverzeichnis
; $iMethod - Hash-Methode (siehe _Crypt_HashFile()) - Standard: md5
; Return values .: Erfolg - 1D-Array mit Dateipfaden getrennt durch |
; Fehler - Gibt -1 zurück und setzt @error:
; |1 - Fehler beim erstellen der Collections
; |2 - Startverzeichnis existiert nicht
; Author ........: AspirinJunkie
; Modified.......:
; Remarks .......: Benötigt .Net für Collections
; Related .......: Crypt.au3
; Link ..........;
; Example .......; No
;
; ;==========================================================================================
Func FindeDublettesByHash($sStDir, $iMethod = 0x00008003)
Local $cSQueue = ObjCreate("System.Collections.Queue")
If @error Then Return SetError(1, 1, -1)
Local $cRetQu = ObjCreate("System.Collections.Queue")
If @error Then Return SetError(1, 2, -1)
Local $cHashes = ObjCreate("Scripting.Dictionary")
If @error Then Return SetError(1, 3, -1)
Local $cRet = ObjCreate("Scripting.Dictionary")
If @error Then Return SetError(1, 3, -1)Local $FFFF, $FFNF, $sDir, $iTemp, $iCount = 1
[/autoit] [autoit][/autoit] [autoit]
Local $sHashIf StringRight($sStDir, 1) = '\' Then $sStDir = StringTrimRight($sStDir, 1)
[/autoit] [autoit][/autoit] [autoit]
If Not FileExists($sStDir) Then Return SetError(2, 0, "")$cSQueue.Enqueue($sStDir)
[/autoit] [autoit][/autoit] [autoit]While $cSQueue.Count > 0
[/autoit] [autoit][/autoit] [autoit]
$sDir = $cSQueue.Dequeue
$FFFF = FileFindFirstFile($sDir & '\*')
If $FFFF <> -1 Then
Do
$FFNF = FileFindNextFile($FFFF)
If @error Then ExitLoop
If @extended Then
$cSQueue.Enqueue($sDir & '\' & $FFNF)
Else
$sHash = String(_Crypt_HashFile($sDir & '\' & $FFNF, $iMethod))
If $cHashes.Exists($sHash) Then
If $cRet.Exists($sHash) Then
$iTemp = $cRet($sHash)
$cRet.Remove($sHash)
$cRet.Add($sHash, $iTemp & '|' & $sDir & '\' & $FFNF)
Else
$cRet.Add($sHash, $cHashes($sHash) & '|' & $sDir & '\' & $FFNF)
EndIf
Else
$cHashes.Add($sHash, $sDir & '\' & $FFNF)
EndIf
EndIf
Until 0
EndIf
WEndLocal $aRet[$cRet.Count + 1]
[/autoit] [autoit][/autoit] [autoit]
$aRet[0] = $cRet.Count
For $i In $cRet.Keys
$aRet[$iCount] = $cRet($i)
$iCount += 1
NextReturn $aRet
[/autoit]
EndFunc ;==>FindeDublettesByHash -
Es gibt 2 prinzipielle GUI-Betriebsarten.
Den >>Message-Loop-Modus<< und den >>OnEvent-Modus<<.
Für beide findest du ein entsprechendes Beispiel in der Beschreibung. -
Gibt viele Möglichkeiten - hier mal eine:
Spoiler anzeigen
[autoit]#include <GUIConstantsEx.au3>
[/autoit] [autoit][/autoit] [autoit]
#include <WindowsConstants.au3>$GUI = GUICreate("", 633, 447, 189, 121)
[/autoit] [autoit][/autoit] [autoit]
$Progress1 = GUICtrlCreateProgress(192, 184, 150, 17)
$Button1 = GUICtrlCreateButton("Button1", 88, 64, 161, 73, $WS_GROUP)
GUISetState()While 1
[/autoit]
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
Exit
Case $Button1
$Timer = TimerInit()
Do
GUICtrlSetData($Progress1, TimerDiff($Timer) / 100)
Until TimerDiff($Timer) > 10000
EndSwitch
WEnd -
Wieso Angriff?
War auch nur eine Frage bezüglich der Aussage da ich diese nicht verstanden habe.
Denn es ist das selbe Prinzip.
Der einzige Unterschied ist (mal von der wunderschönen Animation abgesehen) dass ich nicht zwischen Grad und Radiant hin und her rechne sondern gleich bei Radiant bleibe.
Hab nur die Aussage nicht verstanden.
Nix passiert -
Ich glaube ihr denkt zu kompliziert! Ein Dreieck hat 3 Ecken und auf einen Kreis transferiert bedeutet dies, dass alle 120° eine Ecke vom Dreick ist!
Das merkte ich hier schon 2x an und habe es in meinem letzten Post umgesetzt.
Warum denk ich da zu kompliziert? -
[autoit]
Global $aArray[3][2][2]
[/autoit] -
Eins vorweg: Ich hab keine Ahnung von GDI+
Aber ich denke folgendes sollte das sein was du willst:Spoiler anzeigen
[autoit]#include <Array.au3>
[/autoit] [autoit][/autoit] [autoit]
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
Opt("GUIOnEventMode", 1)
OnAutoItExitRegister("__GDIPlus_Shutdown")
_GDIPlus_Startup()Global $iRadius = 100
[/autoit] [autoit][/autoit] [autoit]
Global $iWidth = 640, $iHeight = 480
$GUI_Back_Color = 0xFF000000Global $aPolygon
[/autoit] [autoit][/autoit] [autoit]$hGUI = GUICreate("", $iWidth, $iHeight)
[/autoit] [autoit][/autoit] [autoit]
GUISetOnEvent(-3, "OnEvent_Eventhandler")
GUIRegisterMsg($WM_PAINT, "WM_PAINT")$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
[/autoit] [autoit][/autoit] [autoit]
$hBrush = _GDIPlus_BrushCreateSolid(0xFF000000 + $GUI_Back_Color)
$hPen = _GDIPlus_PenCreate(0xFF000000, 3)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphic)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)_Draw()
[/autoit] [autoit][/autoit] [autoit]
GUISetState()
While 1 * Sleep(10)
WEndFunc OnEvent_Eventhandler()
[/autoit] [autoit][/autoit] [autoit]
Switch @GUI_CtrlId
Case -3
Exit
EndSwitch
EndFunc ;==>OnEvent_EventhandlerFunc _Draw()
[/autoit] [autoit][/autoit] [autoit]
Local $iPi = 4*ATan(1), $iDegToRad = $iPi / 180
Local $iEllipseCol = 0xFFEA33EE, $iTriangleCol = 0xFF6FE1EE
Local $aMitte[2] = [$iWidth / 2, $iHeight / 2]Local $aA = PolarAnhaeng($aMitte, 0, $iRadius)
[/autoit] [autoit][/autoit] [autoit]
Local $aB = PolarAnhaeng($aMitte, (2*$iPi)/3, $iRadius)
Local $aC = PolarAnhaeng($aMitte, (4*$iPi)/3, $iRadius)Local $aPolygon[4][2] = [[3,0], [$aA[0],$aA[1]], [$aB[0],$aB[1]],[$aC[0],$aC[1]]]
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]_GDIPlus_GraphicsClear($hBackbuffer, $GUI_Back_Color)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
_GDIPlus_PenSetColor($hPen, $iEllipseCol)
_GDIPlus_GraphicsDrawEllipse($hBackbuffer, $aMitte[0] - $iRadius, $aMitte[1] - $iRadius, $iRadius * 2, $iRadius * 2, $hPen)
_GDIPlus_PenSetColor($hPen, $iTriangleCol)
_GDIPlus_GraphicsDrawPolygon($hBackbuffer, $aPolygon, $hPen)
EndFunc ;==>_DrawFunc WM_PAINT()
[/autoit] [autoit][/autoit] [autoit]
_GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, $iWidth, $iHeight)
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_PAINTFunc __GDIPlus_Shutdown()
[/autoit] [autoit][/autoit] [autoit]
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_Shutdown()
EndFunc ;==>__GDIPlus_Shutdown; Berechnet einen polaren Anhänger
[/autoit]
Func PolarAnhaeng(ByRef $iXq, $iWinkel, $iRadius)
Local $Ret[2] = [ Round($iXq[0] + sin($iWinkel)*$iRadius), _
Round($iXq[1] - cos($iWinkel)*$iRadius)]
Return $Ret
EndFuncIch denke mal eine kleine Falle in die man schnell treten kann ist die Orientierung.
Bei Bildschirmkoordinaten handelt es sich um ein linksseitiges Koordinatensystem weswegen man die Y-Achse "anders herum" betrachten muss. -
Ja, ich geh von dieser Skizze aus. Der Denkfehler liegt scheinbar darin, das ich davon ausgehe das Seite AB des Dreicks als x-Achse herhalten soll bzw. parallel zu ihr laufen soll.
Dann ist es eindeutig - dies wäre eine entsprechende Nebenbedingung welche die Orientierung im Koordinatensystem fest macht.
Alles vor dem Hintergrund das die Winkelhalbierende wirklich 3xRadius ist. Hat ja noch niemand bestätigt.
Im gleichseitigen Dreieck gilt für den Innenkreisradius ri = Wurzel(3)/6 * AC.
Für den Umkreisradius: ru = Wurzel(3)/3 * AC.
Also ri = ru/2.
Die Winkelhalbierende (in deiner Skizze z.B. A-E) ist dann ri+ru = 3*ri = 1/2*Wurzel(3)* ACWenn er allerdings die Richtung eines Punktes zum Mittelpunkt hat braucht er das alles aber nicht.
Der nächste Punkt liegt dann einfach 120° weiter mit der Entfernung 2*ri. -
[...] dann wäre der Winkel AMG immer 60°. Liesse sich damit nicht auch der Endpunkt in Bezug auf den Mittelpunkt errechnen ohne einen der Punkte A,B oder C zu kennen?
Beim gleichseitigen wäre AMG (ich denke du nimmst diese Bezeichnungen aus deiner verlinkten Skizze?) wirklich 60° (= 1/3 Pi).
Das hat allerdings nichts damit zu tun ob man mindestens 1 Punkt kennen muss oder nicht - denn das muss man.
Stell dir einfach vor du hast dein Dreieck schon fertig um den Kreis.
Du kannst es beliebig um den Kreis drehen ohne das der Kreis sich verändert.
Du brauchst also eine Orientierung des Dreiecks.
Die Seitenlängen und Winkel des Dreiecks bleiben natürlich gleich - es geht nur um die Orientierung des Dreiecks in unserem Koordinatensystem.
Du könntest beliebig viele Dreiecke berechnen welche den Bedingungen entsprechen (Gleichseitig, gleichwinklig, mit diesem Kreis als Innenkreis...). -
Ein Kreis geht von 0°-360° d.h., da AutoIt in Radiant rechnet, von 0 bis 2Pi.
Viele haben Probleme damit mit Radiant etwas anzufangen.
Radiant ist strenggenommen kein wirklicher Winkel sondern stellt das Bogenstück am Einheitskreis dar.
Der Umfang eines Kreises mit dem Radius 1 (Einheitskreis) ist 2Pi (bei 360°).
die Hälfte des Einheitskreises hat die Bogenlänge Pi ( bei 180°) usw.
So kann man sich den Radiant wahrscheinlich besser vorstellen.
Bei Sinus & Cosinus kann ich eigentlich nur auf die vielen Darstellungen bezüglich des Einheitskreis hinweisen - anschaulicher geht es erstmal nicht. (>>klickmich<<)Wie berechne ich die einzelnen Punkte auf denen der Kreis gezeichnet wird
Die Laufvariable ist der Winkel - keine Koordinate oder ähnliches.
Wir wollen also Koordinatenunterschiede zu den Mittelpunktkoordinaten anhand des Winkels und des Radius berechnen.
In Kurzform:
x = Xm + cos(Winkel)*Radius
y = Ym + sin(Winkel)*RadiusJe nachdem wo man seinen Winkelursprung hin haben möchte kann man sinus und cosinus vertauschen.
Du gehst in einer For-Schleife von 0 bis 2 Pi einmal durch (Step-Weite beachten).
Deine Laufvariable ist dann der Winkel.
Wie man das jetzt konkret in AutoIt umsetzt - keine Ahnung - hab noch nie mit AutoIt gemaltWie berechne ich die 3 Eckpunkte des dreiecks, ausgehend vom Radius?
Da fehlt eine Nebenbedingung.
Die Punkte können in unendlicher Kombination liegen.
Wenigstens 1 Punkt muss bekannt sein.
Die anderen Punkte liegen dann mit der Schrittweite 2/3*Pi vom 1. Punkt von der Kreismitte entfernt wenn es sich um ein gleichseitiges Dreieck handelt. -
Wenn es wirklich auf die Geschwindigkeit ankommt dann wär es vielleicht besser eine Funktion speziell für diesen Fall zu verwenden.
Die komplette Dateiliste in einem Array benötigt man hier ja nicht - warum also erstellen lassen?
Mal ein Vorschlag:Spoiler anzeigen
[autoit]Global $Path = @SystemDir
[/autoit] [autoit][/autoit] [autoit]$Files = CountAllFiles($Path, 1)
[/autoit] [autoit][/autoit] [autoit]
$Folders = CountAllFiles($Path, 2)
MsgBox(0,"Anzahl", "Dateien: " & $Files & @CRLF & "Ordner: " & $Folders); by AspirinJunkie
[/autoit] [autoit][/autoit] [autoit]
; benötigt .Net für Stack
; $Flag auf 1 für Dateien, 2 für Ordner, 3 für beide
Func CountAllFiles($sStDir, $iFlag = 3)
Local $cStack = ObjCreate("System.Collections.Stack")
If @error Then Return SetError(1, 1, -1)
Local $Counter = 0, $FFFF, $FFNF, $sDirIf StringRight($sStDir, 1) = '\' Then $sStDir = StringTrimRight($sStDir, 1)
[/autoit] [autoit][/autoit] [autoit]
If Not FileExists($sStDir) Then Return SetError(2, 0, "")$cStack.Push($sStDir)
[/autoit] [autoit][/autoit] [autoit]While $cStack.Count > 0
[/autoit]
$sDir = $cStack.Pop
$FFFF = FileFindFirstFile($sDir & '\*')
If $FFFF <> -1 Then
Do
$FFNF = FileFindNextFile($FFFF)
If @error Then ExitLoop
If @extended Then
$cStack.Push($sDir & '\' & $FFNF)
If BitAND($iFlag, 2) Then $Counter += 1
Else
If BitAND($iFlag, 1) Then $Counter += 1
EndIf
Until 0
EndIf
WEnd
Return $Counter
EndFunc -
Ich weiß was ihr denkt: "Schon wieder, so wie jede Woche, eine weitere Funktion zur Auflistung aller Dateien und Ordner im gesamten Verzeichnisbaum..."
Nun ... ja - aber nicht ganz.
Alle bisherigen Ansätze welche ich bisher dazu gesehen habe basierten auf einem rekursiven Ansatz (wenn es doch etwas anderes gibt - berichtigt mich).
Ich hab daher mal eine entsprechende Funktion geschrieben welche ohne Rekursion auskommt:Spoiler anzeigen
[autoit]#include <Array.au3>
[/autoit] [autoit][/autoit] [autoit]$Array = _FL2Arr(@WindowsDir, '*.exe', 1)
[/autoit] [autoit][/autoit] [autoit]
_ArrayDisplay($Array); #FUNCTION# ====================================================================================================================
[/autoit] [autoit][/autoit] [autoit]
; Name...........: _FL2Arr
; Description ...: Gibt ein Array mit Dateien bzw. Unterordnern im gesamten Verzeichnisbaum zurück
; Syntax.........: _FL2Arr($sStDir, [$sPat = '*', [$iFlag = 0]])
; Parameters ....: $sStDir - Startverzeichnis
; $sPat - Optional: Pattern zur Filterung (Stichwort: "WildCards")
; $iFlag - Optional: Flag ob nur Dateien, Ordner oder beides gesucht werden sollen
; |$iFlag=0(Default) Gibt beides zurück
; |$iFlag=1 Gibt nur Dateien zurück
; |$iFlag=2 Gibt nur Ordner zurück
; Return values .: @Error - 1 = Fehler beim erstellen der Queue
; |2 = Startverzeichnis existiert nicht.
; |3 = ungültiger Wert für $iFlag
; Author ........: AspirinJunkie
; Modified.......:
; Remarks .......: Benötigt .Net
; Related .......:
; Link ..........:
; Example .......: No
; Note ..........:
; ===============================================================================================================================
Func _FL2Arr($sStDir, $sPat = '*', $iFlag = 0)
Local $cSQueue = ObjCreate("System.Collections.Queue")
If @error Then Return SetError(1, 1, -1)
Local $cRetQu = ObjCreate("System.Collections.Queue")
If @error Then Return SetError(1, 2, -1)
Local $FFFF, $FFNF, $sDir$sPat = StringReplace($sPat, "\", "\\")
[/autoit] [autoit][/autoit] [autoit]
$sPat = StringReplace($sPat, ".", "\.")
$sPat = StringReplace($sPat, "*", ".*")
$sPat = '^' & $sPat & '$'If StringRight($sStDir, 1) = '\' Then $sStDir = StringTrimRight($sStDir, 1)
[/autoit] [autoit][/autoit] [autoit]
If Not FileExists($sStDir) Then Return SetError(2, 0, "")
If Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then Return SetError(3, 0, "")$cSQueue.Enqueue($sStDir)
[/autoit] [autoit][/autoit] [autoit]While $cSQueue.Count > 0
[/autoit] [autoit][/autoit] [autoit]
$sDir = $cSQueue.Dequeue
$FFFF = FileFindFirstFile($sDir & '\*')
If $FFFF <> -1 Then
Do
$FFNF = FileFindNextFile($FFFF)
If @error Then ExitLoop
If @extended Then
$cSQueue.Enqueue($sDir & '\' & $FFNF)
If $iFlag <> 1 And StringRegExp($FFNF, $sPat) Then $cRetQu.Enqueue($sDir & '\' & $FFNF)
Else
If $iFlag < 2 And StringRegExp($FFNF, $sPat) Then $cRetQu.Enqueue($sDir & '\' & $FFNF)
EndIf
Until 0
EndIf
WEndIf $cRetQu.Count > 0 Then
[/autoit]
Return $cRetQu.ToArray
Else
Local $Ret[1] = [0]
Return $Ret
EndIf
EndFunc ;==>_FL2ArrDas ist vor allem schön für die Speichernutzung da der obligatorische Stackframe für jeden Rekursionsfunktionsaufruf entfällt.
Nun aber warum das ganze?:
Ich wollte es mal hochstellen um mal einen anderen Ansatz zu demonstrieren und eine Vorlage für Erweiterungen, Verbesserungen etc. zu bieten.Beispielsweise könnte man alle Unterordner in einem Verzeichnis auflisten wenn man das Prinzip entsprechend nutzt:
Spoiler anzeigen
[autoit]#include <Array.au3>
[/autoit] [autoit][/autoit] [autoit]$Array = Ordner(@SystemDir)
[/autoit] [autoit][/autoit] [autoit]
_ArrayDisplay($Array);Gibt ein Array aller Ordner im Verzeichnisbaum zurück
[/autoit] [autoit][/autoit] [autoit]
Func Ordner($sStDir)
Local $cStack = ObjCreate("System.Collections.Stack")
Local $cRetSt = ObjCreate("System.Collections.Stack")
Local $oFS = ObjCreate("Scripting.FileSystemObject")$cStack.Push($oFS.GetFolder($sStDir))
[/autoit] [autoit][/autoit] [autoit]While $cStack.Count > 0
[/autoit] [autoit][/autoit] [autoit]
$oSF = $cStack.Pop
$cRetSt.Push($oSF.Path)For $oF In $oSF.SubFolders
[/autoit]
$cStack.Push($oF)
Next
WEnd
Return $cRetSt.ToArray
EndFunc ;==>Ordner
So ich hoffe der ein oder andere sieht darin eine brauchbare Alternative für seine Zwecke.