99re热视频这里只精品,久久久天堂国产精品女人,国产av一区二区三区,久久久精品成人免费看片,99久久精品免费看国产一区二区三区

第九章:數(shù)字

2018-02-24 15:50 更新

處理數(shù)字是 Common Lisp 的強(qiáng)項(xiàng)之一。Common Lisp 有著豐富的數(shù)值類型,而 Common Lisp 操作數(shù)字的特性與其他語言比起來更受人喜愛。

9.1 類型 (Types)

Common Lisp 提供了四種不同類型的數(shù)字:整數(shù)、浮點(diǎn)數(shù)、比值與復(fù)數(shù)。本章所講述的函數(shù)適用于所有類型的數(shù)字。有幾個(gè)不能用在復(fù)數(shù)的函數(shù)會(huì)特別說明。

整數(shù)寫成一串?dāng)?shù)字:如?2001?。浮點(diǎn)數(shù)是可以寫成一串包含小數(shù)點(diǎn)的數(shù)字,如?253.72?,或是用科學(xué)表示法,如?2.5372e2?。比值是寫成由整數(shù)組成的分?jǐn)?shù):如?2/3?。而復(fù)數(shù)?a+bi?寫成?#c(a?b)?,其中?a?與?b?是任兩個(gè)類型相同的實(shí)數(shù)。

謂詞?integerp?、?floatp?以及?complexp?針對相應(yīng)的數(shù)字類型返回真。圖 9.1 展示了數(shù)值類型的層級(jí)。

朗伯定律?告訴我們,由平面上一點(diǎn)所反射的光的強(qiáng)度,正比于該點(diǎn)的單位法向量 (unit normal vector)?N?(這里是與平面垂直且長度為一的向量)與該點(diǎn)至光源的單位向量?L?的點(diǎn)積 (dot-product):

i=N?L

如果光剛好照到這點(diǎn),?N?與?L?會(huì)重合 (coincident),則點(diǎn)積會(huì)是最大值,?1?。如果將在這時(shí)候?qū)⑵矫娉廪D(zhuǎn) 90 度,則?N?與?L?會(huì)垂直,則兩者點(diǎn)積會(huì)是?0?。如果光在平面后面,則點(diǎn)積會(huì)是負(fù)數(shù)。

在我們的程序里,我們假設(shè)光源在觀測點(diǎn) (eye),所以?lambert?使用了這個(gè)規(guī)則來找到平面上某點(diǎn)的亮度 (illumination),返回我們追蹤的光的單位向量與法向量的點(diǎn)積。

在?sendray?這個(gè)值會(huì)乘上平面的顏色 (即便是有好的照明,一個(gè)暗的平面還是暗的)來決定該點(diǎn)之后總體亮度。

為了簡單起見,我們在模擬世界里會(huì)只有一種物體,球體。圖 9.5 包含了與球體有關(guān)的代碼。球體結(jié)構(gòu)包含了?surface?,所以一個(gè)球體會(huì)有一種顏色以及?center?和?radius?。調(diào)用?defsphere?添加一個(gè)新球體至世界里。

(defstruct (sphere (:include surface))
  radius center)

(defun defsphere (x y z r c)
  (let ((s (make-sphere
             :radius r
             :center (make-point :x x :y y :z z)
             :color  c)))
    (push s *world*)
    s))

(defun intersect (s pt xr yr zr)
  (funcall (typecase s (sphere #'sphere-intersect))
           s pt xr yr zr))

(defun sphere-intersect (s pt xr yr zr)
  (let* ((c (sphere-center s))
         (n (minroot (+ (sq xr) (sq yr) (sq zr))
                     (* 2 (+ (* (- (x pt) (x c)) xr)
                             (* (- (y pt) (y c)) yr)
                             (* (- (z pt) (z c)) zr)))
                     (+ (sq (- (x pt) (x c)))
                        (sq (- (y pt) (y c)))
                        (sq (- (z pt) (z c)))
                        (- (sq (sphere-radius s)))))))
    (if n
        (make-point :x  (+ (x pt) (* n xr))
                    :y  (+ (y pt) (* n yr))
                    :z  (+ (z pt) (* n zr))))))

(defun normal (s pt)
  (funcall (typecase s (sphere #'sphere-normal))
           s pt))

(defun sphere-normal (s pt)
  (let ((c (sphere-center s)))
    (unit-vector (- (x c) (x pt))
                 (- (y c) (y pt))
                 (- (z c) (z pt)))))

圖 9.5 球體。

函數(shù)?intersect?判斷與何種平面有關(guān),并調(diào)用對應(yīng)的函數(shù)。在此時(shí)只有一種,?sphere-intersect?,但?intersect?是寫成可以容易擴(kuò)展處理別種物體。

我們要怎么找到一束光與一個(gè)球體的交點(diǎn) (intersection)呢?光線是表示成點(diǎn)?p=?x0,y0,x0??以及單位向量?v=?xr,yr,xr??。每個(gè)在光上的點(diǎn)可以表示為?p+nv?,對于某個(gè)?n?── 即??x0+nxr,y0+nyr,z0+nzr??。光擊中球體的點(diǎn)的距離至中心??xc,yc,zc??會(huì)等于球體的半徑?r?。所以在下列這個(gè)交點(diǎn)的方程序會(huì)成立:

r=(x0+nxr?xc)2+(y0+nyr?yc)2+(z0+nzr?zc)2??????????????????????????????????????????√

這會(huì)給出

an2+bn+c=0

其中

a=x2r+y2r+z2rb=2((x0?xc)xr+(y0?yc)yr+(z0?zc)zr)c=(x0?xc)2+(y0?yc)2+(z0?zc)2?r2

要找到交點(diǎn)我們只需要找到這個(gè)二次方程序的根。它可能是零、一個(gè)或兩個(gè)實(shí)數(shù)根。沒有根代表光沒有擊中球體;一個(gè)根代表光與球體交于一點(diǎn) (擦過 「grazing hit」);兩個(gè)根代表光與球體交于兩點(diǎn) (一點(diǎn)交于進(jìn)入時(shí)、一點(diǎn)交于離開時(shí))。在最后一個(gè)情況里,我們想要兩個(gè)根之中較小的那個(gè);?n?與光離開觀測點(diǎn)的距離成正比,所以先擊中的會(huì)是較小的?n?。所以我們調(diào)用?minroot?。如果有一個(gè)根,?sphere-intersect?返回代表該點(diǎn)的??x0+nxr,y0+nyr,z0+nzr??。

圖 9.5 的另外兩個(gè)函數(shù),?normal?與?sphere-normal?類比于?intersect?與?sphere-intersect?。要找到垂直于球體很簡單 ── 不過是從該點(diǎn)至球體中心的向量而已。

圖 9.6 示范了我們?nèi)绾萎a(chǎn)生圖片;?ray-test?定義了 38 個(gè)球體(不全都看的見)然后產(chǎn)生一張圖片,叫做 “sphere.pgm” 。

(譯注:PGM 可移植灰度圖格式,更多信息參見?wiki?)

(defun ray-test (&optional (res 1))
  (setf *world* nil)
  (defsphere 0 -300 -1200 200 .8)
  (defsphere -80 -150 -1200 200 .7)
  (defsphere 70 -100 -1200 200 .9)
  (do ((x -2 (1+ x)))
      ((> x 2))
    (do ((z 2 (1+ z)))
        ((> z 7))
      (defsphere (* x 200) 300 (* z -400) 40 .75)))
  (tracer (make-pathname :name "spheres.pgm") res))

圖 9.6 使用光線追蹤器

圖 9.7 是產(chǎn)生出來的圖片,其中?res?參數(shù)為 10。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)