---
# System prepended metadata

title: 內外積在程式中的應用

---

# 內外積在程式中的應用
先複習
* $\vec{AB}=(x2−x1	,y2	​−y1​)$
* 內積: $\vec{a}\cdot\vec{b} = a_xb_x+a_yb_y$
* 外積: $\vec{a}\times\vec{b} = a_xb_y-a_yb_x$

:::warning
需要至少三個點才能形成兩個向量
:::
## 內積（Dot Product)
可以用來求角度或判斷夾角是銳角、直角或鈍角
| 判斷                          | 結果 |
| --------------------------- | -- |
| ( $\vec{a}\cdot\vec{b}$ > 0 ) | 銳角 |
| ( $\vec{a}\cdot\vec{b}$ = 0 ) | 直角 |
| ( $\vec{a}\cdot\vec{b}$ < 0 ) | 鈍角 |

由角度的關係可以知道兩向量的方向關係:
* **夾角為銳角**( $0^{\circ }\le\theta <90^{\circ }$)：內積為正值，表示兩個向量方向大致`相同`。
* **夾角為鈍角**( $90^{\circ }\le\theta <180^{\circ }$)：內積為正值，表示兩個向量方向大致`相反`。
* **夾角為直角** ($\theta =90^{\circ }$)：內積為零，表示兩個向量互相`垂直`。

## 外積
在幾何中(3D)，向量的定義為`公垂向量`，他會垂直 $\vec{a}$ 與 $\vec{b}$ ，但在平面中，沒有地方儲存Z軸，所以會運算結果會是一個正負數，用來代表左右轉還是迴轉。
> a = (1, 0)   // 指向 x 軸正方向
b = (0, 1)   // 指向 y 軸正方向
外積：
$a×b=(1)(1)−(0)(0)=+1$
代表「z 軸正方向」，也就是「逆時針」旋轉 -> 左轉。

所以正負號可判斷旋轉方向：

* $> 0$ → 左轉
* $< 0$ → 右轉
* $= 0$ → 共線(迴轉或原地不動)

:::warning
要注意外積=0的時候可能是原地不動，迴轉的條件是兩方向相反(透過內積求得方向)
:::

| 類型    | 用法        | 判斷依據        |
| ----- | --------- | ----------- |
| 判斷轉向  | 外積        | 正負號         |
| 判斷夾角  | 內積        | 正負號         |
| 計算面積  | 外積絕對值 / 2 | 幾何面積        |
| 多邊形方向 | 外積和的符號    | 正→逆時針、負→順時針 |
| 判斷正交  | 內積 = 0    | 垂直          |

# 實作
競賽中會透過Struct這個資料結構來快速存取x,y值。
```cpp=
struct Point {
    double x, y;
};

int main() {
    Point a = {3, 4};
    Point b = {1, 2};
    cout << a.x+b.x;//4
}
```
當然也可以透過以下寫法:
更快速的存取其他運算。
```cpp=
struct Point {
    double x, y;

    // 向量加法
    Point operator+(const Point &other) const {
        return {x + other.x, y + other.y};
    }

    // 向量減法
    Point operator-(const Point &other) const {
        return {x - other.x, y - other.y};
    }

    // 內積
    double dot(const Point &other) const {
        return x * other.x + y * other.y;
    }

    // 外積
    double cross(const Point &other) const {
        return x * other.y - y * other.x;
    }
};

```
```cpp=
Point a = {3, 4}, b = {1, 2};
cout << a.dot(b) << endl;    // 內積
cout << a.cross(b) << endl;  // 外積
```

## 實際演練
[2023/06 APCS 實作題](/Y5GdYfwnQ4Kbw3H8bJTkaw) - 第一題: 路徑偵測