国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

基于JS的人類行為模擬及逼近算法的研究實現(xiàn)

2020-06-02 12:53:12呂丙東
關(guān)鍵詞:眼珠調(diào)用眼球

高 云,呂丙東

(山西大同大學(xué)計算機與網(wǎng)絡(luò)工程學(xué)院,山西大同 037009)

在互聯(lián)網(wǎng)高速發(fā)展的今天,網(wǎng)絡(luò)編程已經(jīng)成為程序設(shè)計的最主要的需求。目前主流的頁面設(shè)計語言是Java 語言,使用JSP 可以開發(fā)出功能強大的網(wǎng)站,但是JSP需要在服務(wù)器端執(zhí)行,瀏覽器和服務(wù)器之間頻繁的交互會大大降低頁面響應(yīng)的效率[1]。因此在不需要和服務(wù)器響應(yīng)的情況下,應(yīng)盡量避免使用JSP進(jìn)行開發(fā),前端程序設(shè)計語言JS就是最理想的選擇了[1-2]。

JS 僅在頁面前端進(jìn)行響應(yīng),由瀏覽器進(jìn)行解析,功能強大并且執(zhí)行效率高[3],所以選用JS 來進(jìn)行頁面的開發(fā)。

1 研究綜述

用戶友好是頁面設(shè)計必不可少的要素,模擬人類行為,尤其是思考即人工智能也是目前程序設(shè)計的重要思考方向[4]。從模擬人類動作的角度出發(fā),使用JS編寫頁面程序模擬一雙盯著鼠標(biāo)的眼睛,頁面加載時,將鼠標(biāo)眼睛定位在頁面的左上角固定位置,當(dāng)鼠標(biāo)在頁面上移動時,鼠標(biāo)眼睛會追隨著鼠標(biāo)進(jìn)行移動,并且會調(diào)整眼球的方向,就像人類的眼睛一樣,隨著鼠標(biāo)位置的變化眼球轉(zhuǎn)動。當(dāng)鼠標(biāo)最終靜止不動時,鼠標(biāo)眼睛停留在鼠標(biāo)上,兩只眼球向內(nèi)集中在鼠標(biāo)箭頭位置,類似于人類的對睛眼。

當(dāng)鼠標(biāo)移動時,鼠標(biāo)眼睛追隨鼠標(biāo)移動的過程是一個逐漸逼近的過程,也就是說,鼠標(biāo)眼睛和鼠標(biāo)箭頭之間的距離越大,移動速度越快,越接近鼠標(biāo)位置時,移動速度越慢。通過這種方式能夠模擬出鼠標(biāo)眼睛移動的動態(tài)漸進(jìn)過程,而不是將鼠標(biāo)眼睛隨著鼠標(biāo)位置的變換進(jìn)行跳躍式移動。眼球的轉(zhuǎn)動也是逐漸進(jìn)行的[4]。

其次,在鼠標(biāo)眼睛移動的過程中,需要先計算出水平移動的距離(X軸方向)與垂直移動的距離(Y軸方向),然后分別根據(jù)計算結(jié)果進(jìn)行水平和垂直的位移,由于水平和垂直的位移距離是不一樣的,如果在兩個方向上以同樣的速度進(jìn)行位移,有可能會先完成某一方向的位移之后還在繼續(xù)進(jìn)行另一方向的位移,為了避免這種情況,我們將鼠標(biāo)眼睛在X軸方向和Y軸方向上成比例進(jìn)行位移,這樣,就保證了兩個方向上的位移同時完成。

可以看出,整個程序?qū)崿F(xiàn)的關(guān)鍵在于設(shè)置鼠標(biāo)眼睛(圖像元素)隨著鼠標(biāo)位置移動的坐標(biāo)以及調(diào)節(jié)X軸方向和Y軸方向位移的比例。

2 頁面初始化定位分析

在頁面加載時,需要在頁面上放置眼睛,并將其固定在頁面的左上角位置,這部分功能由ECMAScript代碼來完成。由于眼睛中的眼球部分是會隨著鼠標(biāo)的位置而轉(zhuǎn)動方向的,即眼球會在眼睛的區(qū)域內(nèi)移動而不是固定在眼睛區(qū)域的某個位置保持不動,所以必須將眼睛和眼球分別用2個不同的圖片對象進(jìn)行表示,然后疊加放置在一起表示一個完整的眼睛。如圖1所示,使用圖像“b.png”表示眼睛,圖像“f.png”表示眼球。這里選擇使用擴展名為png的圖像,原因是圖像的大小僅為幾個KB,這就使的打開圖像并不會成為拖累頁面加載速度的因素。

圖1 眼睛示意圖

表示眼睛的圖像(b.png)中眼睛是一對的,而表示眼球的圖像(f.png)中眼球是單個的,這是因為眼睛移動時是作為一個整體一起隨著鼠標(biāo)移動的,而眼球隨著鼠標(biāo)一起移動的同時,還會跟隨鼠標(biāo)的方向分別轉(zhuǎn)動,所以放置眼球時要將兩個眼球單獨放置以便它們分別進(jìn)行不同的位移。

初始化鼠標(biāo)眼睛時需要完成2個動作,第一是適當(dāng)?shù)陌凑疹A(yù)定位置和一定格式放置各個圖像對象,使之組成圖1 中所示的完整的眼睛,第二是給這些圖像后期的動作設(shè)置明確的指向(包含所要完成動作的事件句柄)。

2.1 初始化對象位置

由于頁面最初加載時即需要初始化鼠標(biāo)眼睛,所以在window 對象的onload 事件中調(diào)用函數(shù)來完成初始化功能。即:

window.onload=setHandlers(200,100);

使用函數(shù)setHandlers(200,100) 在坐標(biāo)(200,100)處放置鼠標(biāo)眼睛,放置時,將鼠標(biāo)眼睛分為三層對象,分別表示眼睛,左眼球和右眼球。

使用div元素來表示這三層對象,采用絕對定位放置對象。將眼睛放置在坐標(biāo)(200,100)處,眼睛半徑為20,左眼球放置于坐標(biāo)(210,210)處(即左眼睛中央),右眼球放置于坐標(biāo)(250,210)處(即右眼睛中央),左右眼球半徑均為10。將眼睛初始化為如圖2的樣式,即眼球是在眼睛的正中央,如圖2所示。

圖2 眼睛初始化

程序中需要用到一些全局變量來在各個函數(shù)中共享鼠標(biāo)眼睛和鼠標(biāo)的坐標(biāo),在放置鼠標(biāo)眼睛后,將這些全局變量賦值以便后面移動時使用。

mouseX,mouseY表示鼠標(biāo)的當(dāng)前位置,頁面最初載入時,鼠標(biāo)位置未知,所以需要初始化鼠標(biāo)位置,而鼠標(biāo)位置會引起鼠標(biāo)眼睛的移動,為了在頁面最初加載時不移動鼠標(biāo)眼睛,所以將鼠標(biāo)位置初始化為眼睛正中。realX和realY表示眼睛的當(dāng)前目標(biāo)位置,由于圖像的位置是用其矩形區(qū)域的左上角坐標(biāo)表示的,所以這里使用pixelLeft和pixelTop,即取眼睛對象樣式的左端位置和頂端位置表示眼睛對象的坐標(biāo)。各個變量含義如圖3所示。

圖3 各全局變量含義

2.2 完成對象的第一次移動

當(dāng)需要的對象和全局變量都設(shè)置完成后,就可以著手設(shè)計鼠標(biāo)眼睛后期的動作。由于鼠標(biāo)眼睛完成的動作是隨著鼠標(biāo)位置的改變(鼠標(biāo)移動)不停的趨近于鼠標(biāo),也就是說,后期鼠標(biāo)的移動會觸發(fā)的鼠標(biāo)事件為onmousemove,因此在這里我們?yōu)閐ocument 對象的onmousemove 事件句柄分配值,使鼠標(biāo)移動時會調(diào)用相應(yīng)的函數(shù)[2],為了使程序結(jié)構(gòu)更加緊湊,設(shè)計更加合理,我們使用了函數(shù)的閉包來完成這一功能[3],即將該函數(shù)體的實現(xiàn)整合在函數(shù)setHandlers()的內(nèi)部。

鼠標(biāo)移動時,獲取事件發(fā)生位置的坐標(biāo)值x和y,將其作為在document。body 中x軸和y軸方向上的偏移量,得到鼠標(biāo)當(dāng)前位置的坐標(biāo)。需要注意的是,這里雖然定義了匿名函數(shù),將鼠標(biāo)移動時調(diào)用的代碼寫入函數(shù)中分配給onmousemove 事件句柄,但是卻并沒有立即調(diào)用函數(shù),只有在頁面加載后移動鼠標(biāo),觸發(fā)了事件后代碼才會生效,這樣就保證了在整個頁面運行過程中,移動鼠標(biāo)都會執(zhí)行這段代碼[5]。

在該匿名函數(shù)中僅實現(xiàn)了鼠標(biāo)移動時獲取鼠標(biāo)移動的位置坐標(biāo),并沒有進(jìn)一步規(guī)定鼠標(biāo)眼睛完成的動作。我們將鼠標(biāo)眼睛移動的動作寫在函數(shù)moveEyes()中,緊接著上面的代碼調(diào)用它,而不是將函數(shù)moveEyes()放在document.onmousemove 事件中調(diào)用。這樣設(shè)計的目的有兩個,第一,在頁面初始化時,鼠標(biāo)眼睛的樣式是如圖2 所示那樣,我們希望在整個頁面運行過程中鼠標(biāo)眼睛的樣式前后保持一致,即為圖1 中所示的樣式,所以在三層對象設(shè)置完后就需要移動鼠標(biāo)眼睛讓其改變初始樣式。第二,由于鼠標(biāo)眼睛追隨鼠標(biāo)位移是一個逐漸逼近的過程,如果將函數(shù)moveEyes()放在document.onmousemove 事件中調(diào)用,那么鼠標(biāo)眼睛就像是粘在了鼠標(biāo)上,隨著鼠標(biāo)移動寸步不離,達(dá)不到程序設(shè)計預(yù)期的效果。

3 模擬人類眼睛轉(zhuǎn)動及漸進(jìn)逼近的分析實現(xiàn)

鼠標(biāo)眼睛移動的全部功能放在函數(shù)moveEyes()中實現(xiàn),根據(jù)前面的分析,為了達(dá)到程序預(yù)期的效果,編寫函數(shù)moveEyes()必須同時考慮以下三個問題。

(1)如何將組成鼠標(biāo)眼睛的三層對象全部移動并且始終保持整體的視覺效果;

(2)如何實現(xiàn)鼠標(biāo)眼睛移動時的漸次逼近;

(3)如何實現(xiàn)鼠標(biāo)眼睛移動時在X軸和Y軸方向上的成比例移動。

由于組成鼠標(biāo)眼睛的對象有三層,所以在移動時要考慮全部三層的位移情況,已經(jīng)描述過,我們使用全局變量realX和realY表示眼睛的當(dāng)前目標(biāo)位置,而左右眼球在移動的過程中要始終保持在眼睛的范圍內(nèi),其目標(biāo)位置坐標(biāo)由眼睛坐標(biāo)和鼠標(biāo)位置坐標(biāo)計算得出,使用dxLeft 表示左眼球目標(biāo)位置的x坐標(biāo),dxRight 表示右眼球目標(biāo)位置的x坐標(biāo),二者在y軸上進(jìn)行同步位移,使用dy表示左右眼球在目標(biāo)位置上的y坐標(biāo)。接下來的工作就是如何按照程序設(shè)計要求獲取上述的這些坐標(biāo)值。

3.1 眼睛逼近

鼠標(biāo)眼睛在向鼠標(biāo)移動的過程是一個逐漸逼近的過程,也就是說,在進(jìn)行移動過程時,是由遠(yuǎn)到近,由快到慢的過程,而不是從前一個位置跳躍到目標(biāo)位置。所以我們將整個位移的長度分別在x軸方向和y軸方向上分為若干個小的區(qū)間,鼠標(biāo)眼睛分別在這些小區(qū)間上做漸次移動,每一次調(diào)用函數(shù)moveEyes()完成一次小區(qū)間上的移動,為此,我們需要不停的調(diào)用函數(shù)moveEyes()保證完成整個位移。使用定時器每隔規(guī)定的時間間隔就調(diào)用一次moveEyes()完成一次小區(qū)間位移是個好的選擇,window 對象的setTimeout()方法可以完成這一要求,雖然該方法完成的是只調(diào)用一次代碼,但調(diào)用的代碼是函數(shù)自身也會構(gòu)成循環(huán)調(diào)用。

調(diào)用時間的選取也是應(yīng)該考慮的問題,時間太短會加重頁面響應(yīng)的負(fù)擔(dān),時間太長會使眼球轉(zhuǎn)動顯得呆滯,觀察人類眼球轉(zhuǎn)動的速度,設(shè)定調(diào)用時間為100。

tID=setTimeout('moveEyes()',100);

在完整位移上劃分的若干小區(qū)間并不是等距的,由于移動是由快到慢的過程,即小區(qū)間的長度是越接近目標(biāo)位置距離越小。我們將每個小區(qū)間的長度規(guī)定為當(dāng)前需要位移長度的十分之一,當(dāng)距離目標(biāo)位置足夠近時,小區(qū)間的長度是趨于0的。

首先確定每次位移眼睛的小區(qū)間長度,使用鼠標(biāo)當(dāng)前位置和取得的眼睛上一次停留的位置之間分別在x軸方向和y軸方向上的距離,再乘以0.1,就得到這次位移的小區(qū)間長度。即在X和Y軸上的位移量分別為(mouseX-realX-40) * 0.1 和(mouseY-realY-20)*0.1。

眼睛對象在x軸方向和y軸方向上的距離計算圖示如圖4所示。

圖4 x軸y軸方向距離計算圖示

將計算所得的當(dāng)前距離*0.1,即得到本次位移的長度,加上上一次眼睛停留的位置坐標(biāo),得到眼睛的目標(biāo)位置坐標(biāo)。

需要注意的是,這里并沒有獲取鼠標(biāo)眼睛實際的實時坐標(biāo),而只是選擇當(dāng)前能夠得到的最近一次的坐標(biāo)作為計算時的當(dāng)前坐標(biāo),這樣做并不是沒有任何偏差,但是相對于獲取實際的實時坐標(biāo)付出的代價來說,這些偏差是可以忽略不計的,并且也是可以在后期加以控制的[3]。

3.2 眼球轉(zhuǎn)動

相較于眼睛對象來說,眼球?qū)ο笞鴺?biāo)的確定就要復(fù)雜多了,眼球不光要產(chǎn)生向鼠標(biāo)位置逼近的動作,同時為了產(chǎn)生人類眼珠模擬的效果,眼珠還要在眼睛中有轉(zhuǎn)動的動作,即眼珠首先要隨著鼠標(biāo)轉(zhuǎn)動到鼠標(biāo)的方向,再沿著鼠標(biāo)方向和眼睛同時進(jìn)行逼近,并且保證眼珠不能移動到眼睛之外。為了保證眼珠始終在眼睛之內(nèi),將眼珠的定位首先設(shè)置為眼睛正中,再加上一個不超出眼睛范圍偏移量。

左眼珠在眼睛正中的位置為(realX+10,realY+10),右眼珠在眼睛正中的位置為(realX+50,realY+10),偏移量在X和Y軸方向都不能超過10,但是左右眼珠的偏移量是不同的,也就是說人類眼睛觀看偏向某一方的物體的時候,兩只眼球的角度是不同,即它們在X和Y軸上的位移是不同的,為了實現(xiàn)這個角度α,采用其當(dāng)前位置與鼠標(biāo)位置構(gòu)成的直角三角形的斜邊長度與兩條直角邊的比例乘以10 作為偏移量,如左眼球構(gòu)成的直角三角形如圖5所示。

圖5 直角三角形示意圖

眼球位移必須區(qū)分左右來單獨計算。這里我們先來確定左眼球的坐標(biāo),由于不考慮左眼球的實際位置,計算就要簡單的多,將眼球的當(dāng)前位置始終認(rèn)為是處于眼睛中央,而目標(biāo)位置則總是認(rèn)為向內(nèi)集中,其位移計算如圖6所示。

圖6 左眼球位移示意圖

那么其在x軸方向上和y軸方向上的距離分別為:

dy=mouseY-realY-20;

dxLeft=mouseX-realX-20;

計算斜邊長度即左眼球與鼠標(biāo)的直線距離為:

r=Math.sqrt(dxLeft*dxLeft+dy*dy)

由此確定左眼球的下一個位置為(dxLeft*10/r+realX+10,dy*10/r+realY+10)。

需要注意的是,如果眼睛已經(jīng)移動到距離鼠標(biāo)位置很近的位置時,眼睛位置和鼠標(biāo)位置之間距離縮小,其位移距離也相應(yīng)縮小,但是眼球和鼠標(biāo)位置所構(gòu)成的直角三角形的某一個銳角會變得很小[3],導(dǎo)致直角邊和斜邊比接近與1,眼球在眼睛中的偏移量就會接近于10,導(dǎo)致眼球在眼睛中的跳動,為了解決這個問題,采用將r的值始終保持在不小于眼睛的半徑20,即r=Math。max(Math sqrt(dxLeft*dxLeft+dy*dy),20),保證在極為接近目標(biāo)時,眼球在眼睛中呈緩慢轉(zhuǎn)動狀態(tài)。

理解了左眼球位移的計算方法,右眼球也就不難理解了,由于兩眼球在y軸上的位移是相同的,只需要單獨計算出右眼球x軸上的位移即可,不難看出,右眼球x軸上位移為mouseX-realX-60。

在頁面存在的整個過程中,函數(shù)moveeyes()實際上是始終在不停的被調(diào)用的,假如鼠標(biāo)眼睛已經(jīng)成功的移到了目標(biāo)位置,函數(shù)moveeyes()仍舊在不停的執(zhí)行,只不過執(zhí)行的是位移為0的移動。直到退出頁面時,調(diào)用了window 對象的clearTimeout(tID)函數(shù)為止,該定時器才會被釋放。

window.onunload=function() {if (tID) clearTimeout(tID);}。

4 算法運行分析

該算法運行時,可在頁面加載時將眼睛定位與頁面(200,100)的位置,并將眼珠向內(nèi)集中。在鼠標(biāo)移動的過程中,由遠(yuǎn)及近,速度又快到慢的接近鼠標(biāo)位置,實現(xiàn)了逼近鼠標(biāo)的功能,在眼睛逼近過程中眼珠始終保持著向著鼠標(biāo)位置方向的轉(zhuǎn)動。完整的實現(xiàn)了人類行為模擬及逼近算法的實現(xiàn)。

猜你喜歡
眼珠調(diào)用眼球
眼珠為何不怕冷
抓人眼球
抓人眼球
核電項目物項調(diào)用管理的應(yīng)用研究
如何在1分鐘之內(nèi)抓住讀者的眼球
童話世界(2019年25期)2019-10-26 02:27:04
LabWindows/CVI下基于ActiveX技術(shù)的Excel調(diào)用
基于系統(tǒng)調(diào)用的惡意軟件檢測技術(shù)研究
紅眼珠小白兔
快樂語文(2016年12期)2016-11-07 09:45:45
眼球經(jīng)濟(jì)(yǎn qiú jīng jì)[目玉経済]
夢與眼珠轉(zhuǎn)動
栖霞市| 怀来县| 富裕县| 托克托县| 华宁县| 广安市| 丽水市| 屯留县| 漯河市| 奇台县| 京山县| 五台县| 柳州市| 定襄县| 朔州市| 苍南县| 邓州市| 嘉鱼县| 封丘县| 南漳县| 万安县| 遂昌县| 车致| 九龙坡区| 渑池县| 定远县| 城固县| 留坝县| 景洪市| 准格尔旗| 富民县| 原平市| 嘉兴市| 普宁市| 阿尔山市| 华蓥市| 元江| 天气| 甘谷县| 浪卡子县| 合江县|