Ae 表達式自動畫切線

做 Ae 時,蠻常遇到要做跟圓形相切的圖形,所以就寫了一個表達式去自動做圖形的連線。一般情況下,如果是做圓形在一個正方形裡面會比較容易一些,只需要把方形的 size 跟圓形的 size 綁在一起就可以了。

而比較麻煩的會是在圓外一點做圓形的相切線,具體圖形會類似下圖:

AE, 自動化切線, Insight
AE, 自動化切線, Insight

這種圖形通常會用在像「聚光燈」這類的東西上。一般來說,設計師在 Ai 都是直接畫出圓形跟三角的形狀大概去做對齊就好,視覺上其實看不出誤差。但是在動畫製作中,圓形跟黃色的端點位置可能會產生許多變化,如果每需要更改都要去手動改變三角形 path 的位置、設 key 會有點不實際,而且破綻會變得很明顯,過程中也一定會產生下圖這種沒有切齊的誤差。

AE, 自動化切線, Insight

製作上的邏輯是要想辦法利用「圓外一點求切線」的方式去找到圓形上的兩個切點座標,再利用那兩個座標位置去跟圓外的點做連線。

具體作法

1.首先要先用 Ae 的 shape 工具 畫出一個正圓形。

2.用 鋼筆工具 大概的畫出一個三角形。(隨便畫就好,只要確保他都是直線,不要讓他產生貝茲曲線的拉桿)

3.點開鋼筆工具畫出的 shape 找到 path 之後,利用內建的腳本「Create Nulls From Path」的「Points Follow Nulls」按鈕,找到三角形 shape 的三個點並且設 null。這時候你的三角形的 3 個點就會根據腳本幫你生成的 3 個 null 去做形變了。

4.把這 3 個 null 重新命名一下,我這邊的命名是 A、B、T。

📌
A:切點1
B:切點2
T:圓外的那一點

5.我通常會另外多設一個 null 當作圓形的控制點,並且給 null 加一個 slider control 去綁定圓形的 size,並且也把圓形的 position 跟 null 的 position 綁在一起。這樣以後如果要做尺寸跟大小的變化就只要選那個 null 就可以了,不用把 shape 裡面的一堆東西都打開。如下:

AE, 自動化切線, Insight
這時候你應該會有 4 個 null,分別代表圓心座標、切點1、切點2、圓外一點座標

6.你只需要把以下的表達式複製起來貼到 A、B 這兩個 null 的 position 上就可以了。


var oX = [圓心 x 座標] ;
var oY = [圓心 y 座標] ;
var r = [圓形shape的Size]/2;   // 半徑(Size是直徑大小所以記得一定要除以2)
var tX = [點 T 的 x 座標] ;
var tY = [點 T 的 y 座標] ;

// 計算向量 OT
var vecX = tX - oX;
var vecY = tY - oY;

d = Math.sqrt(vecX*vecX+vecY*vecY); // OT 距離
l = Math.sqrt(d*d-r*r); //QT 距離

cx = (oX-tX)/d; // X 座標單位向量
cy = (oY-tY)/d; // Y 座標單位向量

var angle = Math.asin(r/d); // ATO、BTO 的夾角

// 計算切點座標
var q1x = cx * Math.cos(-angle) - cy * Math.sin(-angle); // 旋轉後切點1的 X 座標單位向量
var q1y = cx * Math.sin(-angle) + cy * Math.cos(-angle); // 旋轉後切點1的 Y 座標單位向量
var q2x = cx * Math.cos(angle) - cy * Math.sin(angle); // 旋轉後切點2的 X 座標單位向量
var q2y = cx * Math.sin(angle) + cy * Math.cos(angle); // 旋轉後切點2的 Y 座標單位向量

var tp1X = q1x * l + tX;
var tp1Y = q1y * l + tY;
var tp2X = q2x * l + tX;
var tp2Y = q2y * l + tY;


// 输出结果,A、B 點個挑一組輸出
[tp1X, tp1Y] // A 點座標
[tp2X, tp2Y] // B 點座標

7.最後 A、B 兩點的 null 位置會依據表達式給出的計算方式,自己找到位置後根據圓形的半徑大小和 T 點的變化去找適合的位置。結果如下,接著就可以自由的調整圓形大小跟 T 點的位置!

AE, 自動化切線, Insight

Insight 其他文章點這裡!

Insight Collector 社群懶人包 → 點這裡!