Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module Sampler
- open System
- let ran = new System.Random()
- // takes a lower and an upper-bound of a box. Returns a random value within that box
- let randomInBound value increment =
- let lowerValue = value-increment
- let mutable rnvalue = (ran.NextDouble()*((value-lowerValue))+lowerValue)
- if rnvalue > value then rnvalue <- rnvalue-increment
- if rnvalue < lowerValue then rnvalue <- rnvalue
- rnvalue
- // combines 2 arrays of values into a tupple array
- //should probably not use append -> should initialize empty array with listx length and just set the values.
- let combineXY (listx:array<float>) (listy:array<float>) =
- let mutable tmp = [||]
- for i in [0 .. listx.Length-1]
- do
- tmp <- Array.append tmp [|(listx.[i],listy.[i])|]
- tmp
- // Knuth shuffle on array
- let switch inputArray =
- for x in [0 .. (Array.length inputArray)-1]
- do
- let randomValue = ran.Next(0, Array.length inputArray)
- let tmp = inputArray.[x]
- inputArray.[x] <- inputArray.[randomValue]
- inputArray.[randomValue] <- tmp
- // Given a natural number n produces n^2 sample points
- let mkRegularSample n =
- let sampleSize = (float n)
- let padding = (1.0-((sampleSize-1.0)/sampleSize))*0.5
- let increment = 1.0/(sampleSize) // Given N produces N^2 -> Solution to get increment is 1/(n+1)
- let mutable ysamplelist = [||]
- let mutable xsamplelist = [||]
- let addx a =
- xsamplelist <- Array.append xsamplelist [|a|]
- let addy b =
- ysamplelist <- Array.append ysamplelist [|b|]
- for x in [padding..increment..1.0]
- do
- for y in [padding..increment..1.0]
- do
- addx(x)
- addy(y)
- combineXY ysamplelist xsamplelist
- //assignment doesn't mention this function should return n^2, but it is assumed since all else do
- let mkRandomSample n =
- let sampleSize = (float n)
- let mutable ysamplelist = [||]
- let mutable xsamplelist = [||]
- let addx a =
- xsamplelist <- Array.append xsamplelist [|a|]
- let addy b =
- ysamplelist <- Array.append ysamplelist [|b|]
- for i in [1.0 .. sampleSize**2.0]
- do
- let x = ran.NextDouble()
- let y = ran.NextDouble()
- addx(x)
- addy(y)
- combineXY xsamplelist ysamplelist
- //
- let mkJitterSample n =
- if n <= 0 then failwith "can't be 0 or negative" else
- let sampleSize = (float n)
- let increment = 1.0/(sampleSize) // Given N produces N^2 -> Solution to get increment is 1/(n+1)
- let mutable ysamplelist = [||]
- let mutable xsamplelist = [||]
- let addx a =
- xsamplelist <- Array.append xsamplelist [|a|]
- let addy b =
- ysamplelist <- Array.append ysamplelist [|b|]
- for x:float in [increment..increment..1.0]
- do
- for y in [increment..increment..1.0]
- do
- addx(randomInBound x increment)
- addy(randomInBound y increment)
- combineXY xsamplelist ysamplelist
- let mkNRookSample n =
- if n <= 0 then failwith "can't be 0 or negative" else
- let sampleSize = (float n)
- let increment = 1.0/(sampleSize) // Solution to get increment is 1/(n+1)
- let mutable ysamplelist = [||]
- let mutable xsamplelist = [||]
- let addx a =
- xsamplelist <- Array.append xsamplelist [|a|]
- let addy b =
- ysamplelist <- Array.append ysamplelist [|b|]
- for y:float in [increment .. increment .. (1.0-increment)]
- do
- addx y
- addy y
- switch xsamplelist
- switch ysamplelist
- combineXY xsamplelist ysamplelist
- // https://graphics.pixar.com/library/MultiJitteredSampling/paper.pdf
- let mkMultiJittered n =
- let sampleSize = (float n)
- let increment = 1.0/(sampleSize)
- let inc = 1.0/(sampleSize**2.0)
- // initialize empty arrays to create clean code functions
- let mutable ylist = [||]
- let mutable xlist = [||]
- let mutable innerLoopYcordarray = [||]
- let mutable innerLoopXcordarray = [||]
- let addx a =
- innerLoopXcordarray <- Array.append innerLoopXcordarray [|a|]
- let addy b =
- innerLoopYcordarray <- Array.append innerLoopYcordarray [|b|]
- let appendY c =
- ylist <- Array.append ylist [|c|]
- let appendX c =
- xlist <- Array.append xlist [|c|]
- let mutable count = 0.0
- let mutable y = 0.0
- // while loop used, because can't increment outerloop increment value in f#
- while y < (1.0-inc)
- do
- //emptying arrays
- innerLoopYcordarray <- [||]
- innerLoopXcordarray <- [||]
- for x:float in [(inc+count) .. increment .. 1.0]
- do
- y <- y + inc
- //randomize cords within a 1/n^2 box
- addx (randomInBound x inc)
- addy (randomInBound y inc)
- count <- count + inc
- for x in innerLoopXcordarray
- do
- appendX x
- for y in innerLoopYcordarray
- do
- appendY y
- let cordList = combineXY xlist ylist
- // randomize y values (n-rooks)
- for i in [0 .. (n-1)]
- do
- for j in [0 .. (n-1)]
- do
- let rn = ran.Next(0, n)
- let (tmpx,tmpy) = cordList.[i+(j*n)]
- let (rnx,rny) = cordList.[i + (rn*n)]
- cordList.[i+(n*j)] <- (rnx,tmpy)
- cordList.[(rn*n)+i] <- (tmpx,rny)
- // randomize x values (n-rooks)
- for i in [0 .. (n-1)]
- do
- for j in [0 .. (n-1)]
- do
- let rn = ran.Next(0, n)
- let (tmpx,tmpy) = cordList.[j+(i*n)]
- let (rnx,rny) = cordList.[rn + (i*n)]
- cordList.[j+(n*i)] <- (rnx,tmpy)
- cordList.[(i*n)+rn] <- (tmpx,rny)
- cordList
- let pibyfour = (System.Math.PI / 4.0)
- let findQuarter (x,y) =
- match (x,y) with
- | (x,y) when (x>=y) && x>=(-y) -> (x,(pibyfour*(y/x))) //quarter 1
- | (x,y) when (x<=y) && x>=(-y) -> (y,(pibyfour*(2.0-(x/y)))) //quarter 2
- | (x,y) when (x<=y) && x<=(-y) -> (-x,(pibyfour*(4.0+(y/x))))// quarter 3
- | (x,y) when (x>=y) && x<=(-y) -> (-y,(pibyfour*(6.0-(x/y)))) // quarter 4
- | (_,_) -> failwith "Should never go here - didn't find a quarter in disc mapping"
- let discMap cordList =
- let mutable returnList = [||]
- let appendList c =
- returnList <- Array.append returnList [|c|]
- for (x,y) in cordList
- do
- // map to unitsquare size 2.0
- let x = (x*2.0)-1.0
- let y = (y*2.0)-1.0
- //transform and map to disc
- let transformed = findQuarter (x,y)
- let a =
- match transformed with
- | (r,pehta) -> (System.Math.Cos(pehta)*r+1.0)/2.0
- let b =
- match transformed with
- |(r,pehta) -> (System.Math.Sin(pehta)*r+1.0)/2.0
- appendList (a,b)
- Array.toList returnList
- let hemiMap cordList =
- let mutable returnList = [||]
- let appendList c =
- returnList <- Array.append returnList [|c|]
- // close to 0 means closer to Z axis?
- let e = 100.0
- for (x,y) in cordList
- do
- //map each point to hemisphere
- let a = 2.0*System.Math.PI*x
- let b = System.Math.Acos((1.0-y)**(1.0/e+1.0))
- appendList (Math.Sin(b)*Math.Cos(a),Math.Sin(b)*Math.Sin(a),Math.Cos(b))
- Array.toList returnList
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement