創建一個追蹤攝像機(2)

為了生成曲線,函數需要通過4個在沿著重量值在0和1之間的路徑上連貫的位置。由于重量在這些2個值之間增加,曲線返回在更遠的路徑上的坐標。

當所提供的重量值為0,曲線將返回正確的坐標在第二個輸入坐標。當所提供的重量值為1,曲線將返回一個準確的坐標在第三個輸入位置。然而,所有4個值在這些計算中來使用, 來確保在第二個和第三個位置之間的平滑路徑,并同樣向前進到下一組運行點。

這個可以使用圖表來舉例說明,在圖所示。如果使用點0,1,2和3來計算曲線,重量在0.0,由此產生的位置會是1。如果重量增加到1.0,曲線坐標軌跡將沿著在點1和點2之間的線,當重量到達1.0,將到達點2。注意,從這個點的,曲線坐標沒有返回值在線上,朝點0或點3,即使它們將通過曲線函數:這些外部點僅使用來計算在中心的2個點之間的曲線角度。

image

一旦重量到達1.0,曲線可以移動到下一組點,進入點1,2,3和4。然后重量再次從0.0增加到1.0后,導致計算的坐標,沿著點2和點3之間的線。

從這組點,它不可能返回在點0和1之間的曲線坐標,或者在點4和5之間(圖表中顯示灰色),有要處理的路徑這些部分的不足外部點。

通過在點到點之間的移動路徑,一個平滑曲線可以減少,穿過所有定義的位置。這一切在三維空間也能做的很好。

提示:當定義一個路徑,別忘記它將采取完全相同的大量時間在每一個連貫的路徑點之間移動。因此,你應該嘗試去確保點近似等距。點有不同于其它的大的差距將導致更快的移動,在固定時間間隔內穿過增加的距離,點更接近在一起將導致移動緩慢,因為少距離必須要去移動。

為了創建一個封閉的路徑,允許飛機去循環,無縫的回到它最初的點再重新開始,我們必須確保最終的曲線的三個點與三個點的第一個相同。當三個點的重量到達1.0時,曲線坐標將終于到達回正確的在移動路徑上的點1的位置,允許整個路徑從再次從最開始就可以被跟蹤。

我們在PaperPlaneObject代碼中實現它,通過存儲2個類級變量,一個int值稱為_splineIndex,它定義4個點的第一個索引來使用曲線計算;一個浮點值稱為_splineWeight,它允許我們來沿著曲線在定義點之間穿過路徑。

在Update函數中,我們添加一個小的總額到_splineWeight變量中。如果它到達或超過1.0,我們要將它減1.0,并增加_splineIndex。如果_splineIndex通過移動路徑的最后的數組點,它重新設置回開始。這些更新沿著曲線移動飛機,并當它到達它的移動路徑的重點后,重新設置回起點。

在這些更新模式下,我們調用GetPlanePosition函數來執行曲線計算,并返回最終飛行坐標。這個函數,期望曲線索引和曲線重量值來作為參數來傳遞,下面代碼將描述。

private Vector3 GetPlanePosition(int splineIndex, float  splineWeight)
{Vector3 ret;// If the  weight  exceeds 1,  reduce by 1 and move  to  the  next  index if (splineWeight > 1){splineWeight  -=  1;splineIndex += 1;}// Keep  the  spline index  within the  array  boundssplineIndex = splineIndex %   _movementPath.Length;// Calculate  the  spline positionret = Vector3.CatmullRom(_movementPath[splineIndex],_movementPath[(splineIndex + 1)  %   _movementPathLength],_movementPath[(splineIndex + 2)  %   _movementPathLength],_movementPath[(splineIndex + 3)  %   _movementPathLength], splineWeight);return ret;
}

這代碼首先檢查曲線重量是否大于1。如果是,它就減去1并且切換到下一個曲線索引(我們將一會兒看到這個原因)。其次是檢查循環曲線索引,是否它超過_movementPath數組項目的界限。

曲線坐標然后會簡單的計算,通過傳遞4個矢量坐標和曲線重量到Vector3.CatmullRom函數。注意,然而,因為我們在曲線索引指上使用指數運算符,如果它們超過數組長度,它們會循環回到最初的開始。這個運算允許我們去實現我們的閉合環路(要求重復前3個點),而不必實際在數組中重復它們:它們只是一開始就重復使用,當到達數組末尾時。

隨著有能力手動去計算飛行坐標,我們現在可以設置飛行的坐標和沿著軌跡去平滑移動。這是好的開始,但這是非常明顯的可視化問題,當它在運動時:飛行總是對著同一個方向。當然,總是朝著移動的方向(紙飛機通常來說不會側面飛行的很好)。

幸運的是,這是非常容易讓飛行看上去它是正在飛行的。我們需要做的第一件事是計算另一個飛行坐標,僅遠一點沿著軌跡。我們通過調用GetPlanePosition函數,在1秒鐘內來完成它,這個時候添加0.1到曲線重量中。此外的原因是GetPlanePosition函數檢查是否重量超過1.0,因為這一秒可以引起溢出的發生。

第二個調用允許我們看到現在在哪里飛行,下一秒后將會在哪里。飛行的方向必須從這些點到下一秒所在的點,因為它的軌跡是移動的。因此我們需要一個旋轉飛機的方法以便它面朝從第一個位置到下一個秒所要到的位置。

這個旋轉可以使用另一個便利的靜態的矩陣函數來完成:CreateWorld。CreateWorld函數創建一個世界矩陣(它是最后我們要在每一個對象的Update方法中嘗試去做的)以便它放置在特別的位置上,面對特別的方向。這就是我們所需要的:位置是我們已計算出來的第一條曲線,方向從這到下一條曲線點。

通過從下一個位置減去當前位置來簡單計算方向。由此產生的矢量準備作為參數傳遞給CreateWorld。

有一個小問題任然存在:飛機是持續向一側飛行的,因為它的一側已經在SketchUp模式下定義了。要修正這個問題,矩陣計算后,我們簡單旋轉90度角來旋轉它。

計算位置和飛行方向的完整代碼如下代碼所示。

// Calculate  the  current position and store  in the  Position property
Vector3 Position = GetPlanePosition(_splineIndex, _splineWeight);// Calculate  the  next  position too  so we  know  which way we  are moving
Vector3 nextPosition = GetPlanePosition(_splineIndex, _splineWeight  + 0.1f);// Find the  movement  direction
Vector3 delta  = nextPosition - Position;// Create the  world  matrix  for the  plane
Transformation  = Matrix.CreateWorld(Position, delta,  Vector3.Up);
// The plane needs to  be rotated 90 degrees   so that  it points
// forward, so apply  a rotation
ApplyTransformation(Matrix.CreateRotationY(MathHelper.ToRadians(-90)));

最終結果是我們有一個平滑的逼真的在房屋間圍繞場景飛行。你可以通過運行ChaseCam工程看到實際效果—最初的視圖使用一個不會追逐飛行軌跡的相機,而是慢慢的環繞這個場景,允許簡單的看到飛行軌跡。

轉載于:https://www.cnblogs.com/appleseeker/archive/2012/05/24/e5889be5bbbae4b880e4b8aae8bfbde8b8aae69184e5838fe69cba2.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/260789.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/260789.shtml
英文地址,請注明出處:http://en.pswp.cn/news/260789.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Xcodebuild自動打包

#! /bin/bash #firtoken 29b441056e1e17c984cb32fadadsdddd shell_dirdirname $0 TARGET_NAME"SmartLock" DIR_PATH/Users/用戶名/Desktop/SmartLock SIGN"iPhone Distribution:******" PROFILE"66d127d6-7963-4c20-ac8b-47e4f0fe8742" TEMP_DIR…

第3章 Python 數字圖像處理(DIP) - 灰度變換與空間濾波12 - 空間域濾波基礎 - 卷積運算(numpy 實現的三種卷積運算)

這篇文章比較長,請耐心看空間域濾波基礎線性濾波可分離濾波器核空間域濾波和頻率域濾波的一些重要比較如何構建空間濾波器第一種卷積方法(公式法)第二種卷積的方法(可分離核)第三種方法(img2col)這是分離核…

hdu_1861_游船出租_201402282130

游船出租 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7238 Accepted Submission(s): 2411 Problem Description 現有公園游船租賃處請你編寫一個租船管理系統。當游客租船時,管理員輸入船號并按…

acer清理工具 clear下載_SolidWorks綠色版下載-SolidWorks完全清理工具v1.0免費版

SolidWorks完全清理工具(SWCleanUninstall)是一款綠色免費的SolidWorks完全卸載工具。很多SolidWorks安裝不成功都是因為之前安裝錯誤做成軟件殘留。這款工具可以完全清理很多SolidWorks留下的注冊表垃圾。軟件核心功能1、SWCleanUninstall可以直接刪除電腦上的SolidWorks軟件2…

ZOJ1221 Risk 圖形的遍歷

一開始做圖形遍歷的題都是用鏈表做的&#xff0c;這次用數組體會到了方便但就是有點浪費。 不過題目給的內存限制已經足夠了。 View Code 1 #include<cstdio>2 #include<cstdlib>3 #include<cstring>4 #include<queue>5 #include<iostream>6 7 …

Android 從AndroidManifest獲取meta-data

語法如下&#xff1a; <meta-data android:name"string"android:resource"resource specification"android:value"string" /><meta-data>標簽可以作為子標簽&#xff0c;可以被包含在<activity>、<application> 、<s…

trim()函數

參數string&#xff1a;string類型&#xff0c;指定要刪除首部和尾部空格的字符串返回值String。 函數執行成功時返回刪除了string字符串首部和尾部空格的字符串&#xff0c;發生錯誤時 返回空字符串&#xff08;""&#xff09;。 如果參數值為null時&#xff0c;會拋…

第3章 Python 數字圖像處理(DIP) - 灰度變換與空間濾波13 - 平滑低通濾波器 -盒式濾波器核

這里寫目錄標題平滑&#xff08;低通&#xff09;空間濾波器盒式濾波器核平滑&#xff08;低通&#xff09;空間濾波器 平滑&#xff08;也稱平均&#xff09;空間濾波器用于降低灰度的急劇過渡 在圖像重取樣之前平滑圖像以減少混淆用于減少圖像中無關細節平滑因灰度級數量不…

python中str用法_python數據類型之str用法

1、首字母大寫 語法&#xff1a;S.capitalize() ->str title "today is a good day"title_catitle.capitalize() print(title_ca) 結果&#xff1a;today is a good day 2、大寫轉小寫 1 語法&#xff1a;S.casefold() ->str2 3 title "TODAY is a GOOD …

WPF 窗體設置

WPF 當窗體最大化時控件位置的大小調整&#xff1a; View Code 1 <Window x:Class"WpfApplication1.MainWindow"2 xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"3 xmlns:x"http://schemas.microsoft.com/wi…

Git實踐

Git是什么自不必說。Git和gitlab安裝和實踐在后邊的倆篇中會寫。本篇僅重點寫Git自動部署。Git同樣有Hooks,可以用于各種需求。可以控制提交commit名稱&#xff0c;可以控制代碼規范&#xff0c;也當然包含以下要介紹的自動部署&#xff0c;也不僅包含這些。Git自動部署簡單的思…

第3章 Python 數字圖像處理(DIP) - 灰度變換與空間濾波14 - 平滑低通濾波器 -高斯濾波器核的生成方法

目錄平滑&#xff08;低通&#xff09;空間濾波器低通高斯濾波器核統計排序&#xff08;非線性&#xff09;濾波器平滑&#xff08;低通&#xff09;空間濾波器 平滑&#xff08;也稱平均&#xff09;空間濾波器用于降低灰度的急劇過渡 在圖像重取樣之前平滑圖像以減少混淆用…

易經0

--- 陽爻 - - 陰爻 從下往上 畫爻 (yao) 三畫卦 --> 2^38 (八卦) 那天有空用程序 解析一下 六畫卦 --> 2^664(卦) 卦形記憶歌&#xff1a;宋代朱熹的《周易本義》寫了《八卦取象歌》幫人記卦形&#xff1a; 乾三連&#xff0c;坤六斷&#xff1b;震仰盂&#xff0c;艮覆碗…

python3.7怎么安裝turtle_python怎么安裝turtle

turtle庫是Python語言中一個很流行的繪制圖像的函數庫&#xff0c;想象一個小烏龜&#xff0c;在一個橫軸為x、縱軸為y的坐標系原點&#xff0c;(0,0)位置開始&#xff0c;它根據一組函數指令的控制&#xff0c;在這個平面坐標系中移動&#xff0c;從而在它爬行的路徑上繪制了圖…

強制html元素不隨窗口縮小而換行

<style> div{ white-space:nowrap; } </style> 強制div內的元素不隨窗口縮小而換行 本文出自 “點滴積累” 博客&#xff0c;請務必保留此出處http://tianxingzhe.blog.51cto.com/3390077/1679366

靜態變量、方法

static 變量---所有對象共享一個變量&#xff08;全局變量區&#xff09;&#xff0c;無需構造---概念上和.net相同所有對象共享一個變量的實質&#xff1a;聲明時&#xff1a;堆區存放一個地址&#xff0c;地址指向全局變量區。然后當類對象聲明時&#xff0c;只是在堆區中為自…

python語言是機器語言_Python解釋器:源代碼--字節碼--機器語言

"一個用編譯性語言比如C或C寫的程序可以從源文件&#xff08;即C或C語言&#xff09;轉換到一個你的計算機使用的語言&#xff08;二進制代碼&#xff0c;即0和1&#xff09;。這個過程通過編譯器和不同的標記、選項完成。當你運行你的程序的時候&#xff0c;連接/轉載器軟…

第3章 Python 數字圖像處理(DIP) - 灰度變換與空間濾波15 - 銳化高通濾波器 -拉普拉斯核(二階導數)

目錄銳化&#xff08;高通&#xff09;空間濾波器基礎 - 一階導數和二階導數的銳化濾波器二階導數銳化圖像--拉普拉斯銳化&#xff08;高通&#xff09;空間濾波器 平滑通過稱為低通濾波類似于積分運算銳化通常稱為高通濾波微分運算高過&#xff08;負責細節的&#xff09;高頻…

Debian on VirtualBox下共享win7文件夾設置

借用&#xff1a;http://www.dbasoul.com/2010/695.html 1. 安裝增強功能包(Guest Additions) 參考文檔&#xff1a;Debian下安裝VirtualBox增強功能2. 設置共享文件夾 重啟完成后點擊”設備(Devices)” -> 共享文件夾(Shared Folders)菜單&#xff0c;添加一個共享文件夾&a…

第四周作業

1、復制/etc/skel目錄為/home/tuser1&#xff0c;要求/home/tuser1及其內部文件的屬組和其它用戶均沒有任何訪問權限。cp -r /etc/skel/ /home/tuser1/chmod -R go--- /home/tuser1/2、編輯/etc/group文件&#xff0c;添加組hadoop。vim /etc/group G, o, hadoop:x:501, esc, …