calculating ratios to find optimal grid layout - madscijr - 02-19-2025
Thanks to Steve and BPlus for helping figure out the ratio math.
I don't know if this is the most efficient code, but it seems to work...
Code: (Select All) Option _Explicit
Type LayoutType
HRatio As Single
VRatio As Single
Name As String
ColumnCount As Integer
RowCount As Integer
TargetCount As Long
CellCount As Long
EmptyCells As Long
Error As String
End Type ' LayoutType
Dim iLoop1 As Integer
Dim iLoop2 As Integer
Dim iCount As Integer
Dim iItemCount As Long
Dim iEvenCount As Long
Dim iSquareCount As Long
Dim iLayoutCount As Integer
Dim sNextName As String
Dim RatioSum As Single
Dim sngColumnCount As Single
Dim sngRowCount As Single
Dim sngRowCol As Single
Dim sRatio As String
Dim sColsRows As String
Dim sCount As String
Dim sLine As String
Dim iMaxEmpty As Long
Dim iMinEmpty As Long
Dim iNextMinEmpty As Long
Dim iIndex As Integer
Dim iSortIndex As Integer
Dim bFinished As Integer
Dim in$
' LAYOUTS
ReDim arrLayout(1 To 32) As LayoutType
ReDim arrSorted(1 To 32) As LayoutType
' INIT SCREEN
Screen _NewImage(1280, 900, 32)
_ScreenMove 0, 0
Cls , cBlack
' =============================================================================
' INITIALIZE LAYOUT OPTIONS
For iLoop1 = LBound(arrLayout) To UBound(arrLayout)
arrLayout(iLoop1).Name = ""
arrLayout(iLoop1).HRatio = 0
arrLayout(iLoop1).VRatio = 0
arrLayout(iLoop1).Error = ""
Next iLoop1
iLayoutCount = 0
Restore RatioData
Do
iLayoutCount = iLayoutCount + 1
Read arrLayout(iLayoutCount).HRatio
Read arrLayout(iLayoutCount).VRatio
Read sNextName: arrLayout(iLayoutCount).Name = Replace$(sNextName, ";", ",")
If arrLayout(iLayoutCount).HRatio = 0 Then Exit Do
Loop
RatioData:
Data 1,1,Square (profile pictures; social media)
Data 3,2,Classic 35mm (4x6; 6x9; etc.) (landscape)
Data 2,3,Classic 35mm (4x6; 6x9; etc.) (portrait)
Data 3.5,2.5,5x7 photo (landscape)
Data 2.5,3.5,5x7 photo (portrait)
Data 1.29,1,Standard letter size (8.5x11) (landscape)
Data 1,1.29,Standard letter size (8.5x11) (portrait)
Data 1.414,1,A4 paper (landscape)
Data 1,1.414,A4 paper (portrait)
Data 4,3,Older PC monitor + analog TV (640x480; 1024x768; etc.) (landscape)
Data 3,4,Older PC monitor + analog TV (640x480; 1024x768; etc.) (portrait)
Data 5,4,Art prints + medium format (8x10; 16x20) (landscape)
Data 4,5,Art prints + medium format (8x10; 16x20) (portrait)
Data 14,11,legal paper (11x14) (landscape)
Data 11,14,legal paper (11x14) (portrait)
Data 16,9,Standard HD display (1920x1080; 1280x720; etc.) (landscape)
Data 9,16,Standard HD display (1920x1080; 1280x720; etc.) (portrait)
Data 0,0,Custom (user enters ratio)
' =============================================================================
' PROMPT USER TO ENTER A NUMBER THEN CALCULATE ROWS/COLUMNS BASED ON LAYOUT RATIOS
Do
Do
Color cLtGray, cBlack
Print "-------------------------------------------------------------------------------"
Print "Grid Layouts"
Print "-------------------------------------------------------------------------------"
Input "Number of items? (0 to exit)"; in$
Print
_KeyClear: '_DELAY 1
If IsNumber%(in$) = _TRUE Then
iItemCount = Val(in$)
Exit Do
End If
Loop
If iItemCount < 1 Then Exit Do
' -----------------------------------------------------------------------------
' Get even # of items
If IsEven%(iItemCount) = _TRUE Then
iEvenCount = iItemCount
Else
iEvenCount = iItemCount + 1
End If
' -----------------------------------------------------------------------------
' Get total # of items we would need for an equal number of rows and columns
' DOES COUNT ALLOW FOR A PERFECT SQUARE?
sngRowCol = Sqr(iItemCount)
If sngRowCol = Int(sngRowCol) Then
' COUNT IS ALREADY RIGHT FOR SQUARE LAYOUT
iSquareCount = iItemCount
Else
' ADD ITEMS TO ALLOW FOR SQUARE LAYOUT
iSquareCount = iItemCount
Do
iSquareCount = iSquareCount + 1
sngRowCol = Sqr(iSquareCount)
If sngRowCol = Int(sngRowCol) Then Exit Do
Loop
End If
' -----------------------------------------------------------------------------
' DETERMINE RATIOS WITH CALCULATED NUMBER OF ROWS/COLUMNS FOR EACH
iMaxEmpty = 0
'For iLoop1 = 1 To iLayoutCount
For iLoop1 = LBound(arrLayout) To UBound(arrLayout)
' Ignore uninitialized
If arrLayout(iLoop1).HRatio > 0 And arrLayout(iLoop1).VRatio > 0 Then
arrLayout(iLoop1).Error = ""
arrLayout(iLoop1).ColumnCount = 0
arrLayout(iLoop1).RowCount = 0
arrLayout(iLoop1).TargetCount = iItemCount
arrLayout(iLoop1).CellCount = 0
arrLayout(iLoop1).EmptyCells = 0
If arrLayout(iLoop1).HRatio <= 0 Then
arrLayout(iLoop1).Error = arrLayout(iLoop1).Error + _
"Illegal value: " + _
"arrLayout(" + _TRIM$(Str$(iLoop1)) + ").HRatio = " + _
_TRIM$(Str$(arrLayout(iLoop1).HRatio)) + ". "
End If
If arrLayout(iLoop1).VRatio <= 0 Then
arrLayout(iLoop1).Error = arrLayout(iLoop1).Error + _
"Illegal value: " + _
"arrLayout(" + _TRIM$(Str$(iLoop1)) + ").VRatio = " + _
_TRIM$(Str$(arrLayout(iLoop1).VRatio)) + ". "
End If
If Len(arrLayout(iLoop1).Error) = 0 Then
' IS RATIO A PERFECT SQUARE?
If arrLayout(iLoop1).HRatio = arrLayout(iLoop1).VRatio Then
' # OF COLUMS EQUALS # ROWS
arrLayout(iLoop1).ColumnCount = Sqr(iSquareCount)
arrLayout(iLoop1).RowCount = arrLayout(iLoop1).ColumnCount
Else
' NOT A PERFECT SQUARE
sngColumnCount = Sqr(iEvenCount * (arrLayout(iLoop1).HRatio / arrLayout(iLoop1).VRatio))
sngRowCount = Sqr(iEvenCount * (arrLayout(iLoop1).VRatio / arrLayout(iLoop1).HRatio))
' DO THESE DIVIDE EVENLY?
If sngColumnCount = Int(sngColumnCount) Then
arrLayout(iLoop1).ColumnCount = Int(sngColumnCount)
Else
arrLayout(iLoop1).ColumnCount = Fix(sngColumnCount)
End If
If sngRowCount = Int(sngRowCount) Then
arrLayout(iLoop1).RowCount = Int(sngRowCount)
Else
arrLayout(iLoop1).RowCount = Fix(sngRowCount)
End If
' ENOUGH COLUMNS & ROWS?
If arrLayout(iLoop1).HRatio > arrLayout(iLoop1).VRatio Then
Do
If arrLayout(iLoop1).ColumnCount * arrLayout(iLoop1).RowCount >= iItemCount Then Exit Do
arrLayout(iLoop1).ColumnCount = arrLayout(iLoop1).ColumnCount + 1
Loop
Else
Do
If arrLayout(iLoop1).ColumnCount * arrLayout(iLoop1).RowCount >= iItemCount Then Exit Do
arrLayout(iLoop1).RowCount = arrLayout(iLoop1).RowCount + 1
Loop
End If
End If
End If
' Calculate total # of cells + empty cells
If Len(arrLayout(iLoop1).Error) = 0 Then
arrLayout(iLoop1).CellCount = arrLayout(iLoop1).ColumnCount * arrLayout(iLoop1).RowCount
arrLayout(iLoop1).EmptyCells = arrLayout(iLoop1).CellCount - arrLayout(iLoop1).TargetCount
' STORE MAXIMUM # OF EMPTY CELLS
If arrLayout(iLoop1).EmptyCells > iMaxEmpty Then
iMaxEmpty = arrLayout(iLoop1).EmptyCells
End If
End If
End If
Next iLoop1
' -----------------------------------------------------------------------------
' SORT RATIOS IN ORDER OF EMPTY CELLS
'arrLayout(iLoop1).EmptyCells = arrLayout(iLoop1).CellCount - arrLayout(iLoop1).TargetCount
' INITIALIZE SORTED LAYOUTS
For iLoop1 = LBound(arrSorted) To UBound(arrSorted)
arrSorted(iLoop1).Name = ""
arrSorted(iLoop1).HRatio = 0
arrSorted(iLoop1).VRatio = 0
arrSorted(iLoop1).Error = ""
Next iLoop1
' SORT RATIOS
bFinished = _FALSE
iSortIndex = LBound(arrSorted) - 1
iMinEmpty = iMaxEmpty + 1 ' reset min value to find
Do
' Reset compare
iNextMinEmpty = iMaxEmpty + 1 ' reset temp min value to find
iIndex = LBound(arrLayout) - 1 ' Set iIndex outside of array bounds, next smallest not found (yet)
' Find smallest empty
For iLoop1 = LBound(arrLayout) To UBound(arrLayout)
' Ignore unused
If arrLayout(iLoop1).HRatio > 0 And arrLayout(iLoop1).VRatio > 0 Then
' Ignore errors
If Len(arrLayout(iLoop1).Error) = 0 Then
' Is this the smallest yet?
If arrLayout(iLoop1).EmptyCells < iMinEmpty Then
iMinEmpty = arrLayout(iLoop1).EmptyCells ' update minimum
End If
' Is this the smallest of the ones left so far?
If arrLayout(iLoop1).EmptyCells < iNextMinEmpty Then
iNextMinEmpty = arrLayout(iLoop1).EmptyCells ' update minimum
iIndex = iLoop1 ' remember this layout
End If
End If
End If
Next iLoop1
' Add smallest to sorted
' As long as iIndex is within array bounds, we found next smallest
If iIndex >= LBound(arrLayout) Then
iSortIndex = iSortIndex + 1
If iSortIndex <= UBound(arrSorted) Then
arrSorted(iSortIndex).HRatio = arrLayout(iIndex).HRatio
arrSorted(iSortIndex).VRatio = arrLayout(iIndex).VRatio
arrSorted(iSortIndex).Name = arrLayout(iIndex).Name
arrSorted(iSortIndex).ColumnCount = arrLayout(iIndex).ColumnCount
arrSorted(iSortIndex).RowCount = arrLayout(iIndex).RowCount
arrSorted(iSortIndex).TargetCount = arrLayout(iIndex).TargetCount
arrSorted(iSortIndex).CellCount = arrLayout(iIndex).CellCount
arrSorted(iSortIndex).EmptyCells = arrLayout(iIndex).EmptyCells
arrSorted(iSortIndex).Error = ""
arrLayout(iIndex).Error = "Sorted" ' remove this from sort pool
Else
' Exceeded sorted array size, quit sorting
Exit Do
End If
Else
' Finished sorting
Exit Do
End If
Loop
' -----------------------------------------------------------------------------
' DISPLAY SORTED RESULTS
Color cLtGray, cBlack
Print "LAYOUTS FROM MOST OPTIMAL TO LEAST:"
Print
Color cWhite~&, cBlack
Print " # H-Ratio V-Ratio Columns Rows Cells Empty Layout"
Print "---- -------- -------- -------- -------- -------- -------- ------"
' 1 12345678 12345678 12345678 12345678 12345678 12345678 123456
iCount = 0
For iLoop1 = LBound(arrSorted) To UBound(arrSorted)
' Ignore unused
If arrSorted(iLoop1).HRatio > 0 And arrSorted(iLoop1).VRatio > 0 Then
iCount = iCount + 1
sCount = Right$(String$(4, " ") + _Trim$(Str$(iCount)), 4) + " "
sRatio = left$( _Trim$(Str$(arrSorted(iLoop1).HRatio)) + string$(8, " "), 8) + _
" " + _
left$( _Trim$(Str$(arrSorted(iLoop1).VRatio)) + string$(8, " "), 8) + _
" "
sColsRows = ""
sColsRows = _
right$( string$(8, " ") + _Trim$(Str$(arrSorted(iLoop1).ColumnCount)) , 8) + _
" " + _
right$( string$(8, " ") + _Trim$(Str$(arrSorted(iLoop1).RowCount)) , 8) + _
" " + _
right$( string$(8, " ") + _Trim$(Str$(arrSorted(iLoop1).CellCount)) , 8) + _
" " + _
right$( string$(8, " ") + _Trim$(Str$(arrSorted(iLoop1).EmptyCells)) , 8) + _
" "
' SHOW OPTIMAL LAYOUTS IN YELLOW, SQUARE LAYOUTS IN LIME, ALL OTHERS IN CYAN
If arrSorted(iLoop1).ColumnCount = arrSorted(iLoop1).RowCount Then
Color cLime~&, cBlack
ElseIf arrSorted(iLoop1).EmptyCells = iMinEmpty Then
Color cYellow~&, cBlack
Else
Color cCyan~&, cBlack
End If
sLine = sCount + sRatio + sColsRows + arrSorted(iLoop1).Name
Print Left$(sLine, 160)
End If
Next iLoop1
' CLEAR KEYBOARD BUFFER AND START OVER
_KeyClear: '_DELAY 1
Print
Loop
Cls: Print: Print "Finished"
End
' /////////////////////////////////////////////////////////////////////////////
' Returns TRUE if number n is even
' https://slaystudy.com/qbasic-program-to-check-if-number-is-even-or-odd/
' see also: IsOdd%
Function IsEven% (n)
If n Mod 2 = 0 Then
IsEven% = _TRUE
Else
IsEven% = _FALSE
End If
End Function ' IsEven%
' /////////////////////////////////////////////////////////////////////////////
' Returns TRUE if value OriginalString$ is numeric.
' Re: Does a Is Number function exist in QB64?
' https://www.qb64.org/forum/index.php?topic=896.15
' Version 2 by madscijr
' Returns TRUE (-1) if string is an integer, FALSE (0) if not
' Version 1 by MWheatley
' Reply #18 on: January 01, 2019, 11:24:30 AM
' returns 1 if string is an integer, 0 if not
Function IsNumber% (OriginalString$)
Dim bResult%: bResult% = _FALSE
Dim iLoop%
Dim TestString$
'Dim bNegative%
Dim iDecimalCount%
Dim sNextChar$
'THEY SHOULD TRIM OUTSIDE THE FUNCTION!
'TestString$ = _TRIM$(OriginalString$)
If Len(OriginalString$) > 0 Then
TestString$ = ""
If Left$(OriginalString$, 1) = "+" Then
TestString$ = Right$(OriginalString$, Len(OriginalString$) - 1)
'bNegative% = FALSE
ElseIf Left$(OriginalString$, 1) = "-" Then
TestString$ = Right$(OriginalString$, Len(OriginalString$) - 1)
'bNegative% = TRUE
Else
TestString$ = OriginalString$
'bNegative% = FALSE
End If
If Len(TestString$) > 0 Then
bResult% = _TRUE
iDecimalCount% = 0
For iLoop% = 1 To Len(TestString$)
sNextChar$ = Mid$(TestString$, iLoop%, 1)
If sNextChar$ = "." Then
iDecimalCount% = iDecimalCount% + 1
If iDecimalCount% > 1 Then
' TOO MANY DECIMAL POINTS, INVALID!
bResult% = _FALSE
Exit For
End If
ElseIf Asc(sNextChar$) < 48 Or Asc(sNextChar$) > 57 Then
' NOT A NUMERAL OR A DECIMAL, INVALID!
bResult% = _FALSE
Exit For
End If
Next iLoop%
End If
End If
IsNumber% = bResult%
End Function ' IsNumber%
' /////////////////////////////////////////////////////////////////////////////
' FROM: String Manipulation
' found at abandoned, outdated and now likely malicious qb64 dot net website
' http://www.qb64.[net]/forum/index_topic_5964-0/
'
'SUMMARY:
' Purpose: A library of custom functions that transform strings.
' Author: Dustinian Camburides (dustinian@gmail.com)
' Platform: QB64 (www.qb64.org)
' Revision: 1.6
' Updated: 5/28/2012
'SUMMARY:
'[Replace$] replaces all instances of the [Find] sub-string with the [Add] sub-string within the [Text] string.
'INPUT:
'Text: The input string; the text that's being manipulated.
'Find: The specified sub-string; the string sought within the [Text] string.
'Add: The sub-string that's being added to the [Text] string.
Function Replace$ (Text1 As String, Find1 As String, Add1 As String)
' VARIABLES:
Dim Text2 As String
Dim Find2 As String
Dim Add2 As String
Dim lngLocation As Long ' The address of the [Find] substring within the [Text] string.
Dim strBefore As String ' The characters before the string to be replaced.
Dim strAfter As String ' The characters after the string to be replaced.
' INITIALIZE:
' MAKE COPIESSO THE ORIGINAL IS NOT MODIFIED (LIKE ByVal IN VBA)
Text2 = Text1
Find2 = Find1
Add2 = Add1
lngLocation = InStr(1, Text2, Find2)
' PROCESSING:
' While [Find2] appears in [Text2]...
While lngLocation
' Extract all Text2 before the [Find2] substring:
strBefore = Left$(Text2, lngLocation - 1)
' Extract all text after the [Find2] substring:
strAfter = Right$(Text2, ((Len(Text2) - (lngLocation + Len(Find2) - 1))))
' Return the substring:
Text2 = strBefore + Add2 + strAfter
' Locate the next instance of [Find2]:
lngLocation = InStr(1, Text2, Find2)
' Next instance of [Find2]...
Wend
' OUTPUT:
Replace$ = Text2
End Function ' Replace$
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' BEGIN TEXT MODE COLOR CODE FUNCTIONS
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function cBlackT%
cBlackT% = 0
End Function
Function cBlueT%
cBlueT% = 1
End Function
Function cGreenT%
cGreenT% = 2
End Function
Function cLtBlueT%
cLtBlueT% = 3
End Function
Function cRedT%
cRedT% = 4
End Function
Function cPurpleT%
cPurpleT% = 5
End Function
Function cOrangeT%
cOrangeT% = 6
End Function
Function cWhiteT%
cWhiteT% = 7
End Function
Function cGrayT%
cGrayT% = 8
End Function
Function cPeriwinkleT%
cPeriwinkleT% = 9
End Function
Function cLtGreenT%
cLtGreenT% = 10
End Function
Function cCyanT%
cCyanT% = 11
End Function
Function cLtRedT%
cLtRedT% = 12
End Function
Function cPinkT%
cPinkT% = 13
End Function
Function cYellowT%
cYellowT% = 14
End Function
Function cLtGrayT%
cLtGrayT% = 15
End Function
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' END TEXT MODE COLOR CODE FUNCTIONS
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' BEGIN RGB COLOR FUNCTIONS #RGB
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function cRed~& ()
cRed = _RGB32(255, 0, 0)
End Function
Function cOrangeRed~& ()
cOrangeRed = _RGB32(255, 69, 0)
End Function ' cOrangeRed~&
Function cDarkOrange~& ()
cDarkOrange = _RGB32(255, 140, 0)
End Function ' cDarkOrange~&
Function cOrange~& ()
cOrange = _RGB32(255, 165, 0)
End Function ' cOrange~&
Function cGold~& ()
cGold = _RGB32(255, 215, 0)
End Function ' cGold~&
Function cYellow~& ()
cYellow = _RGB32(255, 255, 0)
End Function ' cYellow~&
' LONG-HAIRED FRIENDS OF JESUS OR NOT,
' THIS IS NOT YELLOW ENOUGH (TOO CLOSE TO LIME)
' TO USE FOR OUR COMPLEX RAINBOW SEQUENCE:
Function cChartreuse~& ()
cChartreuse = _RGB32(127, 255, 0)
End Function ' cChartreuse~&
' WE SUBSTITUTE THIS CSS3 COLOR FOR INBETWEEN LIME AND YELLOW:
Function cOliveDrab1~& ()
cOliveDrab1 = _RGB32(192, 255, 62)
End Function ' cOliveDrab1~&
Function cLime~& ()
cLime = _RGB32(0, 255, 0)
End Function ' cLime~&
Function cMediumSpringGreen~& ()
cMediumSpringGreen = _RGB32(0, 250, 154)
End Function ' cMediumSpringGreen~&
' ADDED THIS FOR THE GAUGE COLOR:
Function cSpringGreen~& ()
cSpringGreen = _RGB32(0, 255, 160)
End Function ' cSpringGreen~&
Function cCyan~& ()
cCyan = _RGB32(0, 255, 255)
End Function ' cCyan~&
Function cDeepSkyBlue~& ()
cDeepSkyBlue = _RGB32(0, 191, 255)
End Function ' cDeepSkyBlue~&
Function cDodgerBlue~& ()
cDodgerBlue = _RGB32(30, 144, 255)
End Function ' cDodgerBlue~&
Function cSeaBlue~& ()
cSeaBlue = _RGB32(0, 64, 255)
End Function ' cSeaBlue~&
Function cBlue~& ()
cBlue = _RGB32(0, 0, 255)
End Function ' cBlue~&
Function cBluePurple~& ()
cBluePurple = _RGB32(64, 0, 255)
End Function ' cBluePurple~&
Function cDeepPurple~& ()
cDeepPurple = _RGB32(96, 0, 255)
End Function ' cDeepPurple~&
Function cPurple~& ()
cPurple = _RGB32(128, 0, 255)
End Function ' cPurple~&
Function cPurpleRed~& ()
cPurpleRed = _RGB32(128, 0, 192)
End Function ' cPurpleRed~&
Function cDarkRed~& ()
cDarkRed = _RGB32(160, 0, 64)
End Function ' cDarkRed~&
Function cBrickRed~& ()
cBrickRed = _RGB32(192, 0, 32)
End Function ' cBrickRed~&
Function cDarkGreen~& ()
cDarkGreen = _RGB32(0, 100, 0)
End Function ' cDarkGreen~&
Function cGreen~& ()
cGreen = _RGB32(0, 128, 0)
End Function ' cGreen~&
Function cOliveDrab~& ()
cOliveDrab = _RGB32(107, 142, 35)
End Function ' cOliveDrab~&
Function cLightPink~& ()
cLightPink = _RGB32(255, 182, 193)
End Function ' cLightPink~&
Function cHotPink~& ()
cHotPink = _RGB32(255, 105, 180)
End Function ' cHotPink~&
Function cDeepPink~& ()
cDeepPink = _RGB32(255, 20, 147)
End Function ' cDeepPink~&
Function cMagenta~& ()
cMagenta = _RGB32(255, 0, 255)
End Function ' cMagenta~&
Function cBlack~& ()
cBlack = _RGB32(0, 0, 0)
End Function ' cBlack~&
Function cDimGray~& ()
cDimGray = _RGB32(105, 105, 105)
End Function ' cDimGray~&
Function cGray~& ()
cGray = _RGB32(128, 128, 128)
End Function ' cGray~&
Function cDarkGray~& ()
cDarkGray = _RGB32(169, 169, 169)
End Function ' cDarkGray~&
Function cSilver~& ()
cSilver = _RGB32(192, 192, 192)
End Function ' cSilver~&
Function cLtGray~& ()
cLtGray~& = cLightGray~&
End Function ' cLtGray~&
Function cLightGray~& ()
cLightGray = _RGB32(211, 211, 211)
End Function ' cLightGray~&
Function cGainsboro~& ()
cGainsboro = _RGB32(220, 220, 220)
End Function ' cGainsboro~&
Function cWhiteSmoke~& ()
cWhiteSmoke = _RGB32(245, 245, 245)
End Function ' cWhiteSmoke~&
Function cWhite~& ()
cWhite = _RGB32(255, 255, 255)
'cWhite = _RGB32(254, 254, 254)
End Function ' cWhite~&
Function cDarkBrown~& ()
cDarkBrown = _RGB32(128, 64, 0)
End Function ' cDarkBrown~&
Function cLightBrown~& ()
cLightBrown = _RGB32(196, 96, 0)
End Function ' cLightBrown~&
Function cKhaki~& ()
cKhaki = _RGB32(240, 230, 140)
End Function ' cKhaki~&
Function cEmpty~& ()
'cEmpty~& = -1
cEmpty = _RGB32(0, 0, 0, 0)
End Function ' cEmpty~&
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' END RGB COLOR FUNCTIONS @RGB
' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
RE: calculating ratios to find optimal grid layout - SMcNeill - 02-20-2025
I have no idea what this is supposed to do.
I type in: 5 Items
It matches a 16:9 ratio, with a 5x1 grid.
A 5x1 grid isn't a 16:9 ratio.
What exactly is this supposed to be doing here?
RE: calculating ratios to find optimal grid layout - madscijr - 02-20-2025
(02-20-2025, 01:51 AM)SMcNeill Wrote: I have no idea what this is supposed to do.
I type in: 5 Items
It matches a 16:9 ratio, with a 5x1 grid.
A 5x1 grid isn't a 16:9 ratio.
What exactly is this supposed to be doing here? 5 is too few. Try 40 or 100 or 500.
I should probably add a "use case"...
The ultimate goal is to select a folder containing large number of pictures, and the program will automatically stitch them together into a big poster you can print or use as a screensaver or display on one of those "frame" TVs. Based on the number of pics, it determines how many will fit in different layouts and aspect ratios.
This is just version 1, it assumes pictures are all a uniform size & orientation, it doesn't yet take into account pictures being rectangular or horizontal vs up & down.
Anyway that's what I was designing this for.
RE: calculating ratios to find optimal grid layout - madscijr - 02-20-2025
(02-20-2025, 01:51 AM)SMcNeill Wrote: I have no idea what this is supposed to do.
I type in: 5 Items
It matches a 16:9 ratio, with a 5x1 grid.
A 5x1 grid isn't a 16:9 ratio.
What exactly is this supposed to be doing here? For example, say you have 15 pictures. You might want to lay those out to fit a picture frame in vertical orientation. Say the ratio of horizontal to vertical is 3:5.
So the pictures would be arranged as a 3x5 grid, like
01 02 03
04 05 06
07 08 09
10 11 12
13 14 15
If you wanted a horizontal orientation, the ratio now becomes 5:3, a 5x3 grid, like
01 02 03 04 05
06 07 08 09 10
11 12 13 14 15
If you had a square frame, you would arrange them in a 4x4 grid:
01 02 03 04
05 06 07 08
09 10 11 12
13 14 15 XX
where the last space is empty.
Depending on the # of pictures that need to be arranged, that number is going to more evenly fit into some picture frames' aspect ratios better than others, i.e., a perfect fit would mean no spaces are left empty, but 1 space left empty is better than 2 or more.
So what this program does is, given a count representing the # of pictures (or items), it displays how evenly that many items are going to fit into different aspect ratios, in order of the best fit (least empty spaces) to the worse (most empty spaces).
As a tool it helps you decide what aspect ratio picture frame to get to display a given # of pictures, or if the frame or screen size's aspect ratio is already determined, it lets you know how many pictures you would need to add or remove for a perfect fit (if needed).
RE: calculating ratios to find optimal grid layout - PhilOfPerth - 02-20-2025
(02-20-2025, 09:58 PM)madscijr Wrote: (02-20-2025, 01:51 AM)SMcNeill Wrote: I have no idea what this is supposed to do.
I type in: 5 Items
It matches a 16:9 ratio, with a 5x1 grid.
A 5x1 grid isn't a 16:9 ratio.
What exactly is this supposed to be doing here? For example, say you have 15 pictures. You might want to lay those out to fit a picture frame in vertical orientation. Say the ratio of horizontal to vertical is 3:5.
So the pictures would be arranged as a 3x5 grid, like
01 02 03
04 05 06
07 08 09
10 11 12
13 14 15
If you wanted a horizontal orientation, the ratio now becomes 5:3, a 5x3 grid, like
01 02 03 04 05
06 07 08 09 10
11 12 13 14 15
If you had a square frame, you would arrange them in a 4x4 grid:
01 02 03 04
05 06 07 08
09 10 11 12
13 14 15 XX
where the last space is empty.
Depending on the # of pictures that need to be arranged, that number is going to more evenly fit into some picture frames' aspect ratios better than others, i.e., a perfect fit would mean no spaces are left empty, but 1 space left empty is better than 2 or more.
So what this program does is, given a count representing the # of pictures (or items), it displays how evenly that many items are going to fit into different aspect ratios, in order of the best fit (least empty spaces) to the worse (most empty spaces).
As a tool it helps you decide what aspect ratio picture frame to get to display a given # of pictures, or if the frame or screen size's aspect ratio is already determined, it lets you know how many pictures you would need to add or remove for a perfect fit (if needed).
A good, clear explanation of something that I for one have tried to do several times, with limited success.
I await with bated breath a simple (and brief) rendition.
RE: calculating ratios to find optimal grid layout - madscijr - 02-20-2025
(02-20-2025, 10:33 PM)PhilOfPerth Wrote: (02-20-2025, 09:58 PM)madscijr Wrote: (02-20-2025, 01:51 AM)SMcNeill Wrote: I have no idea what this is supposed to do.
...
What exactly is this supposed to be doing here? For example, say you have 15 picture
...
it lets you know how many pictures you would need to add or remove for a perfect fit (if needed).
A good, clear explanation of something that I for one have tried to do several times, with limited success.
I await with bated breath a simple (and brief) rendition.  Thanks for the warm / enthusiastic response! I think I frustrated poor Steve and if that was the only reaction I was going to get, I'd feel like I need to hire a writer to better explain my programs, LoL.
The real trick is going to be figuring that out for a mixed bag of pictures of different orientations (up/down or longways) and sizes. Currently version 1 assumes all of a uniform size and perfectly square. It shouldn't be too hard to modify to handle non-square (where all are the same orientation), but I haven't yet thought about mixed orientation or size, or a good way to automatically arrange them so as to fit best AND be aesthetically pleasing (not too random but not too regular). I have a feeling that could open a Pandora's box of sub-problems, so my current plan is to present as simple a layout as possible, then let the user tweak it by moving the pictures around with the mouse...
EDIT: removed extraneous quoting to preserve mouse wheels and people's eyes and sanity
RE: calculating ratios to find optimal grid layout - PhilOfPerth - 02-21-2025
(02-20-2025, 11:33 PM)madscijr Wrote: (02-20-2025, 10:33 PM)PhilOfPerth Wrote: (02-20-2025, 09:58 PM)madscijr Wrote: For example, say you have 15 pictures. You might want to lay those out to fit a picture frame in vertical orientation. Say the ratio of horizontal to vertical is 3:5.
So the pictures would be arranged as a 3x5 grid, like
01 02 03
04 05 06
07 08 09
10 11 12
13 14 15
If you wanted a horizontal orientation, the ratio now becomes 5:3, a 5x3 grid, like
01 02 03 04 05
06 07 08 09 10
11 12 13 14 15
If you had a square frame, you would arrange them in a 4x4 grid:
01 02 03 04
05 06 07 08
09 10 11 12
13 14 15 XX
where the last space is empty.
Depending on the # of pictures that need to be arranged, that number is going to more evenly fit into some picture frames' aspect ratios better than others, i.e., a perfect fit would mean no spaces are left empty, but 1 space left empty is better than 2 or more.
So what this program does is, given a count representing the # of pictures (or items), it displays how evenly that many items are going to fit into different aspect ratios, in order of the best fit (least empty spaces) to the worse (most empty spaces).
As a tool it helps you decide what aspect ratio picture frame to get to display a given # of pictures, or if the frame or screen size's aspect ratio is already determined, it lets you know how many pictures you would need to add or remove for a perfect fit (if needed).
Yeah, well... good luck with that!
A good, clear explanation of something that I for one have tried to do several times, with limited success.
I await with bated breath a simple (and brief) rendition.  Thanks for the warm / enthusiastic response! I think I frustrated poor Steve and if that was the only reaction I was going to get, I'd feel like I need to hire a writer to better explain my programs, LoL.
The real trick is going to be figuring that out for a mixed bag of pictures of different orientations (up/down or longways) and sizes. Currently version 1 assumes all of a uniform size and perfectly square. It shouldn't be too hard to modify to handle non-square (where all are the same orientation), but I haven't yet thought about mixed orientation or size, or a good way to automatically arrange them so as to fit best AND be aesthetically pleasing (not too random but not too regular). I have a feeling that could open a Pandora's box of sub-problems, so my current plan is to present as simple a layout as possible, then let the user tweak it by moving the pictures around with the mouse...
RE: calculating ratios to find optimal grid layout - bplus - 02-21-2025
(Yesterday, 11:13 AM)PhilOfPerth Wrote: (02-20-2025, 11:33 PM)madscijr Wrote: (02-20-2025, 10:33 PM)PhilOfPerth Wrote: Yeah, well... good luck with that!
A good, clear explanation of something that I for one have tried to do several times, with limited success.
I await with bated breath a simple (and brief) rendition.  Thanks for the warm / enthusiastic response! I think I frustrated poor Steve and if that was the only reaction I was going to get, I'd feel like I need to hire a writer to better explain my programs, LoL.
The real trick is going to be figuring that out for a mixed bag of pictures of different orientations (up/down or longways) and sizes. Currently version 1 assumes all of a uniform size and perfectly square. It shouldn't be too hard to modify to handle non-square (where all are the same orientation), but I haven't yet thought about mixed orientation or size, or a good way to automatically arrange them so as to fit best AND be aesthetically pleasing (not too random but not too regular). I have a feeling that could open a Pandora's box of sub-problems, so my current plan is to present as simple a layout as possible, then let the user tweak it by moving the pictures around with the mouse...
Good example of bad over quoting! are you guys doing this on purpose?
RE: calculating ratios to find optimal grid layout - SMcNeill - 02-21-2025
Seems to me that what you have here is a simple less than/greater than comparison.
Take your ratio and multiple that out. For example 2 x 3 = 6... you can put six or fewer items in a 2 x 3 grid. Anything more than that won't work without doubling up.
So the initial compare is easy... But how do you figure out how close you can come if you do double up that ratio? For example, you have 23 items?
You multiply that value by (x ^ 2) and see what fits.
Say a 1 x 1 grid. 1 * 1 = 1. You can put 1 item in that grid.
2 * 2 = 4. (1 * 2 ^ 2)
3 * 3 = 9 (1 * 3 ^ 2)
4 * 4 = 16 (1 * 4 ^ 2)
All of the above layouts are too small to fit 23 items.
5 * 5 = 25 (1 * 5 ^ 2)
Now 25 is larger than 23, so you can put your 23 items there and have 2 spaces left over.
Same way for a 2 x 3 ratio. The base is 6.
2 * 3 = 6
4 * 6 = 24 ( 6 * 2 ^ 2)
You can put your 23 items in a 4 * 6 grid.
It's a simple DO loop of comparisons where you just increment the base by x ^ 2 until it's larger than your number of items.
If you want to see what stores your numbers the most efficiently, just compare the difference in your total grid number - the number of items and save it.
For example, of the above you have 23 items:
in a 5 * 5 grid (which is based off the 1 x 1 ratio), you could have 25 items. The difference is 2 unused spots.
In a 4 * 6 grid (which is based off the 2 x 3 ratio), you could have 24 items. The difference is 1 unused spot.
The 4x6 would be more efficient at showing all your items than the 5x5 would be, with fewer blank spaces afterwards.
Just simple multiplication and equality comparison, with a little subtraction to get your leftover spots.
RE: calculating ratios to find optimal grid layout - madscijr - 02-21-2025
(Yesterday, 11:53 AM)bplus Wrote: Good example of bad over quoting! are you guys doing this on purpose?
Ha!
The editor does it for you when you hit 'reply', then it's a pain to edit it all back out if you're in a hurry, especially if you're replying using a smartphone with a tiny little screen.
It would be cool if the forum had some handy checkbox or something next to the reply button, to choose "only quote what the person wrote most recently instead of the whole damn thread", LOL
|