Advertisement
Guest User

Untitled

a guest
Apr 26th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 7.46 KB | None | 0 0
  1. module Sampler
  2.  
  3. open System
  4.  
  5. let ran = new System.Random()
  6.  
  7.  
  8. // takes a lower and an upper-bound of a box. Returns a random value within that box
  9. let randomInBound value increment =
  10.             let lowerValue = value-increment
  11.             let mutable rnvalue = (ran.NextDouble()*((value-lowerValue))+lowerValue)
  12.             if rnvalue > value then rnvalue <- rnvalue-increment
  13.             if rnvalue < lowerValue then rnvalue <- rnvalue
  14.             rnvalue
  15.  
  16. // combines 2 arrays of values into a tupple array
  17. //should probably not use append -> should initialize empty array with listx length and just set the values.
  18. let combineXY (listx:array<float>) (listy:array<float>) =
  19.     let mutable tmp = [||]
  20.     for i in [0 .. listx.Length-1]
  21.         do
  22.         tmp <- Array.append tmp [|(listx.[i],listy.[i])|]
  23.     tmp
  24.  
  25. // Knuth shuffle on array
  26. let switch inputArray =
  27.     for x in [0 .. (Array.length inputArray)-1]
  28.         do
  29.         let randomValue = ran.Next(0, Array.length inputArray)
  30.         let tmp = inputArray.[x]
  31.         inputArray.[x] <- inputArray.[randomValue]
  32.         inputArray.[randomValue] <- tmp
  33.  
  34. // Given a natural number n produces n^2 sample points
  35. let mkRegularSample n =
  36.     let sampleSize = (float n)
  37.     let padding = (1.0-((sampleSize-1.0)/sampleSize))*0.5
  38.     let increment = 1.0/(sampleSize) // Given N produces N^2  -> Solution to get increment is 1/(n+1)
  39.     let mutable ysamplelist = [||]
  40.     let mutable xsamplelist = [||]
  41.     let addx a =
  42.         xsamplelist <- Array.append xsamplelist [|a|]
  43.     let addy b =
  44.         ysamplelist <- Array.append ysamplelist [|b|]
  45.  
  46.     for x in [padding..increment..1.0]
  47.         do
  48.         for y in [padding..increment..1.0]
  49.             do
  50.             addx(x)
  51.             addy(y)
  52.     combineXY ysamplelist xsamplelist
  53.  
  54. //assignment doesn't mention this function should return n^2, but it is assumed since all else do
  55. let mkRandomSample n =
  56.     let sampleSize = (float n)
  57.     let mutable ysamplelist = [||]
  58.     let mutable xsamplelist = [||]
  59.     let addx a =
  60.         xsamplelist <- Array.append xsamplelist [|a|]
  61.     let addy b =
  62.         ysamplelist <- Array.append ysamplelist [|b|]
  63.  
  64.     for i in [1.0 .. sampleSize**2.0]
  65.         do
  66.         let x = ran.NextDouble()
  67.         let y = ran.NextDouble()
  68.         addx(x)
  69.         addy(y)
  70.     combineXY xsamplelist ysamplelist
  71.  
  72. //
  73. let mkJitterSample n =
  74.     if n <= 0 then failwith "can't be 0 or negative" else
  75.     let sampleSize = (float n)
  76.     let increment = 1.0/(sampleSize) // Given N produces N^2  -> Solution to get increment is 1/(n+1)
  77.     let mutable ysamplelist = [||]
  78.     let mutable xsamplelist = [||]
  79.     let addx a =
  80.         xsamplelist <- Array.append xsamplelist [|a|]
  81.     let addy b =
  82.         ysamplelist <- Array.append ysamplelist [|b|]
  83.  
  84.     for x:float in [increment..increment..1.0]
  85.         do
  86.         for y in [increment..increment..1.0]
  87.             do
  88.             addx(randomInBound x increment)
  89.             addy(randomInBound y increment)
  90.     combineXY xsamplelist ysamplelist
  91.    
  92.  
  93. let mkNRookSample n =
  94.     if n <= 0 then failwith "can't be 0 or negative" else
  95.     let sampleSize = (float n)
  96.     let increment = 1.0/(sampleSize) // Solution to get increment is 1/(n+1)
  97.     let mutable ysamplelist = [||]
  98.     let mutable xsamplelist = [||]
  99.     let addx a =
  100.         xsamplelist <- Array.append xsamplelist [|a|]
  101.     let addy b =
  102.         ysamplelist <- Array.append ysamplelist [|b|]
  103.  
  104.     for y:float in [increment .. increment .. (1.0-increment)]
  105.         do
  106.         addx y
  107.         addy y
  108.    
  109.     switch xsamplelist
  110.     switch ysamplelist
  111.  
  112.     combineXY xsamplelist ysamplelist
  113.  
  114. // https://graphics.pixar.com/library/MultiJitteredSampling/paper.pdf
  115. let mkMultiJittered n =
  116.     let sampleSize = (float n)
  117.     let increment = 1.0/(sampleSize)
  118.     let inc = 1.0/(sampleSize**2.0)
  119.  
  120.     // initialize empty arrays to create clean code functions
  121.     let mutable ylist = [||]
  122.     let mutable xlist = [||]
  123.     let mutable innerLoopYcordarray = [||]
  124.     let mutable innerLoopXcordarray = [||]
  125.     let addx a =
  126.         innerLoopXcordarray <- Array.append innerLoopXcordarray [|a|]
  127.     let addy b =
  128.         innerLoopYcordarray <- Array.append innerLoopYcordarray [|b|]
  129.     let appendY c =
  130.         ylist <- Array.append ylist [|c|]
  131.     let appendX c =
  132.         xlist <- Array.append xlist [|c|]
  133.  
  134.     let mutable count = 0.0
  135.     let mutable y = 0.0
  136.  
  137.     // while loop used, because can't increment outerloop increment value in f#
  138.     while y < (1.0-inc)
  139.         do
  140.         //emptying arrays
  141.         innerLoopYcordarray <- [||]
  142.         innerLoopXcordarray <- [||]
  143.         for x:float in [(inc+count) .. increment .. 1.0]
  144.             do
  145.             y <- y + inc
  146.  
  147.             //randomize cords within a 1/n^2 box
  148.             addx (randomInBound x inc)
  149.             addy (randomInBound y inc)
  150.         count <- count + inc
  151.  
  152.         for x in innerLoopXcordarray
  153.             do
  154.             appendX x
  155.         for y in innerLoopYcordarray
  156.             do
  157.             appendY y
  158.      
  159.     let cordList = combineXY xlist ylist
  160.    
  161.     // randomize y values (n-rooks)
  162.     for i in [0 .. (n-1)]
  163.         do
  164.         for j in [0 .. (n-1)]
  165.             do
  166.             let rn = ran.Next(0, n)
  167.             let (tmpx,tmpy) = cordList.[i+(j*n)]
  168.             let (rnx,rny) = cordList.[i + (rn*n)]
  169.             cordList.[i+(n*j)] <- (rnx,tmpy)
  170.             cordList.[(rn*n)+i] <- (tmpx,rny)
  171.  
  172.      // randomize x values (n-rooks)
  173.     for i in [0 .. (n-1)]
  174.         do
  175.         for j in [0 .. (n-1)]
  176.             do
  177.             let rn = ran.Next(0, n)
  178.             let (tmpx,tmpy) = cordList.[j+(i*n)]
  179.             let (rnx,rny) = cordList.[rn + (i*n)]
  180.             cordList.[j+(n*i)] <- (rnx,tmpy)
  181.             cordList.[(i*n)+rn] <- (tmpx,rny)
  182.  
  183.     cordList
  184.    
  185.  
  186. let pibyfour = (System.Math.PI / 4.0)
  187.  
  188. let findQuarter (x,y) =
  189.     match (x,y) with
  190.     | (x,y) when (x>=y) && x>=(-y) -> (x,(pibyfour*(y/x))) //quarter 1
  191.     | (x,y) when (x<=y) && x>=(-y) -> (y,(pibyfour*(2.0-(x/y)))) //quarter 2
  192.     | (x,y) when (x<=y) && x<=(-y) -> (-x,(pibyfour*(4.0+(y/x))))// quarter 3
  193.     | (x,y) when (x>=y) && x<=(-y) -> (-y,(pibyfour*(6.0-(x/y)))) // quarter 4
  194.     | (_,_) -> failwith "Should never go here - didn't find a quarter in disc mapping"
  195.    
  196.  
  197. let discMap cordList =  
  198.  
  199.     let mutable returnList = [||]
  200.     let appendList c =
  201.         returnList <- Array.append returnList [|c|]
  202.     for (x,y) in cordList
  203.         do
  204.         // map to unitsquare size 2.0
  205.         let x = (x*2.0)-1.0
  206.         let y = (y*2.0)-1.0
  207.  
  208.         //transform and map to disc
  209.         let transformed = findQuarter (x,y)
  210.  
  211.         let a =
  212.             match transformed with
  213.             | (r,pehta) -> (System.Math.Cos(pehta)*r+1.0)/2.0
  214.         let b =
  215.             match transformed with
  216.             |(r,pehta) -> (System.Math.Sin(pehta)*r+1.0)/2.0
  217.  
  218.         appendList (a,b)
  219.  
  220.     Array.toList returnList
  221.  
  222. let hemiMap cordList =  
  223.  
  224.     let mutable returnList = [||]
  225.     let appendList c =
  226.         returnList <- Array.append returnList [|c|]
  227.  
  228.     // close to 0 means closer to Z axis?
  229.     let e = 100.0
  230.  
  231.     for (x,y) in cordList
  232.         do
  233.         //map each point to hemisphere
  234.         let a = 2.0*System.Math.PI*x
  235.         let b = System.Math.Acos((1.0-y)**(1.0/e+1.0))
  236.         appendList (Math.Sin(b)*Math.Cos(a),Math.Sin(b)*Math.Sin(a),Math.Cos(b))
  237.  
  238.     Array.toList returnList
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement