Blogging

有时午夜有彩虹

Read this first

PathTracer

— render the world in one triangle

Screen Shot 2020-08-04 at 10.56.30 PM.png

Lambert

Screen Shot 2020-07-25 at 8.42.19 PM.png

Screen Shot 2020-07-26 at 10.03.57 PM.png

The Next Estimation

FresnelSpecular | Glass

Screen Shot 2020-08-04 at 9.40.46 PM.png

Continue reading →


再来看看Flocking

Nature Of Code 这本书给我印象最深的就是Flocking示例, 当中的算法来源于Craig Reynolds 1986年 。

CodeOfNature很好的实现了该算法, 但是当中存在一些冗余的计算,以及为了清晰阐述Separation | Alignment | Cohesion这三条规则而采用分别遍历计算,对我来说,不够高效之余,还显得不够直观。这里我对该算法进行了简化。

Boid.prototype.steerToVel = function (desired) {
    let steer = p5.Vector.sub(desired, this.velocity);
    steer.limit(this.maxAcceleration);
    return steer;
}

Boid.prototype.flock = function (boids) {
    let sepRad = 25.0, aliRad = 50.0, cohRad = 50.0;
    let sepCount = 0, aliCount = 0, cohCount = 0;
    let sepAcc = createVector()
    let aliAcc = createVector()
    let cohAcc = createVector()
    for (let i = 0; i < boids.length; i++) {
        let diff = p5.Vector.sub(this.position, boids[i].position);
        let d = diff.mag();
        if (d === 0) continue;
        if (d < sepRad) {
            sepAcc.add(diff.normalize().div(d));
            sepCount++;
        }
        if (d
...

Continue reading →


Play With KDTree

source code in this page lies here
s3.png
最近工作中实现了基于KDTree的3D空间划分,用于实时判断Mesh和Ray的相交,我现在依然惊讶于这个算法的优美和高效。

还是先从工作中逃离一会,试试用Clojure实现一下2D-KDtree,然后在quil框架来些与工作无关的东西看看。

先生成3000个点吧:


(def pts
  (repeatedly 3000 (vec2 (q/random (q/width))
                          (q/random (q/height)))))

调用quil的point函数画出来看看

 (doall (map (apply q/point %) pts))

111.jpg

好了, 现在我们可以将这些点通过KDTree算法来进行二维分割了:


(defn divide [pts rect depth]
  (when (>= (count pts) 1)
    (let [top-left (:p rect)
          axis ([:x :y] (mod depth 2))
          sort-pts (vec (sort-by (axis %) pts))
          median (quot (count pts) 2)
          translate (g/translate % (m/- top-left))
          left (map translate (subvec sort-pts 0 median))
          right (map translate (subvec sort-pts (inc median)))
          div-rects (divide-rect
                     rect axis
                     (get-in sort-pts [median axis]))]
      {:pts
...

Continue reading →


Fill The Probability

source code in this page lies here

6-pub.pngGenerative-Art常常借助概率分布来构建画面的形式与秩序。

其中最常用的有Gaussian、Uniform和PowerLaw分布函数了,Processing中甚至专门提供了randomGaussian这个函数方法来返回符合标准正态分布的随机数。

最近在翻阅一本概率书籍的时候, 当中提到一种简单的算法来生成符合某概率密度函数的连续随机数(假设下图函数是我们想要的概率分布):

  1. 生成一个随机数x,y = F(x)。
  2. 再生成一个随机数m。
  3. 如果y>m,则该随机数是符合概率分布的,则返回 (如下图的0.1),反之丢弃(如下图的0.3)并重复第一步直到找到符合该条件的x。

💡 注意自定义函数作为概率密度函数不是数学严谨的,概率也只有相对的意义,函数值相对越大越容易被返回。

这篇帖子主要记录了用这种方法来自定义概率分布并“填充”它们,使用Clojure编程语言绑定的Processing框架Quil。

(defn custom-distribution [pdf dimension]
  (loop []
     (let [ts (repeatedly dimension rand)
           v (apply pdf ts)]
       (if (< (rand) v)
         (flatten [v ts])
         (recur)))))

custom-distribution接受两个参数,第一个参数为自定义的概率分布函数F,第二个参数则是该分布函数的维度。上图的函数实际上常被称为Impulse,因为它很像一次脉搏跳动,将它用代码定义出来,然后调用custom-distribution...

Continue reading →