OK,這裏去...
你點A,B和C,其中的每一個具有座標x,y和z。正如馬蒂亞斯所說,你需要法線的長度,這樣就可以計算出你的點與法線原點之間的向量與法線本身所成的角度。它可以幫助你認識到你的形象對我們的計算而言是誤導性的;法線(藍線)應該從三角形的一個頂點發出。要將你的點轉化爲矢量,它必須到某個地方,並且你只知道頂點的點(當你可以插入三角形內的任何點時,頂點着色的整個點不必)。
無論如何,第一步是把你的Point3Ds成Vector3Ds。簡單地通過獲取每個起點和終點的座標之間的差異來實現這一點。使用一個點作爲兩個向量的起點,其他兩個點作爲每個點的目的地。因此,如果A是您的原點,則從B中減去A,然後從C中減去A.現在您有一個向量,它描述X,Y和Z軸從A點到B點的運動幅度,同樣從A到C.值得注意的是,一個理論向量沒有自己的起點;要到達B點,您必須從A開始並應用該向量。
的System.Windows.Media.Media3D命名空間有可以使用的Vector3D結構,並輕而易舉地不夠,三維點在同一個命名空間中有一個返回的Vector3D減法()函數:
Vector3D vectorAB = pointB.Subtract(pointA);
Vector3D vectorAC = pointC.Subtract(pointA);
現在,法線是兩個向量的叉積。使用下面的公式:
V1 X V2 = [Y1 * Z2 - Y2 * Z1,Z1 * X2 - Z2 * X1,X1 * Y2 - X2 * Y1]
這是基於矩陣數學你不併不一定要知道實施它。矩陣中的三項是法向量的X,Y和Z。幸運的是,如果你使用的Media3D命名空間,則將對Vector3D結構具有雙重交叉()方法會爲你做到這一點:
Vector3D vectorNormal = Vector3D.CrossProduct(vectorAB, vectorAC);
現在,你需要第三個向量,LightPoint和A之間:
Vector3D vectorLight = PointA.Subtract(LightPoint);
這是光線從你的光源到達PointA的方向。
現在,找到它們之間的角度,你計算這兩個點積和這兩個長度:
| V | =開方(X^2 + Y^2 + Z^2)
V1 * V2 = X1 * X2 + Y1 * Y2 + Z1 * Z2
或者,如果你使用Media3D,的Vector3D有長度屬性和DotProduct靜態方法:
double lengthLight = vectorLight.Length;
double lengthNormal = vectorNormal.Length;
double dotProduct = Vector3D.DotProduct(vectorNormal, vectorLight);
最後,式Matias的提及:
V1 * V2 = | V1 || V2 | COS(THETA)
重新排列而代變量名:
double theta = arccos(dotProduct/(lengthNormal*lengthLight))
或者,如果你足夠聰明才能使用Media3D對象,忘記所有的長度和積東西:
double theta = Vector3D.AngleBetween(vectorNormal, vectorLight);
西塔現在在度的角度。如果你需要這種方式,乘以數量2(pi)/ 360乘以得到弧度。
故事的寓意是,使用框架給你的東西,除非你有充分的理由不這樣做;使用Media3D命名空間,所有的向量代數消失,你可以找到在5易於讀取線[我編輯的這一點,我將使用的代碼 - 伊恩]答案:
Vector3D vectorAB = Point3D.Subtract(pointB, pointA);
Vector3D vectorAC = Point3D.Subtract(pointC, pointA);
Vector3D vectorNormal = Vector3D.CrossProduct(vectorAB, vectorAC);
Vector3D vectorLight = Point3D.Subtract(pointA, LightPoint);
double lengthLight = light.Length;
double lengthNormal = norm.Length;
double dotProduct = Vector3D.DotProduct(norm, light);
double theta = Math.Acos(dotProduct/(lengthNormal * lengthLight));
// Convert to intensity between 0..255 range for 'Color.FromArgb(...
//int intensity = (120 + (Math.Cos(theta) * 90));
+1謝謝你的一個很好的答案! System.Windows.Media.Media3D是框架4 ...看起來像我升級:) – 2010-09-02 08:38:41
它也在3.5。您可能必須將應用程序設置爲WPF應用程序,我不確定。 – KeithS 2010-09-02 14:50:11