亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

python光學(xué)仿真實(shí)現(xiàn)光線追跡折射與反射的實(shí)現(xiàn)

 更新時(shí)間:2021年10月19日 17:14:37   作者:微小冷  
這篇文章主要為大家介紹了python光學(xué)仿真實(shí)現(xiàn)光線追跡折射與反射的實(shí)現(xiàn)示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步

折射與反射

光線與光學(xué)元件相互作用,無非只有兩件事,反射和透射。而就目前看來,我們所常用的光學(xué)元件,也無非有兩種表面,即平面和球面,二維化之后就簡化成了射線與線段,射線與劣弧的關(guān)系。

平面反射

無論從哪個(gè)角度來看,平面的反射折射都要比球面更簡單,而反射問題要比折射問題更簡單,所以,我們首先處理平面的反射問題。

反射定律即入射角等于反射角,心念及此,最為循規(guī)蹈矩的思路必然是先找到入射光線和平面的夾角,然后用這個(gè)夾角和平面(在二維空間中是一條直線)在空間中的斜率,由這個(gè)斜率與入射角得到出射光的斜率,然后就可以得到出射光的方程。

這個(gè)方法的問題是需要反復(fù)使用三角函數(shù)和反三角函數(shù),而三角函數(shù)和反三角函數(shù)并非嚴(yán)格意義上的互為相反,所以在傳參的過程中,可能會(huì)遇到一些麻煩。

相對來說,比較不容易出錯(cuò)的方法是,尋找入射點(diǎn)關(guān)于法線的對稱點(diǎn),那么這個(gè)對稱點(diǎn)與交點(diǎn)的連線,便是出射光的方程。

在這里插入圖片描述

在這里插入圖片描述

平面折射

折射與反射的思路如出一轍,最原始的想法仍舊是獲取入射角,然后根據(jù)折射定律求出射角,然后再按照出射角解出出射光的表達(dá)式。這個(gè)思路的難點(diǎn)仍舊在三角函數(shù)與反函數(shù)的轉(zhuǎn)化上。

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

至此,我們發(fā)現(xiàn)折射與反射在表達(dá)形式上是相通的,如果令入射點(diǎn)關(guān)于法線做垂線,垂足為C,約定這條垂線與出射光線的交點(diǎn)為出射點(diǎn)B,那么出射點(diǎn)到垂足的距離BC與入射點(diǎn)到垂足的距離AC之間是滿足比例關(guān)系的。當(dāng)入射光線和反射光線的折射率相等時(shí),這個(gè)比例為1,否則比例為 λ \lambda λ。

我們還能發(fā)現(xiàn),這個(gè) λ \lambda λ不一定有解,因?yàn)榉帜钢杏幸粋€(gè)根號表達(dá)式,當(dāng)內(nèi)部的值小于0時(shí),自然無解。這與我們的物理直覺是符合的,即并不是所有的入射光線都有折射光線,當(dāng)折射光線消失的時(shí)候,就發(fā)生了全反射。

所以,當(dāng)務(wù)之急是根據(jù)入射點(diǎn)找垂足,易得

在這里插入圖片描述

那么對于我們所熟知的折射問題,即可令入射點(diǎn)關(guān)于反射平面做一次對稱,再關(guān)于發(fā)現(xiàn)做一次定比延長線的對稱,即可得到出射點(diǎn)。

python實(shí)現(xiàn)

至此,我們已經(jīng)完全建立了一套反射與折射的關(guān)系,代碼如下:

#得到點(diǎn)關(guān)于直線的對稱點(diǎn),k為比例系數(shù)
def getSymDot(point,line,k=1):
    return tuple((np.array(getPedal(point,line))*(1+k)-point)/k)
#得到直線的垂足
def getPedal(point,line):
    a,b,c=line
    x0,y0 = point
    y1 = (a**2*y0-a*b*x0-b*c)/(a**2+b**2)
    x1 = (b**2*x0-a*b*y0-a*c)/(a**2+b**2)
    return (x1,y1)

函數(shù)getSymDot即通過輸入點(diǎn)和線來求解對稱點(diǎn),其思路是把點(diǎn)關(guān)于線對稱的問題轉(zhuǎn)化為點(diǎn)關(guān)于垂足對稱的問題。所以引用了getPedal函數(shù),這個(gè)函數(shù)通過輸入一點(diǎn)和線來返回過點(diǎn)做線的垂線所得到的垂足。

所有代碼都是對上述數(shù)學(xué)公式的簡單復(fù)現(xiàn)。

def cataDioLine(abc=[1,-1,1],line=[2,-1,1],
                sPoint=[],cross=[],n1=1,n2=1.5):
    normal = [-line[1],line[0],line[1]*cross[0]-line[0]*cross[1]]#法線
    flecDot = getSymDot(sPoint,normal)
    flec=getABC([cross,flecDot])
    dPara = np.sqrt(line[0]**2+line[1]**2)
    dNormal = np.abs(np.array(normal).dot(list(sPoint)+[1]))/dPara#到法線距離
    dPane = np.abs(np.array(line).dot(list(sPoint)+[1]))/dPara#到反射面距離
    if dNormal == 0:
        return flec,abc
    delt = (n2/n1)**2*(1+(dPane/dNormal)**2)-1#判定全反射
    if delt>0:
        k =dPane/dNormal/np.sqrt(delt)
        fracDot = getSymDot(sPoint,normal,k)
        fracDot = getSymDot(fracDot,line)
        frac = getABC([cross,fracDot])
        return flec,frac
    return flec,[0,0,0]

函數(shù)cataDioLine則是反射折射的實(shí)現(xiàn)函數(shù)。注意,在此引入的getABC并不是此前定義的通過點(diǎn)和角度求表達(dá)式的函數(shù),而是通過兩點(diǎn)轉(zhuǎn)[a,b,c]的函數(shù)。

那么我們是否可以寫一個(gè)同名函數(shù)來實(shí)現(xiàn)不同的功能呢?很遺憾的是,Python不支持函數(shù)的重載,所以只能將同名函數(shù)封裝在一起:

def getABC(*par):
    if len(par)==1:     #此時(shí)傳入的參數(shù)為點(diǎn)對dots=[(x0,y0),(x1,y1)]
        dots = par[0]
        abc = [dots[1][1]-dots[0][1],
                dots[0][0]-dots[1][0], 
                -np.linalg.det(dots)]
        return np.array(abc)/(np.sqrt(abc[0]**2+abc[1]**2))
    elif len(par)==2:   #此時(shí)傳入的參數(shù)為點(diǎn)和角度(x0,y0),theta
        theta,sPoint = par
        a,b = [np.sin(theta),-np.cos(theta)]
        c = -(a*sPoint[0]+b*sPoint[1])
        return [a,b,c]

看到輸入?yún)?shù)(*par),我們很多人可能會(huì)產(chǎn)生某些不是很美妙的聯(lián)想,但不要興奮,這只是python的一種傳參方式。(*args)表示將傳入的參數(shù)組成一個(gè)列表args;(**kargs)表示將傳入的參數(shù)組成一個(gè)字典kargs。

弧面問題

光線在弧面上的反射問題,是典型的那種看似復(fù)雜實(shí)則簡單的紙老虎問題,簡單到我們只要找到法線就能輕松地轉(zhuǎn)化為平面問題。

所以,問題被簡單地轉(zhuǎn)化為求解圓的切線問題——這個(gè)切線即反射平面。由于數(shù)學(xué)過程過于簡單,就不寫公式了,讀者可以試著看代碼反推公式。

#獲取過交點(diǎn)的圓弧的切線
def getTangent(corss=[0,1],circle=[0,0,1]):
    a = corss[0]-circle[0]
    b = corss[1]-circle[1]
    c = -a*corss[0]-b*corss[1]
    return [a,b,c]

至此,我們就可以得到一個(gè)完整的折射反射問題的求解方案:

#光在直線或弧線表面的反折射
def cataDio(abc=[1,-1,1],dots=[(0,2),(2,2)],
            sPoint=[-2,-1],n1=1,n2=1.5):
    cross = getCross(abc,dots,sPoint)           #獲取交點(diǎn)
    if cross == []:
        return [],[],[]
    if len(dots)==3:
        line = getTangent(cross,arc2cir(dots))  #圓上切線
    elif len(dots)==2:
        line = getABC(dots)
    flec,frac = cataDioLine(abc,line,sPoint,cross,n1,n2)
    return cross,flec,frac

當(dāng)然,這里的getCross也需要重新寫成不僅適合直線,而且適合弧線的形式:

def getCross(abc=[1,-1,0],dots=[[0,-1],[0,1],[0.5,0]],point=[]):
    if len(dots)==3:
        return getCrossArc(abc,dots,point)
    if len(dots)==2:
        return getCrossDots(abc,dots,point)

這時(shí)我們發(fā)現(xiàn)用兩個(gè)點(diǎn)表示線段,三個(gè)點(diǎn)表示弧線還是比較舒服的一種做法,至少二者在表達(dá)形式上的統(tǒng)一似乎能為我們帶來某種內(nèi)心的愉悅。

以上就是python光學(xué)仿真實(shí)現(xiàn)光線追跡折射與反射的實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于python光線追跡的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python網(wǎng)絡(luò)編程 使用UDP、TCP協(xié)議收發(fā)信息詳解

    python網(wǎng)絡(luò)編程 使用UDP、TCP協(xié)議收發(fā)信息詳解

    這篇文章主要介紹了python網(wǎng)絡(luò)編程 使用UDP、TCP協(xié)議收發(fā)信息詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • python中urllib.request和requests的使用及區(qū)別詳解

    python中urllib.request和requests的使用及區(qū)別詳解

    這篇文章主要介紹了python中urllib.request和requests的使用及區(qū)別詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • python制作的天氣預(yù)報(bào)小工具(gui界面)

    python制作的天氣預(yù)報(bào)小工具(gui界面)

    大家好啊!我用Tkinter寫了一個(gè)天氣預(yù)報(bào)小工具,支持34個(gè)省級行政區(qū)以及港澳臺(tái)地區(qū)天氣,覆蓋全面。程序打包好放在了藍(lán)奏云,與大家分享一下。
    2021-05-05
  • python實(shí)現(xiàn)圖書管理系統(tǒng)

    python實(shí)現(xiàn)圖書管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)圖書管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Python?的Json?模塊編碼詳解

    Python?的Json?模塊編碼詳解

    這篇文章主要為大家介紹了Python?的Json?模塊編碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助<BR>
    2021-11-11
  • Python猴子補(bǔ)丁Monkey Patch用法實(shí)例解析

    Python猴子補(bǔ)丁Monkey Patch用法實(shí)例解析

    這篇文章主要介紹了Python猴子補(bǔ)丁Monkey Patch用法實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • pygame游戲之旅 游戲中添加顯示文字

    pygame游戲之旅 游戲中添加顯示文字

    這篇文章主要為大家詳細(xì)介紹了pygame游戲之旅的第5篇,教大家如何在游戲中添加顯示文字,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • python3.x提取中文的正則表達(dá)式示例代碼

    python3.x提取中文的正則表達(dá)式示例代碼

    這篇文章主要介紹了python3.x中提取中文的正則表達(dá)式的書寫,需要的朋友可以參考下
    2019-07-07
  • php使用遞歸與迭代實(shí)現(xiàn)快速排序示例

    php使用遞歸與迭代實(shí)現(xiàn)快速排序示例

    這篇文章主要介紹了php使用遞歸與迭代實(shí)現(xiàn)快速排序的示例,大家參考使用吧
    2014-01-01
  • Python數(shù)據(jù)結(jié)構(gòu)之列表與元組詳解

    Python數(shù)據(jù)結(jié)構(gòu)之列表與元組詳解

    序列是Python中最基本的數(shù)據(jù)結(jié)構(gòu)。序列中的每個(gè)元素都分配一個(gè)數(shù)字 - 它的位置,或索引,第一個(gè)索引是0,第二個(gè)索引是1,依此類推,元組與列表類似,不同之處在于元組的元素不能修改。元組使用小括號,列表使用方括號
    2021-10-10

最新評論