http://www.csie.ntnu.edu.tw/~u91029/PointLinePlane.html
內積後取絕對值,求得的是投影量,再除以投影標的的單位向量,則得到投影長度。
外積後取絕對值,求得的是平行四邊形的面積量,再除以底的單位向量,則得到高。
- struct Point {double x, y;}; // 點的資料結構
- typedef Point Vector; // 向量的資料結構,和點一樣
- // 向量的長度
- double length(Vector& v)
- {
- return sqrt(v1.x * v1.x + v2.y * v2.y);
- // return sqrt(dot(v, v));
- }
- void print_d1_and_d2()
- {
- Point p, p1, p2;
- Vector v1 = p1 - p, v2 = p2 - p;
- cout << "d1:" << fabs(dot(v1, v2)) / length(v1);
- cout << "d2:" << fabs(cross(v1, v2)) / length(v1);
- }
內積、外積跟角度的關係
- void print_θ()
- {
- Point p, p1, p2;
- Vector v1 = p1 - p, v2 = p2 - p;
- double l1 = length(v1), l2 = length(v2);
- cout << "cos(θ):" << dot(v1, v2) / l1 / l2;
- cout << "sin(θ):" << cross(v1, v2) / l1 / l2;
- cout << "θ:" << acos(dot(v1, v2) / l1 / l2); // [0, π]
- cout << "θ:" << asin(cross(v1, v2) / l1 / l2); // [-π/2, π/2]
- }
注意到 acos 與 asin 的回傳值,回傳的結果是弳度量( radian )而非度度量( grade ),而且回傳值的範圍也不同。一般都以內積與 acos 求得介於 0˚ 到 180˚ 之間的夾角大小。
內積與向量夾角
利用內積的性質,可以粗略判斷夾角大小:內積大於 0 時,兩向量夾角小於 90˚ ;等於 0 時,夾角等於 90˚ ;小於零時,夾角大於 90˚ 且小於 180˚ 。
- // 向量oa與向量ob進行內積。可以判斷∠aob之大小。
- double dot(Point& o, Point& a, Point& b)
- {
- return (a.x-o.x) * (b.x-o.x) + (a.y-o.y) * (b.y-o.y);
- }
外積與向量旋轉
外積大於 0 時,兩向量前後順序為逆時針順序(在 180˚ 之內);等於 0 時,兩向量平行,也就是指夾角等於 0˚ 或 180˚ ;小於 0 時,兩向量前後順序為順時針順序(在 180˚ 之內)。
- // 向量oa與向量ob進行外積,可以判斷oa到ob旋轉的方向。
- double cross(Point& o, Point& a, Point& b)
- {
- return (a.x-o.x) * (b.y-o.y) - (a.y-o.y) * (b.x-o.x);
- }
舉例來說,要判斷多邊形凹凸,就沿著多邊形外圍繞一圈,看看每一條邊是不是折向同方向即可。