AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[VxE]'s Home Thread [Scriptlets & Functions]
Goto page 1, 2  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
[VxE]



Joined: 07 Oct 2006
Posts: 1886

PostPosted: Wed Nov 14, 2007 1:16 am    Post subject: [VxE]'s Home Thread [Scriptlets & Functions] Reply with quote

This thread is basically a collection of scripts of which I am particularly not-too-ashamed.

Wheel Spinners for Numbers in Edit Boxes
[VxE]'s Encryption Function
String Replace Function
Clipboard Execute
Quick Click Dictionary Lookup
Google Search Advance to the Next Page
Vector Function Library: a collection of functions for manipulating vectors
Arrow Keys to Numpad Numbers
Hue Sat Lum Functions


The scripts and functions found in this thread are different from my projects in that these are meant to be small, self-contained, and to function either standalone or included in another script.
_________________
My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !


Last edited by [VxE] on Tue May 12, 2009 3:37 am; edited 19 times in total
Back to top
View user's profile Send private message
Guest






PostPosted: Sat Mar 22, 2008 7:33 am    Post subject: Reply with quote

this post sucks








but not as much as this thread Very Happy
Back to top
[VxE]



Joined: 07 Oct 2006
Posts: 1886

PostPosted: Sat Mar 22, 2008 9:12 am    Post subject: Reply with quote

Anonymous wrote:
this post sucks

but not as much as this thread Very Happy

ROFLMAO !!!!

.... this is just too hilarious Laughing Laughing Laughing
_________________
My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Back to top
View user's profile Send private message
_adam
Guest





PostPosted: Sat Mar 22, 2008 5:19 pm    Post subject: Reply with quote

somebody doesn't like you.

can't win them all though. Wink thanks. I picked up some parts.
Back to top
BoBo¨
Guest





PostPosted: Wed Apr 02, 2008 10:51 am    Post subject: Reply with quote

Saw your 'hint' to this thread at your signature. Have you thought about to 'rearrange' the threads apperance a little with using BBCodeWriter?

Currently it's quite a tough challenge to get 'the idea behind' a script within a snap.

JM2€Cs + thanks for sharing your scripts with us. Much appreciated Cool
Back to top
[VxE]



Joined: 07 Oct 2006
Posts: 1886

PostPosted: Wed Apr 02, 2008 9:10 pm    Post subject: Reply with quote

Hmmm... there is indeed a lot of housekeeping that I should do with this thread, but recently I've been up to my eyeballs in other work. I suppose I really should break each scriptlet into its own post and keep a directory in the OP.

I'm glad you found something useful here Laughing Razz
_________________
My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Back to top
View user's profile Send private message
[VxE]



Joined: 07 Oct 2006
Posts: 1886

PostPosted: Fri Apr 04, 2008 8:38 pm    Post subject: Wheel Spinners for Edit Boxes with Numbers in them. Reply with quote

[Edit: Update ( 6-3-08 )]
Code:
; [VxE]'s Number Wheel Script
; Updated version of number control spinner
; Hover the mouse over an edit control with a number in
; its text and the scrollwheel can change the number
SetTimer, CheckMouseOverControl, 50
*WheelUp::
*WheelDown::
CheckMouseOverControl:
MouseGetPos,,,oWin,oCon
ControlGetText, cs, %oCon%, AHK_ID %oWin%
If !InStr(oCon, "Edit") || StrLen(cs) > 199
{
   If (WheelsOnOff != "off")
   {
      WheelsOnOff := "off"
      Hotkey, *Wheelup, *WheelUp, % WheelsOnOff
      Hotkey, *WheelDown, *WheelDown, % WheelsOnOff
   }
}
else
{
   If (WheelsOnOff != "on")
   {
      WheelsOnOff := "on"
      Hotkey, *Wheelup, *WheelUp, % WheelsOnOff
      Hotkey, *WheelDown, *WheelDown, % WheelsOnOff
   }
   If (A_ThisLabel = "CheckMouseOverControl")
      return

   InPos := OutPos := 0   ; operate on first number found
   Loop, Parse, cs
   {
      np := Asc(A_LoopField)
      If ( np >= 45 && np <= 57 && np != 47 )
         If ( InPos = 0 )
            InPos := OutPos := A_Index
         else
            OutPos := (A_Index-Outpos-1) ? OutPos : A_Index
   }
   np := SubStr( cs, InPos, OutPos - InPos + 1 )
   tic := (InStr(np, ".") ? np/20 : Ceil(np/20))
   If (!GetKeyState("Shift") || !tic )
      tic := 1
   If (GetKeyState("Ctrl"))
      tic := 0.001 + GetKeyState("shift") * 0.024
   np -= tic * ((!InStr(A_ThisHotkey, "up")) * 2 - 1 )
   If InStr( np, "." )
      Loop 9
         If !SubStr(np,0)
            StringTrimRight, np, np, 1
         else
            break
   ControlSetText, %oCon%, % SubStr(cs,1,InPos-1) np SubStr(cs,OutPos+1),AHK_ID %oWin%
}
return


new version (above) replaces old version (below).
Changes 1: Uses a timer to watch the mouse cursor to see if it's over a valid control, then if it is, the wheel keys become active and block the wheel events from reaching the target window, thus preventing any native wheel support the target app might have for such controls. To bypass this, simply put the control in focus and move the cursor off the control before using the mousewheel (that allows the wheel event to reach the app's window).
2: To adjust the rate faster (5%), hold [shift] while scrolling. To force adjustments by 0.001, hold [ctrl]. To force an increment of 0.025, hold [ctrl][shift].
3: This script is meant to make adjusting numbers in edit controls easier for someone using a laptop (no numpad) and a logitech mouse with flywheel scrolling.

[End Edit]

Numerical Control Spinner. This script simulates the ability of the scroll wheel to adjust numbers in edit boxes. This behavior is commonly seen in programs like photoshop, where there are a number of edit boxes for brush settings and stuff. This script operates on the control that is currently under the mouse cursor, so if an edit box already has the wheelie change built in, this script will interfere with that (just don't hover the mouse over those controls and it will work OK)

The Default increment is 1, although I have the script set to increase this increment to 5% of the current value if the user waits for 2 seconds between two wheel ticks. The incrementing value can be reset to 1 by activating any other non-wheel hotkey.

Additional Support Idea for Future Update: Support selecting a number in text and changing it with the scrollwheel.
Code:
; Auto spinners for numerical controls
~*LButton::return
~*WheelUp::
~*WheelDown::
MouseGetPos, X, Y, oWin, oCon
If !InStr(oCon, "Edit") ; we only want spinners to work on edit
   return ; controls, not for things like buttons and such
ControlGetText, gvar, %oCon%, AHK_ID %oWin%
ovar := gvar ; chop up a copy
Loop 8 ; provide accomodation to remove stupid words after numbers in the
   If ( ovar + 1 = "" ) ; edit box like "inches" or "pixels"
      ovar := SubStr(ovar, 1, -1)
   else
      break
If ( ovar + 1 != "" ) ; so, our edit control contains a number, brilliant!
{
   gvar := SubStr(gvar, StrLen(ovar)) ; remove the number part
   If !InStr(A_PriorHotkey, "~*Whee") ; use of a non-wheel hotkey will
      uinc := 1 ; reset the step size to 1
   Else If A_TimeSincePriorHotkey > 2000 ; wait for 2 seconds to set the
      uinc := ovar // 20 ; step size to approx 5% of the current value
   ovar += ((A_ThisHotkey = "~*WheelUp")*2-1) * uinc * ((uinc > 0)*2-1) + (uinc + 0.0 = 0)
   ControlSetText, %oCon%, % ovar gvar, AHK_ID %oWin% ; note the %ovar%%gvar%...
}
return

_________________
My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !


Last edited by [VxE] on Wed Jun 04, 2008 7:37 am; edited 1 time in total
Back to top
View user's profile Send private message
[VxE]



Joined: 07 Oct 2006
Posts: 1886

PostPosted: Fri Apr 04, 2008 8:47 pm    Post subject: [VxE]'s Encryption With GUI Reply with quote

My Encryption Function... this examples has a simple gui but you can strip out the functions if you'd like. The function's parameters are as follows: str, str, bool.
The first parameter is the key (i.e. password), the second is the message, the third is a switch to specify wither forwards or backwards.

I have added another function () for users who desire greater readability. All that function does is call the main function with the 3rd parameter set to "1".

The only difference between 'encryption' and 'decryption' is the direction of the algorithm. In other words, 'decryption' is the inverse function of 'encryption' and vice versa ad infinitum.
Code:
; [VxE]'s Double-Dynamic Key-Based Encryption Script
; A fully functional security script for protecting text
; version 1.b, Optimized key handling for large keys
; last edit: [7-10-08]

#SingleInstance force
wid := A_ScreenWidth // 2
bwid := (wid - 100) // 5
cwid := wid // 5
dwid := wid - 100
edh := A_ScreenHeight //100
Gui, font, s16, Arial
Gui, Add, Text, w90, Key
Gui, Add, Edit, X100 R1 vMyKey Y10 W%dwid%
Gui, Add, Edit, +wrap R%edh% vInMessage X10 W%wid%
Gui, Add, Edit, Disabled +wrap R%edh% vOutMessage X10 W%wid%
Gui, Add, Button, w%bwid% x25 gEncrypt, Encrypt
Gui, Add, Button, w%bwid% yp xp+%cwid% gDecrypt, Decrypt
Gui, Add, Button, w%bwid% yp xp+%cwid% gSwap, Swap Fields
Gui, Add, Button, w%bwid% yp xp+%cwid% gcopy, Copy Text
Gui, Add, Button, w%bwid% yp xp+%cwid% gGuiClose, &Quit
Gui, Show, AutoSize, [VxE]'s Double-Dynamic Key-Based Encryption Function
return
GuiClose:
GuiEscape:
exitapp

copy:
Swap:
GuiControlGet, OutMessage,,
If A_ThisLabel = copy
   StringReplace, clipboard, OutMessage, `n, `r`n, all
else
{
   GuiControlGet, InMessage,,
   StringReplace, OutMessage, OutMessage, `r`n, `n, all
   StringReplace, InMessage, InMessage, `r`n, `n, all
   GuiControl,, InMessage, %OutMessage%
   GuiControl,, OutMessage, %InMessage%
}
return

Decrypt:
Encrypt:
GuiControlGet, MyKey,,
GuiControlGet, InMessage,,
GuiControl,, OutMessage, % Encrypt( mykey, InMessage, A_ThisLabel )
return

; Readability consideration, example:
; result := Decrypt( key, message ) ; will attempt to decrypt the message
Decrypt( key, message, optional = "" )
{
   return Encrypt( key, message, !optional )
}

; Param 3 is a binary switch to determine this function's direction.
; [blank], [0], or ["e*"] yields forwards, anything else yields backwards.
; Readability consideration: simply omit the third parameter and use "Decrypt()" to decrypt.
Encrypt(key, message, CryptEvent = "")
{ ; CryptEvent defaults to 'encrypt', but really only the first letter is needed
   LowerBound = 34
   UpperBound = 126
   StringReplace, Message, Message, `r`n, `n, all
   StringLeft, CryptEvent, CryptEvent, 1
   If !CryptEvent
      CryptEvent = e
   Loop, parse, key
      key .= "`n" Asc(A_LoopField)
   key := SubStr(key, InStr(Key, "`n",0,1)+1)
   NewMessage =
   Loop, Parse, Message
   {
      code := Asc(A_LoopField)
      If ( code >= LowerBound ) && ( code <= UpperBound )
      {
         mco := code
         prevc := A_Index
         newkey := ""
         Loop, Parse, key, `n
            code := Clamp(( code - (A_LoopField * ( Mod(A_LoopField, 2)
            * 2 - 1 )) * ((CryptEvent = "e") * 2 - 1) ), LowerBound, UpperBound )
         If CryptEvent = e
            mco := code
         Loop, Parse, key, `n
            newkey .= "`n" (prevc := Clamp((A_LoopField + mco * (Mod((mco
            +Prevc), 2) * 2 - 1) + Prevc), 1, 255))
         key := SubStr( newkey, 2 )
      }
      NewMessage .= Chr(code)
   }
return % NewMessage
}


clamp( number, low, high ) ; altered mutation of Mod() function
{ ; 7-10-2008 edit:
   span := (high - low + (high > low)*2 - 1)
   return number + span * Round(((low-number)/2 + (high-number)/2)/span)
}

_________________
My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !


Last edited by [VxE] on Thu Jul 10, 2008 10:10 pm; edited 3 times in total
Back to top
View user's profile Send private message
[VxE]



Joined: 07 Oct 2006
Posts: 1886

PostPosted: Fri Apr 04, 2008 8:52 pm    Post subject: Joystick to Numberpad Reply with quote

A functionized version of StringReplace that accepts a quantity of substrings to replace, and returns the number of successfully replaced substrings. The input string is passed as byref, since I almost always use the same variable as the input and output for StringReplace
Code:
StrRep( byref str, find, rep="", howmany="all" ) ; returns the number of things replaced
{
   count = 0
   If howmany is number
      Loop % Floor(howmany)
      {
         StringReplace, str, str, % find, % rep
         If !Errorlevel
            count++
         else   break
      }
   else
   {
      StringReplace, str, str, % find, % rep, UseErrorLevel
      count := ErrorLevel
   }
   return count
}

_________________
My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !


Last edited by [VxE] on Tue May 12, 2009 3:43 am; edited 1 time in total
Back to top
View user's profile Send private message
[VxE]



Joined: 07 Oct 2006
Posts: 1886

PostPosted: Fri Apr 04, 2008 9:11 pm    Post subject: AutoExecute Reply with quote

A more recent manifestation of one of my earlier scripts. This script attempts to run the contents of the clipboard as an AHK script with added safeguards and self-cleaning features.
Code:
; you can put this code in your main script and save
; the bulk of the clipboard execute script to a separate file
#/::run ThisScriptsfilename.ahk

And the meat...
Code:
; Clipboard Execute: Attempts to run the contents of
; the clipboard as though they were an AHK script
;
; a list of commands or operators that are common to the vast
; majority of AHK scripts. If the copied text doesn't have one
; of these, it won't be run (helps avoid error popups if run accidentally)

keywords = send,:=,msgbox,tooltip,sleep,fileappend,return,loop,SetTimer,gui
Blacklist = regwrite,filedelete,A_Startup,shutdown,onexit,UrlDownloadToFile

#SingleInstance Off
LifeSpan := 45
SetWorkingDir %A_ScriptDir%
TempTemplate =
(
   #UseHook
   OnExit, lesc
   SetTimer, lesc, -%LifeSpan%000
   Hotkey, esc, lesc, on
   ¿ ; the bulk goes here
   lesc:
   FileDelete, `%A_ScriptFullPath`%
   Exitapp
)
; The template is a safety wrapper put around
; the copied text to prevent the script from
; being annoying. Panic hotkey and Lifespan

Stringreplace, Script, clipboard, srcc, StringReplace`,Clipboard`,Clipboard, all
If !Script
   return

Loop, parse, keywords, `,
   ok += InStr( Script, A_LoopField "," )
    + InStr( Script, A_LoopField " " )
    + InStr( Script, A_LoopField "`r" )
    + InStr( Script, A_LoopField "`n" )

Loop, parse, blacklist, `,
   If InStr(Script, A_LoopField)
   {
      MsgBox, 52, Security Warning !!,
(
The word "%A_LoopField%" was found
in the clipboard. This could cause
undesired or malicious effects if run.

Do you wish to continue ?
)
      IfMsgBox, No
         exitapp
   }

If ok
{
   Loop, ClipEx*.ahk
      Last := 0 SubStr( SubStr(A_LoopFileName, 7), 1, -4)
   Last := SubStr(00 (last+1), -1)
   StringSplit, Str, TempTemplate, ¿
   FileAppend, %Str1% `n %Script% `n %str2%, ClipEx%last%.ahk
   Loop 111
   {
      sleep 25
      IfExist, ClipEx%last%.ahk
      {
         Run, ClipEx%last%.ahk, , , wid
         DetectHiddenWindows, On
         WinWait, Ahk_pID %wid%, , 2
         WinWaitClose, Ahk_pID %wid%, , %LifeSpan%
         DetectHiddenWindows, Off
         FileDelete, ClipEx%last%.ahk
         break
      }
   }
}

_________________
My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !


Last edited by [VxE] on Tue May 12, 2009 3:45 am; edited 2 times in total
Back to top
View user's profile Send private message
[VxE]



Joined: 07 Oct 2006
Posts: 1886

PostPosted: Fri Apr 04, 2008 9:32 pm    Post subject: Online Dictionary Easy Lookup Script Reply with quote

Don't know what a word means? Just Control+Double-Click it (while this script is running)

The variable at the top (page) contains the URL for the results page of a dictionary or search page, some other popular ones are listed in comments below. To use a different search site, simply go to that site, type in a unique word into the search field, click 'search', then get the URL from the results page and replace your unique word with []MySearchTarget[] and put that into the script.
Code:
; [VxE]'s Ctrl+DblClick word lookup script
page = http://dictionary.cambridge.org/results.asp?searchword=[]MySearchTarget[]&x=48&y=1
; page = http://www.merriam-webster.com/dictionary/[]MySearchTarget[]
; page = http://www.google.com/search?hl=en&q=[]MySearchTarget[]&btnG=Google+Search
; page = http://search.yahoo.com/search?p=[]MySearchTarget[]&fr=yfp-t-501&toggle=1&cop=mss&ei=UTF-8
; page = http://en.wikipedia.org/wiki/Special:Search?search=[]MySearchTarget[]&fulltext=Search

~^LButton::
MouseGetPos, px, py
pm := px . py
If    ( A_PriorHotkey = A_ThisHotkey )
     && (A_TimeSincePriorHotkey < DllCall("GetDoubleClickTime"))
     && (om = pm) ; if the mouse moved, it wasn't a double-click
{
   Sleep 150
   sclip := clipboardall
   Clipboard := ""
   Send ^c
   Clipwait, 1
   StringReplace, specpage, page, []MySearchTarget[], %Clipboard%
   Clipboard := sclip
   Run %specpage% ; open page in default browser
}
Else
   om := pm
return

_________________
My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Back to top
View user's profile Send private message
[VxE]



Joined: 07 Oct 2006
Posts: 1886

PostPosted: Fri Apr 04, 2008 9:35 pm    Post subject: Google Search: Advance to Next Page Reply with quote

For those restless people out there who find themselves continuously using google image search to fill those unsupervised work hours. This script saves you the trouble of actually clicking on the little "next" button on a google search (either web search or image search).
Code:
; [VxE]'s "on google-search press 'next' with the keyboard" script
RWin up:: ; or whatever hotkey you like. Suggest you stick to the "Up" part so your key doesn't interrupt anything
SetKeyDelay, 20
SetTitleMatchMode, 2
IfWinNotActive, Google Search   ; only tested on Google
   return
oclip := clipboardall
Send !d^x{tab}
dIncrement = 10 ; websearch number of results per page
IfWinActive, Google Image Search
   dIncrement := 21 ; image search results per page, should auto-correct after first page
StartNum  =
Loop, Parse, Clipboard, & ; find out how many results per page, not available on page 1
   IfInString, A_LoopField, ndsp=
      StringTrimLeft, dIncrement, A_LoopField, 5
Loop, Parse, Clipboard, & ; find out how many search results we've seen and move up to the next bunch
   IfInString, A_LoopField, start=
   {
      StringTrimLeft, StartNum, A_LoopField, 6
      StartNum := "start=" . (StartNum + dIncrement)
      StringReplace, Clipboard, Clipboard, %A_LoopField%, %StartNum%
   }
If StartNum = ; we are on the first page of the search, so make up the next page
   Clipboard = %Clipboard%&start=%dIncrement%&ndsp=%dIncrement%
Send ^v{enter}
clipboard := oclip
oclip := ""
return

_________________
My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Back to top
View user's profile Send private message
[VxE]



Joined: 07 Oct 2006
Posts: 1886

PostPosted: Fri Apr 04, 2008 9:49 pm    Post subject: Vector Function Library Reply with quote

This is my vector function library. I wrote it because I needed easy vector support for some of my other projects. I tried to optimize these functions for speed without sacrificing ease of use. I'm also working on a matrix function library as a companion to this vector lib.

Code:
; [VxE]'s vector function library [10-10-08]
; A collection of vector functions
; A formal vector has the format
;      ##, ##, ##, ##;
; where ## indicates a real number.
; Formalized vector format is used internally to
; increase efficiency. Formalization optimizations
; are not strictly for internal use, if your input
; vectors are in the formal format, you may specify
; 1 as the second parameter to increase performance.
; Supported operations currently include:
;    Float Vect_Item( Vector Index )
;    Float Vect_Len( Vector )
;    Float Vect_Dot( Vector . Vector )
;    Float Vect_Angle(["deg"] Vector . Vector )
;    Vector Vect_Formal( string )
;    Vector Vect_Norm( Vector )
;    Vector Vect_Sub( Vector ... Vector )
;    Vector Vect_Add( Vector ... Vector )
;    Vector Vect_Mult( Vector . Float )
;    Vector Vect_Proj( Vector . Vector )
;    Vector Vect_Reflect( Vector . Vector )
;    Vector Vect_Cross( Vector . Vector )
;

; Returns the Nth member of the input vector
; NOTE: seperate the vector and the index
; by a semicolor or a newline character
; When using a formal vector, you may
; simply use the following format:
; result := Vect_Item( FormalVector . 3, 1 )
; This function will probably never be used
; because you can just use StringSplit and
; put all of the vector's members into vars
Vect_Item(vect, formal=0)
{
   IfNotEqual, formal, 1
   {
      Loop, Parse, vect, `;`n, %A_Space%%A_Tab%`r`,
        IfLess, A_Index, 3, SetEnv, factor%A_Index%, % Vect_Formal(A_LoopField)
         Else Break
      factor2 := SubStr(Factor2, 1, -1+InStr(Factor2, ","))
   } Else StringSplit, factor, vect, `;, %A_Space%%A_Tab%`r`n`,
   
   Loop, Parse, factor1, `,, %A_Space%`;
      IfEqual, A_Index, % Round( factor2 ), return %A_LoopField%
   return ""
}


; Returns the absolute length of the input vector
Vect_Len(vect, formal=0)
{
   off := A_FormatFloat
   SetFormat, Float, 0.15
   IfNotEqual, formal, 1, SetEnv, vect, % Vect_Formal(vect)
   Loop, Parse, vect, `,, %A_Space%`;
      sum += A_LoopField**2
   SetFormat, Float, %off%
   return sqrt(sum)
}

; returns the dot product of the first two vectors.
; the dot product is an easy test of orthogonality
; if the dot product is zero, the two vectors are
; orthogonal (at a right-angle to each other)
Vect_Dot(vlist, formal=0)
{
   off := A_FormatFloat
   SetFormat, Float, 0.15
   IfNotEqual, formal, 1, Loop, Parse, vlist, `;`n, %A_Space%%A_Tab%`r`,
   {
      IfEqual, A_LoopField,, Continue
      IfEqual, True, % !(vect := Vect_Formal(A_LoopField)), continue
      u++
      StringSplit, v%u%d, vect, `,, %A_Space%%A_Tab%`r`;
      IfLess, vorder, % v%u%d0, SetEnv, vorder, % v%u%d0
   }
   else   Loop, Parse, vlist, `;`n, `r%A_Space%%A_Tab%
   {
      IfEqual, A_LoopField,, Continue
      u++
      StringSplit, v%u%d, A_LoopField, `,, `n%A_Space%
      IfLess, vorder, % v%u%d0, SetEnv, vorder, % v%u%d0
   }
   Loop %vorder%
      EnvAdd, acc, v1d%A_Index% * v2d%A_Index%
   SetFormat, Float, %off%
   return acc + 0
}

; returns the angle between the first two vectors in vlist
; Essentially, return the arccosine of the dot product of the
; normals of two vectors.
; default return value is in radians, specify "deg" before
; any vectors to return the angle in degrees. Example:
; ResultInDegrees := Vect_Angle( "deg" Vector1 Vector2 )
Vect_Angle(vlist, formal=0)
{
   off := A_FormatFloat
   SetFormat, Float, 0.15
   deg := u := 1
   IfEqual,True, % InStr(vlist,"deg")
    SetEnv,vlist, % SubStr(vlist,53.3-deg:=45/ATan(1))
   IfNotEqual, formal, 1, Loop, Parse, vlist, `;`n, %A_Space%%A_Tab%`r`,
   {
      IfEqual, A_LoopField,, Continue
      IfEqual, True, % !(vect%u% := Vect_Formal(A_LoopField)), continue
      else u++
   }
   else   Loop, Parse, vlist, `;`n, `r%A_Space%%A_Tab%
      IfEqual, A_LoopField,, Continue
      else vect%u% := A_LoopField ";", u++
   angle := ACos( Vect_Dot( Vect_Norm( vect1, 1 ) . Vect_Norm( vect2, 1 ), 1 ) )
   SetFormat, Float, %off%
   return angle * deg
}


; Formalize a string into a vector by parsing through
; any numeric characters (includes '-' and '.') and
; appending them according to the following rules:
; 0. Characters listed in the second parameter
; are ignored (for instance: commas in large numbers)
; 1. The first semicolon or newline reached marks
; the end of the input string. This is to stop multiple
; vectors from being formalized into a frankenvector
; 2. all non-numeric chars become item breaks
; 3. an item break preceeds every minus sign
; 4. within an unbroken numeric string, the second
; decimal point is dropped along with all chars
; following it until the next item break is reached
; 5. There are no empty vector members unless the
; input contains no numeric characters.
; NOTE: If there is a way to do this in one line
; with regex, I'm not interested! Either release
; it or append it to this library yourself.
Vect_Formal(string, ignorechars="")
{
   Loop, Parse, string, , %ignorechars%
      If A_LoopField !=
         IfEqual, A_LoopField, `;, break
         else   nv .= (u := InStr("-.1234567890", A_LoopField)) ? (u
            =1 ? " " : "") A_LoopField : " "
   Loop, Parse, nv, %A_Space%
      IfEqual, A_LoopField,, Continue
      Else    IfNotEqual, A_LoopField, -
      {
         stringsplit, q, A_LoopField, .
         vect .= ", " q1 + 0 (q0>1 ? "." q2 : "")
      }
   return StrLen(vect) > 3 ? SubStr(vect,3) ";" : ""
}


; Returns the normal of the input vector
Vect_Norm(vect, formal=0)
{
   off := A_FormatFloat
   SetFormat, Float, 0.15
   IfNotEqual, formal, 1, SetEnv, vect, % Vect_Formal(vect)
   len := Vect_Len(vect, 1)
   Loop, Parse, vect, `,, %A_Space%`;
      nv .= ", " A_LoopField / len
   SetFormat, Float, %off%
   return substr(nv,3) ";"
}

; Returns the sum of the first vector and the negatives
; of all subsequent vectors in the list
Vect_Sub(vlist, formal=0)
{
   off := A_FormatFloat
   SetFormat, Float, 0.15
   IfNotEqual, formal, 1, Loop, Parse, vlist, `;`n, %A_Space%%A_Tab%`r`,
   {
      IfEqual, A_LoopField,, Continue
      IfEqual, True, % !(vect := Vect_Formal(A_LoopField)), continue
      u++
      StringSplit, v%u%d, vect, `,, %A_Space%%A_Tab%`r`;
      IfLess, vorder, % v%u%d0, SetEnv, vorder, % v%u%d0
   }
   else   Loop, Parse, vlist, `;`n, `r%A_Space%%A_Tab%
   {
      IfEqual, A_LoopField,, Continue
      u++
      StringSplit, v%u%d, A_LoopField, `,, `n%A_Space%
      IfLess, vorder, % v%u%d0, SetEnv, vorder, % v%u%d0
   }
   Loop %vorder%
   {
      v := A_Index
      Loop %u%
         IfEqual, A_Index, 1, SetEnv, acc, % v1d%v%
         else   EnvSub, acc, % v%A_Index%d%v%
      nv .= ", " acc
   }
   SetFormat, Float, %off%
   return substr(nv,3) ";"
}

; Adds the vectors in the list.
Vect_Add(vlist, formal=0)
{
   off := A_FormatFloat
   SetFormat, Float, 0.15
   IfNotEqual, formal, 1, Loop, Parse, vlist, `;`n, %A_Space%%A_Tab%`r`,
   {
      IfEqual, A_LoopField,, Continue
      IfEqual, True, % !(vect := Vect_Formal(A_LoopField)), continue
      u++
      StringSplit, v%u%d, vect, `,, %A_Space%%A_Tab%`r`;
      IfLess, vorder, % v%u%d0, SetEnv, vorder, % v%u%d0
   }
   else   Loop, Parse, vlist, `;`n, `r%A_Space%%A_Tab%
   {
      IfEqual, A_LoopField,, Continue
      u++
      StringSplit, v%u%d, A_LoopField, `,, `n%A_Space%
      IfLess, vorder, % v%u%d0, SetEnv, vorder, % v%u%d0
   }
   Loop %vorder%
   {
      v := A_Index
      acc := 0
      Loop %u%
         EnvAdd, acc, % v%A_Index%d%v%
      nv .= ", " acc
   }
   SetFormat, Float, %off%
   return substr(nv,3) ";"
}

; Returns the input vector with length
; multiplitd by a factor. NOTE: seperate
; the vector and the factor by a
; semicolor or a newline character
; When using a formal vector, you may
; simply use the following format:
; result := Vect_Mult( FormalVector . 3, 1 )
Vect_Mult(vect, formal=0)
{
   off := A_FormatFloat
   SetFormat, Float, 0.15
   IfNotEqual, formal, 1
   {
      Loop, Parse, vect, `;`n, %A_Space%%A_Tab%`r`,
        IfLess, A_Index, 3, SetEnv, factor%A_Index%, % Vect_Formal(A_LoopField)
         Else Break
      factor2 := SubStr(Factor2, 1, -1+InStr(Factor2, ","))
   } Else StringSplit, factor, vect, `;, %A_Space%%A_Tab%`r`n`,
   
   Loop, Parse, factor1, `,, %A_Space%`;
      nv .= ", " A_LoopField * factor2
   SetFormat, Float, %off%
   return substr(nv,3) ";"
}

; returns a vector describing the projection A onto B
; where A is the first vector in the list and B is the next
; The result is linearly dependant to vector B
Vect_Proj(vlist, formal=0)
{
   u=1
   IfNotEqual, formal, 1, Loop, Parse, vlist, `;`n, %A_Space%%A_Tab%`r`,
   {
      IfEqual, A_LoopField,, Continue
      IfEqual, True, % !(vect%u% := Vect_Formal(A_LoopField)), continue
      else u++
   }
   else   Loop, Parse, vlist, `;`n, `r%A_Space%%A_Tab%
      IfEqual, A_LoopField,, Continue
      else vect%u% := A_LoopField ";", u++
   return Vect_Mult(vect2 . Vect_Dot(vect1 . vect2, 1) / (Vect_Len(vect2, 1)**2), 1)
}

; if the second vector is normal to a plane, and
; the first vector is not paralell to that plane
; then this function returns the first vector
; after it bounces off the plane
; In essense, this function subtracts twice the
; projection of v1 onto v2 from v1, clear?
; Also, the angle between a vector and its reflection
; is exactly equal to twice the angle betwen that
; vector and the normal it is being reflected from
; so, Vect_Angle( v1 v2 ) is the same as
; Vect_Angle( Vect_Reflect( v1 v2 ) v2 )
Vect_Reflect(vlist, formal=0)
{
   u=1
   IfNotEqual, formal, 1, Loop, Parse, vlist, `;`n, %A_Space%%A_Tab%`r`,
   {
      IfEqual, A_LoopField,, Continue
      IfEqual, True, % !(vect%u% := Vect_Formal(A_LoopField)), continue
      else u++
   }
   else   Loop, Parse, vlist, `;`n, `r%A_Space%%A_Tab%
      IfEqual, A_LoopField,, Continue
      else vect%u% := A_LoopField ";", u++
   vx := Vect_Proj(vect1 . vect2, 1)
   return Vect_Sub(vect1 . vx . vx, 1)
}

; returns a vector that is the cross-product of
; the first two vectors in vlist provided that
; those two vectors are independant and are in R3
; Note: the cross product in Rn requires n-1 vectors
; and is produced by calculating the determinants of
; n square matrices of size (n-1)x(n-1)
; For example, in R5...
;
;  v1 = v1a, v1b, v1c, v1d, v1e
;  v2 = v2a, v2b, v2c, v2d, v2e
;  v3 = v3a, v3b, v3c, v3d, v3e
;  v4 = v4a, v4b, v4c, v4d, v4e
; Cross = I,   J,   K,   L,   M
; I = Det( v1b, v1c, v1d, v1e; v2b, v2c, v2d, v2e; v3b, v3c, v3d, v3e; v4b, v4c, v4d, v4e)
; J = Det( v1c, v1d, v1e, v1a; v2c, v2d, v2e, v2a; v3c, v3d, v3e, v3a; v4c, v4d, v4e, v4a)
; K = Det( v1d, v1e, v1a, v1b; v2d, v2e, v2a, v2b; v3d, v3e, v3a, v3b; v4d, v4e, v4a, v4b)
; L = Det( v1e, v1a, v1b, v1c; v2e, v2a, v2b, v2c; v3e, v3a, v3b, v3c; v4e, v4a, v4b, v4c)
; M = Det( v1a, v1b, v1c, v1d; v2a, v2b, v2c, v2d; v3a, v3b, v3c, v3d; v4a, v4b, v4c, v4d)
; where Det() is the determinate of the specified matrix
; And for large n's, the fastest way to get the determinant
; is through row-reduction to row-echelon form and then
; multiply along the diagonal. Since row-reduction would
; have a big-O notation of O(n²) whereas finding
; the determinate by laplace expansion would have a
; big-O of O(n!) (and that's really bad!!)
;
Vect_Cross(vlist, formal=0) ; WARNING: R3 supported only!!!!
{
   off := A_FormatFloat
   SetFormat, Float, 0.15
   IfNotEqual, formal, 1, Loop, Parse, vlist, `;`n, %A_Space%%A_Tab%`r`,
   {
      IfEqual, A_LoopField,, Continue
      IfEqual, True, % !(vect := Vect_Formal(A_LoopField)), continue
      u++
      StringSplit, v%u%d, vect, `,, %A_Space%%A_Tab%`r`;
   }
   else   Loop, Parse, vlist, `;`n, `r%A_Space%%A_Tab%
   {
      IfEqual, A_LoopField,, Continue
      u++
      StringSplit, v%u%d, A_LoopField, `,, `n%A_Space%
   }
   vr := (v1d2 * v2d3 - v1d3 * v2d2) ", "
   vr .= (v1d3 * v2d1 - v1d1 * v2d3) ", "
   vr .= (v1d1 * v2d2 - v1d2 * v2d1) ";"
   SetFormat, Float, %off%
   return vr
}

_________________
My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !


Last edited by [VxE] on Fri Oct 10, 2008 11:13 am; edited 3 times in total
Back to top
View user's profile Send private message
[VxE]



Joined: 07 Oct 2006
Posts: 1886

PostPosted: Sat Jun 07, 2008 4:44 am    Post subject: Reply with quote

This script turns the 4 arrow keys into the number keys on the numberpad. Press one or two arrow keys to get the appropriate numpad number or pgup/home/end or numpadarrows (depending on the numlock state). Feel free to change the actual toggle to something other than Numlock (the appskey is pretty handy Wink). Also the alternate functions can be easily customized.
Code:
; [VxE]'s Arrow Keys To Numpad Multiplexer.
ArrowKeys = Up,Left,Down,Right
NumPadAliases = End,Down,PgDn,Left,NumpadClear,Right,Home,Up,PgUp
StringSplit, k, ArrowKeys, `,
StringSplit, NumAlias, NumPadAliases, `,
NumAlias0 = Ins ; I'd recommend 'BackSpace' as it seems more useful
Loop, Parse, ArrowKeys, `,
   Hotkey, $*%A_LoopField%, $*Up, on
$*Up::
mark := SubStr(((sk1:=GetKeyState(k1,"P"))-(sk3:=GetKeyState(k3,"P"))+1)*3
+(sk4:=GetKeyState(k4,"P"))-(sk2:=GetKeyState(k2,"P"))+2-5*(!sk2 & !sk4 & sk1 & sk3),0)
If (!InThread)
{
   InThread = 1
   Sleep 40 ; delay to allow coordination of multiple keys
   If (GetKeyState("NumLock", "T")) ; put any toggle you want
      Send {blind}{NumPad%mark%}
   else
      Send % "{blind}{" NumAlias%mark% "}" ; "{blind}{Numpad" NumAlias%mark% "}"
   InThread = 0
}
return

_________________
My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Back to top
View user's profile Send private message
[VxE]



Joined: 07 Oct 2006
Posts: 1886

PostPosted: Sun Jun 08, 2008 7:24 am    Post subject: Reply with quote

I know that RGB to HSV has been done before in AHK (props, tonne), but here's another manifestation of it which handles hex-code BGR (like what PixelGetColor returns) as well as the reverse: HSL to BGR

Code:
Hue(BGR) ; Hue: output range [0,360) float
{ ; Function by [VxE], formula from wikipedia.org/wiki/HSV_color_space
   OFF := A_FormatFloat
   SetFormat, Float, 0.16
;   pi := ATan(1) * 4
   pi := 360 / 2 ; what do you consider a full circle ? 360º or 2pi ?
   hex := pi / 3
   blue := (BGR >> 16) / 256
   green := ((BGR >> 8) & 255) / 256
   red := (BGR & 255) / 256
   max := ((blue > green) && (blue > red)) ? blue : (green > red ? green : red)
   min := ((blue < green) && (blue < red)) ? blue : (green < red ? green : red)
   If (min = max)
      res := 0
   else If (max = red)
      res := hex * ((green - blue) / (max - min))
   else If (max = green)
      res := hex * ((blue - red) / (max - min)) + 2 * hex
   else If (max = blue)
      res := hex * ((red - green) / (max - min)) + 4 * hex
   If (res >= 2 * pi )
      res -= 2 * pi
   If (res < 0 )
      res += 2 * pi
   SetFormat, Float, %OFF%
   return res
}
Code:
Sat(BGR) ; Saturation: output range [0,1)
{ ; Function by [VxE], formula from wikipedia.org/wiki/HSV_color_space
   OFF := A_FormatFloat
   SetFormat, Float, 0.16
   blue := (BGR >> 16) / 256
   green := ((BGR >> 8) & 255) / 256
   red := (BGR & 255) / 256
   max := ((blue > green) && (blue > red)) ? blue : (green > red ? green : red)
   min := ((blue < green) && (blue < red)) ? blue : (green < red ? green : red)
   lum := (min + max) / 2
   If (min = max)
      res := 0
   else If (lum <= 0.5)
      res := (max - min) / (2*lum)
   else
      res := (max - min) / (2-2*lum)
   SetFormat, Float, %OFF%
   return res
}
Code:
Lum(BGR) ; output range [0,1)
{ ; Function by [VxE], formula from wikipedia.org/wiki/HSV_color_space
   OFF := A_FormatFloat
   SetFormat, Float, 0.16
   blue := (BGR >> 16) / 256
   green := ((BGR >> 8) & 255) / 256
   red := (BGR & 255) / 256
   max := ((blue > green) && (blue > red)) ? blue : (green > red ? green : red)
   min := ((blue < green) && (blue < red)) ? blue : (green < red ? green : red)
   res := (min + max) / 2
   SetFormat, Float, %OFF%
   return res
}
Code:
HSL_to_RGB( hue, sat, lum ) ; inputs should be [0,360) : [0,1) : [0,1), output = 24b hex BGR
{ ; Function by [VxE], formula from wikipedia.org/wiki/HSV_color_space
   OFF := A_FormatFloat
   SetFormat, Float, 0.16
   If ( lum < 0.5 )
      weight := Lum + Lum * Sat
   else
      weight := Lum + Sat - Lum * Sat
   size := 2 * Lum - weight
   value := hue / 360
   red := value + 1/3 - (value > 2/3)
   green := value
   blue := value - 1/3 + (value < 1/3)

   If (blue < 1/6)
      blue := (blue * 6 * (weight - size)) + size
   else if (blue < 1/2)
      blue := weight
   else if (blue < 2/3)
      blue := ((2/3 - blue) * 6 * (weight - size)) + size
   else
      blue := size

   If (green < 1/6)
      green := (green * 6 * (weight - size)) + size
   else if (green < 1/2)
      green := weight
   else if (green < 2/3)
      green := ((2/3 - green) * 6 * (weight - size)) + size
   else
      green := size

   If (red < 1/6)
      red := (red * 6 * (weight - size)) + size
   else if (red < 1/2)
      red := weight
   else if (red < 2/3)
      red := ((2/3 - red) * 6 * (weight - size)) + size
   else
      red := size

   OIF := A_FormatInteger
   SetFormat, Integer, Hex
   ret := (Round(blue*256) << 16) | (Round(green*256) << 8) | Round(red*256)
   SetFormat, Float, %OFF%
   SetFormat, Integer, %OIF%
   ret := "0x" SubStr( "00000" SubStr(ret, 3), -5 )
   StringUpper, ret, ret
   return ret
}

And of course, the accessory function
Code:
FlipBlueAndRed(c) ; takes RGB or BGR and swaps the R and B
{
   return (c&255)<<16 | (c&65280) | (c>>16)
}

_________________
My Home Thread
Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group