Archive

2008年7月 的Archive

當觸控螢幕加上力回饋

2008年7月29日 尚無評論
科技真是始終來自人性, 這句話真的是再度印證人類的欲望是無窮的

當觸控螢幕大行其道的開始被應用在各種不同的使用者環境中時,

我們開始對觸控式螢幕有了更深一步的要求, 便是要能知道是否有按下,

透過聲音跟光影的變化, 當然可以很輕易的產生出是否有被按下的效果,

但卻無法滿足人體最直覺的觸覺反應, 所以國外公司發展出了觸覺反饋,

也就是當觸控在觸控螢幕上, 透過軟體跟機械硬體的乘載機構, 產生

各種不同類似機械式反應的震動, 讓使用者誤認為是直接接觸在按鈕上,

也許透過這樣的發展, 未來的鍵盤, 恐怕真的不在有機械式的, 而被觸控

加上觸覺反饋的設備給取代, 將來可能一個鍵盤不但可以是鍵盤, 也可以

是 TouchPad, 甚至有可能是繪圖板,在加上螢幕的話, 未來恐怕筆記本

打開, 就跟 NDS 一樣, 上下都是觸控螢幕, 這樣的夢想會不會在NDS上

首先被實現呢? 呵呵

美國Immersion發佈觸覺反饋式觸控螢幕的開發套件

DATE 2008/07/29

  【日經BP社報導】美國Immersion發佈了觸覺反饋式觸控螢幕開發套件(英文發佈資料)。觸覺反饋技術採用該公司的“TouchSense”。在螢幕上按壓手指、描畫,能夠以按壓機械式開關般的感覺進行操作。該產品支援最大6吋的小螢幕尺寸。設想配備于PMP、PND及固定電話等產品上。

  TouchSense技術與觸覺感測器的組合此前存在一些問題,例如,輸入方式從機械式鍵盤向觸覺感測器轉換時,會產生錯誤的觸覺反饋等。此次對誤操作方面的問題進行了改善,達到了用戶可以接受的程度。開發套件除印刷電路板外,還同時提供固件及觸覺反饋技術的類庫。

  該公司生產的最大支援36吋大螢幕幕尺寸的觸覺反饋式觸控螢幕目前已被ATM和自助服務終端(Kiosk)等採用。

  另外,SMK此前曾公開過配備基於觸覺反饋技術的觸控螢幕手機(參閱本站報導)。SMK從2006年2月開始接受了Immersion的“TouchSense”技術授權。(記者:吉澤 惠)

Immersion的觸覺反饋式觸控螢幕開發套件
原文網址: http://big5.nikkeibp.co.jp/china/news/flat/flat200807290118.html?ref=ML
Categories: 新知快報 Tags:

翻轉翻轉~翻轉元件做好囉

2008年7月24日 尚無評論
暫時先看看影片吧, WPF 裡面有些物件還不知道怎麼用,

所以有點小 Bug, 等到臭蟲除完了再發表心得吧~呵呵

Categories: 軟體技術 Tags:

3D 旋轉球測試 (程式篇 三) [轉載請通知, 謝謝]

2008年7月22日 尚無評論

下面我們就來撰寫程式設計師的互動部分, 我們把這些互動放在外部程式, 可以依據需求做出許多不同的變化, 例如放大縮小旋轉點選等等各種功能,在 VB.NET Express 當中, 會根據我們所寫的 XAML 來自動產生一個 .g的隱藏程式檔, 主要是宣告 XAML 定義有名稱的物件我們可以直接使用,以下我們就依序來介紹如何讓球互動起來.

Private myLastPoint As Media3D.Point3D
Private myThisPoint As Media3D.Point3D
Private myRotate As Media3D.Vector3D Private myAngle As Double = 0 
Private WithEvents tmr As New System.Timers.Timer(1000 / 25) 
Private Sub Window1_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded 
tmr.Start() 
Debug.Listeners.Add(New Diagnostics.ConsoleTraceListener()) 
End Sub

首先, 針對宣告部分, 我們主要記錄兩個觸控的位置, 來計算移動量, 另外須要有參數記錄旋轉的角度, 以及旋轉所繞行的中心軸,還有就是要有一個計時器, 目的是要自行製作甩開後的動畫,透過計時器來達到背景執行的目的, 所以當視窗一載入後,我們便啟動計時器, 以隨時準備接受有移動向量參數時要自動執行動畫

Private Sub Window1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Input.MouseWheelEventArgs) Handles Me.MouseWheel
        slider3.Value += e.Delta / (120 * 10 * 7)
End Sub
Private Sub Window1_TextInput(ByVal sender As Object, ByVal e As System.Windows.Input.TextCompositionEventArgs) Handles Me.TextInput
        Dim s As String = sphere.Text
        s += e.Text
        sphere.Text = Right(s, 100)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
        sphere.Transform = New Media3D.TranslateTransform3D(0, 0, 0)
End Sub

這部分主要是讓滑鼠的滾輪可以改變球體的大小, 以及輸入文字時可以改變球體上貼圖的文字, 由於元件都已設定好該方法, 所以僅需在收到滑鼠鍵盤訊息時, 將參數資料傳送給該物件即可,另外就是增加一個按鍵可以讓球體恢復到原始的角度.

    Private Sub vport_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles vport.MouseDown
        If e.LeftButton = MouseButtonState.Pressed Then
            myAngle = 0
            Dim r As Media3D.RayHitTestResult = VisualTreeHelper.HitTest(sender, e.GetPosition(sender))
            If r.VisualHit.GetType Is GetType(Shapes.Sphere) Then
                myLastPoint = r.PointHit
                Labelx1.Content = myLastPoint.X.ToString
                Labely1.Content = myLastPoint.Y.ToString
                Labelz1.Content = myLastPoint.Z.ToString
            Else
                myLastPoint = Nothing
            End If
        End If
    End Sub

當滑鼠按下或是有觸控事件發生時, 我們必須記錄其觸控的位置,以便後續計算移動位移的基準, 這裡使用 HitTest 來取得 2D 轉換到 3D 的點擊坐標位置, 但這裡取得的是 3D 原始模型的座標位置,也就是不論 Transform 如何變化, 其取得的位置還是相對於原始建構 3D 模型的座標系(這點不太容易說明, 但一定要理解這段)

Private Sub vport_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Input.MouseEventArgs) Handles vport.MouseMove
        If e.LeftButton = MouseButtonState.Pressed Then
            Dim r As Media3D.RayHitTestResult = VisualTreeHelper.HitTest(sender, e.GetPosition(sender))
            If r.VisualHit.GetType Is GetType(Shapes.Sphere) Then
                myThisPoint = r.PointHit
                Labelx2.Content = myThisPoint.X.ToString
                Labely2.Content = myThisPoint.Y.ToString
                Labelz2.Content = myThisPoint.Z.ToString                Dim vt As Media3D.Vector3D = sphere.Transform.Transform(myThisPoint)
                Dim vl As Media3D.Vector3D = sphere.Transform.Transform(myLastPoint)
                Dim al As Double = Media3D.Vector3D.AngleBetween(vl, vt)
                Dim ct As Media3D.Vector3D = Media3D.Vector3D.CrossProduct(vl, vt)
                Dim mt As New Media3D.RotateTransform3D(New Media3D.AxisAngleRotation3D(ct, al))
                sphere.Transform = New Media3D.MatrixTransform3D(Media3D.Matrix3D.Multiply(sphere.Transform.Value, mt.Value))                Labelx3.Content = ct.X.ToString
                Labely3.Content = ct.Y.ToString
                Labelz3.Content = ct.Z.ToString
            Else
                myThisPoint = Nothing
            End If
        End If
    End Sub

整段程式的重點就在這裡了, 要旋轉一個 3D 物件, 當然我們可以使用 Transform 裡面各種不同的Transform來計算, 但是這裡為什麼我們要用 MatrixTransform 呢? 因為所有的 Transform都是相對於原始物件的模型建構座標為基準去計算, 所以如果用其他的 Transform 並沒有辦法去針對現有的座標系, 也就是說經由 Transform 轉換的座標系在做運算, 但我們觸控的動作是連續性值的, 因此必須要從新的座標系去產生相對的位移動作, 所以整個程式的流程如下說明

1. 將 Hittest 的座標經由現有的 Transfrom Matrix 去做轉換,以取得原有模型的座標系, 相對於在 Transform 以後的座標系座標.
2. 計算兩觸控點相對於球體中心所產生的位移角度,
3. 計算兩觸控點相對於球體中心所產生的平面的垂直線, 也就是要旋轉角度的中心軸,
4. 利用旋轉角度及中心軸產生一組新的座標系, 該座標系是以旋轉後的座標系為基礎的位移差
5. 將該組座標系與現有旋轉後的座標系相加, 得出的結果便是再一次新旋轉的新座標系, 因此這裡要用 Martix Transform 來做, 才能用矩陣相乘的方式很快取得新的座標系雖然程式只有短短的幾行, 但這一段非常難以說明, 建議大家只好回去念念高中學的空間向量跟二維矩陣 (忘了是高中還是大學學的~呵呵)

Private Sub vport_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles vport.MouseUp
        If e.LeftButton = MouseButtonState.Released Then
            Dim r As Media3D.RayHitTestResult = VisualTreeHelper.HitTest(sender, e.GetPosition(sender))
            If r.VisualHit.GetType Is GetType(Shapes.Sphere) Then
                Dim vt As Media3D.Vector3D = sphere.Transform.Transform(myThisPoint)
                Dim vl As Media3D.Vector3D = sphere.Transform.Transform(myLastPoint)
                myAngle = Media3D.Vector3D.AngleBetween(vl, vt)
                myRotate = Media3D.Vector3D.CrossProduct(vl, vt)
                myLastPoint = myThisPoint
            Else
                myThisPoint = Nothing
            End If
        End If
    End Sub

這段程式主要就是紀錄甩開動作時 (滑鼠按鍵放開) 的移動軌跡跟方向, 所以我們記錄最重要的兩個變數, 中心軸跟角度差, 以便後續計時器可以繼續產生甩出後球體逐漸變慢的動畫效果

   Private Sub tmr_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles tmr.Elapsed
        vport.Dispatcher.Invoke(Windows.Threading.DispatcherPriority.Normal, New noargs(AddressOf updateui))
    End Sub    Delegate Sub noargs()    Private Sub updateui()
        If myAngle <> 0 Then
            myAngle *= 0.95
            If Math.Abs(myAngle) < 1 Then
                myAngle = 0
            Else
                Dim rt As New Media3D.RotateTransform3D(New Media3D.AxisAngleRotation3D(myRotate, myAngle))
                sphere.Transform = New Media3D.MatrixTransform3D(Media3D.Matrix3D.Multiply(sphere.Transform.Value, rt.Value))
            End If
        Else
            myRotate = Nothing
            myAngle = 0
        End If
    End Sub

這兩段程式最主要的兩個重點是, 一 多執行緒的問題顯示元件更新的問題, 二 逐漸減慢的動作運算針對一的部分, 因為計時器元件並非在顯示元件的主程式執行緒裡直行, 因此無法更新顯示元件資料所以必須用到 Invoke 或是 BeginInvoke 來通知原來的執行緒佇列要去執行更新資料的程式二的部分, 則是我們中心軸維持不變, 要改變的只是旋轉角度逐漸變小, 因此我們用壘乘的方式來產生單位時間內角度越來越小的位移量, 為什麼是單位時間呢, 因為我們一開始便給定計時器每秒內要來檢查 25 次是否有角度需要被旋轉, 所以當旋轉角度<-1 或 >1 時就必須要旋轉

以上這一小段程式便可以模擬 Google Earth 的旋轉 UI 效果, 而且是精確的追蹤到手指移動到的位置, 也就是說無論 3D 模型是用什麼方式投射在 2D 平面上, 無論經過幾次的旋轉, 都可以準確的追蹤鼠標或是手指的位置, 當然現在很多程式僅採用相對移動方式, 也就是僅處理,鼠標或是手指移動的方向, 而不去準確的計算 2D 平面對應到 3D 模型時相對應的正確位置,這對於要在一個 3D 模型上去點選一個點, 或是選取一個範圍, 就完全無法應用了, 所以採用這樣的演算方式才能正確計算投影座標位置.

微軟的 WPF 在 3D 上面確實有讓人驚艷的地方, 也就是這些涵式也都已經完全建立好, 當然,矩陣的乘除, 向量的計算, 都可以用簡單的數學公式來完成, 但對於 Flash 來說, 這些都必須自行撰寫, 雖然市面上已經有很多寫好的 AS , 但在國內真的要找到好的 AS 設計師也是相當不容易, 所以很多國外寫好的 AS 依然沒有多少使用者會使用. 尤其是在 3D 部分的 AS 更是讓程式設計師頭大的問題~呵呵, 所以我還是用最簡單的 VB 來寫啦~呵呵

Categories: 軟體技術 Tags:

“以大螢幕提高效率” 日立展示車站導遊顯示器

2008年7月22日 尚無評論
強烈建議政府打造國內優質旅遊便民環境, 韓國政府推動 U-City, 在城市內處處可見到

互動式的導覽系統, 對該城市旅遊景店, 特色文化進行介紹, 北京政府因應奧運也在北京

各重要路口設置導覽亭, 日本也在車站內提供大屏幕的互動導覽, 香港也在機場內提供

導覽服務不但可以整合一般的導覽, 更可進一步整合公眾布告欄, 電子留言板, 甚至商業

廣告來提升服務品質並且增加公眾事業收益, 如此可達到雙贏的局面.

反觀台灣不但公眾場合沒有該類型互動導覽系統, 甚至人口使用度極高的台北捷運也沒有,

台灣觀光客每年 350 萬人, 卻沒有可以讓這 350 萬人可以更了解, 更便利, 更喜愛這地方

的公眾行銷工具, 就算不論觀光客, 對於搭乘捷運的旅客來說, 如果到了一個新地方, 第一件

就是想知道要去的地方在哪裡, 比如說台北車站有 10 幾個出口, 又連結地下街, 往往想去

植物園都不知道該從哪個出口出去, 出去後有哪些公車可以接駁, 再者台北市地下街若非

經常通勤人員, 常可以發現外來旅客在裡面看地圖, 看指標, 繞了半天還會回到原來的地方,

希望政府能夠在執行擴大內需預算上面, 把花費用到真正有用的地方, 透過這種互動導覽

不但可以讓民眾感覺更便利, 讓外地旅客感到更親合, 讓觀光客更了解地方特色, 甚至結合

周邊特色商店, 小吃, 古蹟等等, 透過廣告增加公眾服務收益, 減少人民稅收, 如此不但政府

與民眾能夠雙贏, 更能讓台灣這地方與世界接軌, 達到多贏的局面. 

原文引用來自 技術在線 日經 BP 社報導 http://big5.nikkeibp.co.jp/china/news/flat/flat200807220118.html?ref=ML

DATE 2008/07/22

  【日經BP社報導】

圖:配備觸控面板的“觸控式導遊板”。詳細地圖中顯示了從所在地到目的地的路線

  日立製作所在該公司展會“Hitachi uVALUE CONVENTION 2008”上,展出了用帶觸控螢幕功能的液晶顯示器提供車站導向圖的“觸控式導向板”。該顯示器通常用於指示月臺和車站內設施的方向。觸摸顯示設施的名稱,即可顯示詳細地圖和去往該設施的路線。還配備有學習功能,查詢次數越多的設施在詳細顯示時的排序越靠前。

  日立製作所于2007年1月~2008年2月,在東日本旅客鐵道(JR東日本)品川車站內的商業設施“ecute品川”附近,試運行了“觸控式導向板”。剛在牆柱兩側設置後,“每當有人使用,都會有很多人圍觀”(解說員),頻繁使用的人越多,使用頻率也就會高。此次的展品增加了搜索功能。當輸入“香煙”時,能夠顯示吸煙區等資訊。該展品預定將從2008年夏季開始,設置在東京車站內八重洲中央口附近的新幹線檢票口附近,進行試運營。(記者:宇野 麻由子)

■日文原文
「大画面で稼働率が向上」,日立製作所の駅向け案内表示

■相關報導
【FPD】景深效果鮮明!日立展出立體顯示器

【FPDI】日立顯示器開發亮度增至1.4倍的便攜產品用IPS液晶面板

【CEATEC】富士通強化廣告用顯示器業務 大螢幕立式PDP挺立街頭

■讀者反饋
感謝您的意見反饋!
讀者反饋的意見不代表日經BP社的立場與觀點。日經BP社對讀者反饋的內容的信賴性和合法性不做任何保證。由讀者反饋引發的任何糾紛,日經BP社不擔負任何責任。請讀者本著對自己的反饋負責的態度利用本服務。

Nikkei Electronics

 原文連結: http://big5.nikkeibp.co.jp/china/news/flat/pr_flat200807220118.html
Categories: 未來科技 Tags:

3D 旋轉球測試 (程式篇 二) [轉載請通知, 謝謝]

2008年7月21日 尚無評論

 

接下來就是屬於藝術設計或是稱做 ART / UI Designer 的主要工作了, 把畫面給架構出來,

在 WPF 裡面架構畫面主要是採用 XAML,跟 XML 的描述方式差不多, 當然, 對 ART Designer

來說可以用更直覺化的工具來產生畫面, 例如 Blend Express, 由於物件已經完成,

所以可以即時反應所給予的參數, 並呈現於設計工具裡面, 也就是立即達到所見及所得的效果,

而非憑空想像, 這點對 ART Designer 幫助很大, 不會再有跟 Programmer 溝通不良的問題,

當然利用 XML 架構也有許多好處, 比如說可攜性, 交換性, 活用性, 架構性 都相當的完善與便利,

舉例來說, 各位只要把這個 XAML 複製過去, 即可把整各 UI 架構給複製過去, 如果要改變球體,

也只要修改其中的參數, 在設計工具的畫面裡面, 立可就能呈現出來修改參數後的效果,

這裡可以見到, 微軟的野心, 就如同作業系統一樣, 將底層平台架構完整, 將來勢必又是被”教育”

成”傻瓜使用者”, 只要如同操作傻瓜相機一般, 一個按鈕搞定一切, 呵呵~~

<window x:Class="Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1.Shapes"     
    Title="Window1" Height="610.122" Width="633.46" Name="Window1">
    <grid>
        </grid><grid .RowDefinitions>
            <rowdefinition Height="105.021*" />
            <rowdefinition Height="499.479*" />
        </grid>
 
        <grid Grid.Row="0">
            </grid><grid .RowDefinitions>
                <rowdefinition Height="*" />
                <rowdefinition Height="*" />
                <rowdefinition Height="*" />
            </grid>
            <grid .ColumnDefinitions>
                <columndefinition Width="198.373*" />
                <columndefinition Width="546.447*" />
            </grid>
            <!--<SnippetSliders>-->
            <slider Grid.Row="0" Grid.Column ="1" Name="slider1" Width="448.605680056927"
                    HorizontalAlignment="Left" Margin="0,0,0,7.105427357601E-15"
                    Value="{Binding ElementName=sphere, Path=ThetaDiv}" Minimum="1" Maximum="100"/>
            <slider Grid.Row="1" Grid.Column ="1" Name="slider2"
                    Margin="5.6843418860808E-14,2.1316282072803E-14,0,0"
                    Value="{Binding ElementName=sphere, Path=PhiDiv}" Minimum="1" Maximum="100"/>
            <slider Grid.Row="2" Grid.Column ="1" Name="slider3"
                    Value="{Binding ElementName=sphere, Path=Radius}" Margin="5.6843418860808E-14,-2.8421709430404E-14,0,0"
                     Minimum="0" Maximum="2" />
            <!--</SnippetSliders>-->
            <label Margin="0,0,0,0" Grid.Row="0" Name="label1">Theta</label>
            <label Margin="0,0,0,0" Grid.Row="1" Name="label2">Phi</label>
            <label Margin="0,0,0,0" Grid.Row="2" Name="label3">Radius</label>
            <label Margin="62,0,0,0" Name="Label4" Content="{Binding ElementName=slider1, Path=Value}"/>
            <label Content="{Binding Path=Value, ElementName=slider2}" Margin="62,0,0,0" Name="Label5" Grid.Row="1" />
            <label Content="{Binding Path=Value, ElementName=slider3}" Margin="62,0,0,0" Name="Label6" Grid.Row="2" />
 
 
        <!--<SnippetViewport3D>-->
        <viewport3d x:Name="vport" Grid.Row="1">
            <!-- The camera for the scene -->
            </viewport3d><viewport3d .Camera>
                <perspectivecamera Position="0,0,4" />
            </viewport3d>
 
            <local :Sphere x:Name="sphere" Text="1234567890 10 11 12 13 14 15">
                </local><local :Sphere.Transform >
                    <transform3dgroup>
                        <translatetransform3d OffsetX="0" OffsetY="0" OffsetZ="0"/>
                        <scaletransform3d ScaleX="1" ScaleY="1" ScaleZ="1"/>
                        <rotatetransform3d CenterX=" 0" CenterY=" 0" CenterZ=" 0">
                            </rotatetransform3d><rotatetransform3d .Rotation >
                                <axisanglerotation3d x:Name="rotate" />
                            </rotatetransform3d>
 
                    </transform3dgroup>
                </local>
 
 
 
            <!-- Lights -->
            <modeluielement3d>
                </modeluielement3d><modeluielement3d .Model>
                    <model3dgroup>
                        </model3dgroup><model3dgroup .Children>
                            <directionallight Color="WhiteSmoke"  Direction="0,0,-1" />
                        </model3dgroup>
 
                </modeluielement3d>
 
 
 
        <label Grid.Row="1" Height="29" HorizontalAlignment="Left" Name="Labelx1" VerticalAlignment="Top" Width="58">Label</label>
        <label Height="29" HorizontalAlignment="Left" Margin="62,0,0,0" Name="Labely1" VerticalAlignment="Top" Width="58" Grid.Row="1">Label</label>
        <button Grid.Row="1" Height="21" HorizontalAlignment="Right" Margin="0,8,14,0" Name="Button1" VerticalAlignment="Top" Width="51">Button</button>
        <label Grid.Row="1" Height="21" HorizontalAlignment="Left" Margin="0,27.604,0,0" Name="Labelx2" VerticalAlignment="Top" Width="47">Label</label>
        <label Height="21" HorizontalAlignment="Left" Margin="62,27.604,0,0" Name="Labely2" VerticalAlignment="Top" Width="47" Grid.Row="1">Label</label>
        <label Height="21" HorizontalAlignment="Left" Margin="115.854,27.604,0,0" Name="Labelz2" VerticalAlignment="Top" Width="47" Grid.Row="1">Label</label>
        <label Height="29" HorizontalAlignment="Left" Margin="115.854,0,0,0" Name="Labelz1" VerticalAlignment="Top" Width="58" Grid.Row="1">Label</label>
        <label Height="21" HorizontalAlignment="Left" Margin="0,54,0,0" Name="Labelx3" VerticalAlignment="Top" Width="47" Grid.Row="1">Label</label>
        <label Height="21" HorizontalAlignment="Left" Margin="62,54,0,0" Name="Labely3" VerticalAlignment="Top" Width="47" Grid.Row="1">Label</label>
        <label Height="21" HorizontalAlignment="Left" Margin="115.854,54,0,0" Name="Labelz3" VerticalAlignment="Top" Width="47" Grid.Row="1">Label</label>
        <!--</SnippetViewport3D>-->
 
</window>

 

上面程式中大部分都在描述整體畫面, 所以不詳加介紹, 請各位讀者大大自行參閱 WPF 文件,

其中只有兩個地方要特別說明的是, 1 Data Binding 的觀念, 因為之前的物件參數交由 vhost 管理

所以這裡可以輕易的達成 Databinding, 這可以節省許多需要動用程式設計師來撰寫程式的麻煩,

只要由 ART Designer 直接把兩物件的直關聯起來便可以達成互動效果, 例如以下我們把 sliderbar

跟我們自行製作的物件中的 ThetaDiv 關聯起來, 就可以直接用 sliderbar 來調整這個參數值,

Value=”{Binding ElementName=sphere, Path=ThetaDiv}”, 這樣一行就取代掉 Programming

第 2 點, 物件相容的整合性, 由於我們在設計元件時, 繼承了 UIElement 的特性, 所以很多各種

應用可以直接套用, 例如各種不同的 Transform, 原本在這裡僅需要一行指令(如下) 即可

<local:Sphere x:Name=”sphere” Text=”1234567890 10 11 12 13 14 15″ />

但是 ART Designer 可以輕易透過 Transform 來改變他原有的角度, 大小, 位置,

所以在這個 XAML 裡面加入 Transform 宣告, 來測試他即時再 UI 上面呈現的結果,

這裡比較需要說明的是, 因為我們程式需要直接掌握 Transform 參數, 才能正確轉換鼠標位置,

所以在 Transofrm 裡面去定義任何參數, 如 <AxisAngleRotation3D  x:Name=”rotate” />

其實是沒有意義的, 因為這個定義很快會在我們的程式裡面把它給覆蓋掉, 下一篇, 我們將介紹

如何讓這個球體能夠互動起來, 其中最難理解的地方應該是在 3D 空間座標的轉換, 因為透過 Transform

之後, 要在一個 3D 立體物件上偵測滑鼠的點擊(Hittest), 雖然 WPF 有相當好用的物件可以使用,

但基本上這物件取得的座標是原本 3D 物件建構時的座標系, 而非經過 Transform 轉換後的座標,

所以在轉換上面的下一番工夫, (呵呵~也是簡單幾個指令啦), 如此才能夠正確追蹤到滑鼠由標的正確位置

Categories: 軟體技術 Tags: