Hi once more. Yesterday I needed such code and remembered I've already wrote it many years ago, so here it is reanimated and ported to PB ^^
Rarely but might be useful. Also I don't know how exactly such algorithm is called (nor exists it or not).
EnableExplicit
; (c) Lunasole 2000x-don't-remember-exactly
; Value a number to fit, can be >= 0
; RETURN: none, the X and Y sizes of matrix returned byref
Procedure AmountToMatrix (Value, *OutX.Integer, *OutY.Integer)
Protected.d SamplesDiff ; can use integer instead, result will be "more square" but less optimal
*OutY\i = Int(Sqr(Value))
*OutX\i = *OutY\i
If Pow(*OutY\i, 2) < Value
SamplesDiff = 0.4 + (Value - Pow(*OutY\i, 2)) / *OutY\i
If Mod(SamplesDiff, 2) = 0
*OutX\i = *OutY\i + SamplesDiff / 2
*OutY\i = *OutY\i + SamplesDiff / 2
Else
*OutX\i = *OutY\i + SamplesDiff
EndIf
EndIf
EndProcedure
; Example
; assume you have 5000 files
Define inFilesCnt = 5000
; and need to place them using box-like order for some reason ^^
Define SamplesX, SamplesY
; that thing does something like that
AmountToMatrix(inFilesCnt, @SamplesX, @SamplesY)
Debug Str(inFilesCnt) + " files may be ordered using " + Str(SamplesX) + "x" + Str(SamplesY) + " matrix"
EnableExplicit
; Value a number to fit, can be >= 0
; *OutX, OutY in/out values. input must be zero to be calculated
; UseInt if true, use rounding to estimate diff (this affects results on auto-calculation)
; RETURN: none, the X and Y sizes of matrix returned byref
Procedure AmountToMatrix (Value, *OutX.Integer, *OutY.Integer, UseInt = #False)
Protected.d SamplesDiff
If *OutX\i = 0 And *OutY\i = 0 ; both X and Y are 0
*OutY\i = Int(Sqr(Value))
*OutX\i = *OutY\i
If Pow(*OutY\i, 2) < Value
If UseInt
SamplesDiff = Round(0.4 + (Value - Pow(*OutY\i, 2)) / *OutY\i, #PB_Round_Nearest)
Else
SamplesDiff = 0.4 + (Value - Pow(*OutY\i, 2)) / *OutY\i
EndIf
If Mod(SamplesDiff, 2) = 0
*OutX\i = *OutY\i + SamplesDiff / 2
*OutY\i = *OutY\i + SamplesDiff / 2
Else
*OutX\i = *OutY\i + SamplesDiff
EndIf
EndIf
ElseIf *OutX\i And Not *OutY\i ; user defined X size, but not Y
*OutY\i = Round(Value / *OutX\i, #PB_Round_Up)
ElseIf *OutY\i And Not *OutX\i ; user defined Y size, but not X
*OutX\i = Round(Value / *OutY\i, #PB_Round_Up)
EndIf
EndProcedure
; Example
; assume you have 5000 files
Define inFilesCnt = 5000
; and need to place them using box-like order for some reason ^^
Define SamplesX = 0, SamplesY = 0
; that thing does something like that
AmountToMatrix(inFilesCnt, @SamplesX, @SamplesY, #False)
Debug Str(inFilesCnt) + " files may be ordered using " + Str(SamplesX) + "x" + Str(SamplesY) + " matrix"
; ... and need to place them using box-like order for some reason.
FileNumber = 5000
result.i = Round(Sqr(FileNumber), #PB_Round_Up)
; test
Debug result
Debug result * result
- It was too lonely at the top.
System : PB 6.21(x64) and Win 11 Pro (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
i just realized that you can do it also without the IFs
if the decimal part of Sqr(n) is > 0.5 then x and y need to be the same (rounded up) and if the decimal part is > 0.0 and <= 0.5 then you can reduce one of the dimensions.
you can achive this easily by using round-up for one dimension and round-nearest for the other one.