{"id":33,"date":"2012-07-07T05:40:53","date_gmt":"2012-07-07T05:40:53","guid":{"rendered":"https:\/\/davidmazz.com\/?page_id=33"},"modified":"2015-12-16T07:34:50","modified_gmt":"2015-12-16T07:34:50","slug":"wave-simulation","status":"publish","type":"page","link":"https:\/\/davidmazz.com\/?page_id=33","title":{"rendered":"Wave simulation"},"content":{"rendered":"<div style=\"width: 640px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-33-1\" width=\"640\" height=\"480\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/davidmazz.com\/wp-content\/uploads\/2012\/07\/ocean.mp4?_=1\" \/><a href=\"https:\/\/davidmazz.com\/wp-content\/uploads\/2012\/07\/ocean.mp4\">https:\/\/davidmazz.com\/wp-content\/uploads\/2012\/07\/ocean.mp4<\/a><\/video><\/div>\n<p><a href=\"https:\/\/davidmazz.com\/downloads\/Ocean.hipnc\">Download Houdini Project File (46K)<\/a><\/p>\n<p>This was a project I completed for my Computer Animation and Simulation class during my last semester at USC. Going into this project, I did knew neither Python nor Houdini, and I had never attempted an implementation of Perlin Noise before. This took about 2.5 weeks to complete. Source code below:<\/p>\n<pre><pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nimport random\r\nimport math\r\nimport hou\r\n\r\nNUM_GRIDPTS = 1024\r\nsqrt_gridpts = int(math.sqrt(NUM_GRIDPTS))\r\nlastIterationTime = 0.0\r\n\r\nmaxTimes =  &#x5B;0.001, 0.101, 0.501, 1.801, 4.001]\r\nscales =    &#x5B;0.001, 0.071, 0.301, 1.001, 4.001]\r\ncurrentTimes = maxTimes&#x5B;:]\r\nNUM_OCTAVES = len(maxTimes)-1\r\npoints = &#x5B;0.0]*NUM_GRIDPTS        #current point\r\nendPoints = &#x5B;&#x5B;0.0]*NUM_GRIDPTS for x in xrange(NUM_OCTAVES+1)]     #target point\r\nstartPoints = &#x5B;&#x5B;0.0]*NUM_GRIDPTS for x in xrange(NUM_OCTAVES+1)] #last target point\r\n\r\n#seed the rng with pointNum and time\r\ndef doRandomSeed(pointNum):\r\n    x = pointNum % sqrt_gridpts\r\n    z = pointNum \/ sqrt_gridpts\r\n    t = hou.time()\r\n    random.seed(x*x*x + z*z + t)\r\n\r\n#lerps points to endPoints\r\ndef interpolatePoints():\r\n    index = 0\r\n    fractions = &#x5B;0.0]*(NUM_OCTAVES+1)\r\n    for time in range (1, NUM_OCTAVES+1):\r\n        fractions&#x5B;time] = currentTimes&#x5B;time] \/ maxTimes&#x5B;time]\r\n\r\n    for p in points:\r\n        for o in range(1, NUM_OCTAVES+1):\r\n            points&#x5B;index] += interpolate(startPoints&#x5B;o]&#x5B;index], endPoints&#x5B;o]&#x5B;index], fractions&#x5B;o])\r\n        index += 1\r\n\r\n#computes endPoints in a given octave\r\ndef computeOctave(octNum):\r\n    startPoints&#x5B;octNum] = endPoints&#x5B;octNum]&#x5B;:]\r\n    invFreq = pow(2, octNum)\r\n    x = invFreq \/ 2\r\n    z = invFreq \/ 2\r\n    index = z*sqrt_gridpts + x\r\n\r\n    while(index &amp;lt; NUM_GRIDPTS):         \r\n        doRandomSeed(index)         \r\n        endPoints&#x5B;octNum]&#x5B;index] = (random.random()-0.5) * scales&#x5B;octNum]         \r\n        x += invFreq    #increment index         \r\n        if x &amp;gt;= sqrt_gridpts:\r\n            x = invFreq \/ 2\r\n            z += invFreq\r\n        index = z*sqrt_gridpts + x\r\n    computeMidpts(octNum, invFreq)\r\n\r\n#interpolates pts between control pts\r\ndef computeMidpts(octNum, invFreq):\r\n    brX = invFreq \/ 2                   #bottom-right point\r\n    brZ = invFreq \/ 2\r\n    tlX = sqrt_gridpts - invFreq \/ 2    #top-left point\r\n    tlZ = sqrt_gridpts - invFreq \/ 2\r\n\r\n    while(1):\r\n        x = tlX\r\n        z = tlZ\r\n        br = brZ*sqrt_gridpts + brX\r\n        bl = brZ*sqrt_gridpts + tlX\r\n        tr = tlZ*sqrt_gridpts + brX\r\n        tl = tlZ*sqrt_gridpts + tlX\r\n\r\n        while(x != brX or z != brZ):\r\n            if  ((x != brX or z != tlZ) and\r\n                (x != tlX or z != brZ) and\r\n                (x != tlX or z != tlZ)):\r\n                #find distance between current x\/z and endpts\r\n                xt = x-tlX\r\n                zt = z-tlZ\r\n                maxX = brX-tlX\r\n                maxZ = brZ-tlZ\r\n                if(xt &amp;lt; 0):\r\n                    xt += sqrt_gridpts\r\n                if(zt &amp;lt; 0):\r\n                    zt += sqrt_gridpts\r\n                if(maxX &amp;lt; 0):\r\n                    maxX += sqrt_gridpts\r\n                if(maxZ &amp;lt; 0):\r\n                    maxZ += sqrt_gridpts\r\n                xt \/= float(maxX)\r\n                zt \/= float(maxZ)\r\n                #bi-interp, add to endpts\r\n                b = binterpolate(endPoints&#x5B;octNum]&#x5B;br],\r\n                                endPoints&#x5B;octNum]&#x5B;bl],\r\n                                endPoints&#x5B;octNum]&#x5B;tr],\r\n                                endPoints&#x5B;octNum]&#x5B;tl],\r\n                                xt, zt)\r\n                #if(x == brX or x == tlX or z == brZ or z == tlZ):\r\n                #    b \/= 2.0\r\n                endPoints&#x5B;octNum]&#x5B;z*sqrt_gridpts + x] = b #endif\r\n\r\n            #increase x and z\r\n            if(x == brX):\r\n                x = tlX\r\n                z += 1\r\n                z %= sqrt_gridpts\r\n            else:\r\n                x += 1\r\n                x %= sqrt_gridpts#endwhile\r\n\r\n        #move to next patch\r\n        if(brX == brZ and brZ == sqrt_gridpts - invFreq\/2):\r\n            break\r\n        tlX = brX\r\n        if(brX == sqrt_gridpts - invFreq\/2):\r\n            brX = invFreq\/2\r\n            tlZ = brZ\r\n            brZ += invFreq\r\n        else:\r\n            brX += invFreq\r\n            brX %= sqrt_gridpts\r\n\r\n#lerp for now\r\ndef interpolate(x1, x2, t):\r\n    ts = (1 - math.cos(t*math.pi))*0.5\r\n    return x1*(1-ts) + x2*ts\r\n\r\n#2d interpolation\r\ndef binterpolate(br, bl, tr, tl, xt, yt):\r\n    interpL = interpolate(tl, bl, yt)\r\n    interpR = interpolate(tr, br, yt)\r\n    return interpolate(interpL, interpR, xt)\r\n\r\n#called on every point\r\ndef mainLoop(pointNum):\r\n    global lastIterationTime, NUM_GRIDPTS, points, endPoints, startPoints, currentTimes\r\n\r\n    if pointNum == 0:               #new iteration\r\n        if(hou.time() &amp;lt; lastIterationTime): #did frame counter reset?             \r\n            lastIterationTime = hou.time()         \r\n    for t in range(1, NUM_OCTAVES+1):   #add dT             \r\n        currentTimes&#x5B;t] += (hou.time() - lastIterationTime)         \r\n        lastIterationTime = hou.time()         \r\n        for t in range(1, NUM_OCTAVES+1):\r\n             if(currentTimes&#x5B;t] &amp;gt;= maxTimes&#x5B;t]):\r\n                computeOctave(t)\r\n                currentTimes&#x5B;t] = 0.0\r\n\r\n        points = &#x5B;0.0]*NUM_GRIDPTS\r\n        interpolatePoints()\r\n    return points&#x5B;pointNum]\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Download Houdini Project File (46K) This was a project I completed for my Computer Animation and Simulation class during my last semester at USC. Going into this project, I did knew neither Python nor Houdini, and I had never attempted an implementation of Perlin Noise before. This took about 2.5 weeks to complete. Source code [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":2,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-33","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/davidmazz.com\/index.php?rest_route=\/wp\/v2\/pages\/33","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/davidmazz.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/davidmazz.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/davidmazz.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/davidmazz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=33"}],"version-history":[{"count":0,"href":"https:\/\/davidmazz.com\/index.php?rest_route=\/wp\/v2\/pages\/33\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/davidmazz.com\/index.php?rest_route=\/wp\/v2\/pages\/2"}],"wp:attachment":[{"href":"https:\/\/davidmazz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=33"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}