原理分析
可以將路徑每個(gè)連續(xù)的兩點(diǎn)向量叉乘相加,根據(jù)正負(fù)性判斷路徑順逆時(shí)針性
當(dāng)我們計(jì)算兩個(gè)向量的叉積時(shí),結(jié)果是一個(gè)新的向量,其方向垂直于這兩個(gè)向量所在的平面,并且其大小與這兩個(gè)向量構(gòu)成的平行四邊形的面積成正比。這個(gè)新向量的方向由右手定則確定:如果你將右手的四指放在兩個(gè)向量的方向上,讓拇指指向叉積的方向,那么你的手指彎曲的方向就是兩個(gè)向量的順時(shí)針旋轉(zhuǎn)方向。文章來源:http://www.zghlxwxcb.cn/news/detail-858733.html
當(dāng)我們應(yīng)用這個(gè)概念到路徑的情況時(shí),我們可以將相鄰的路徑點(diǎn)表示為向量,然后計(jì)算它們之間的叉積。這個(gè)叉積的 z 分量(如果我們將路徑投影到 xy 平面上)可以告訴我們這兩個(gè)向量之間的順時(shí)針或逆時(shí)針關(guān)系。
由于threejs很多地方對(duì)凹凸多邊形沒有限制,可以在輸入端限制凹三角或在計(jì)算中舍棄凹點(diǎn)文章來源地址http://www.zghlxwxcb.cn/news/detail-858733.html
代碼
import { Vector3 } from "three";
/**
* 判斷向量是否為順時(shí)針 返回值true逆時(shí)針 false 順時(shí)針
* @param {[Vector3]} path //vec3路徑
* @param {'x'|'y'|'z'} forword //基準(zhǔn)
* @returns
*/
export default function isClockwise(path, forword = 'z') {
let sum = 0;
const n = path.length;
for (let i = 0; i < n; i++) {
const current = path[i];
const next = path[(i + 1) % n]; // 取下一個(gè)點(diǎn),循環(huán)到第一個(gè)點(diǎn)
// 計(jì)算當(dāng)前點(diǎn)到下一個(gè)點(diǎn)的向量
const vector = next.clone().sub(current);
// 只考慮 xy 平面上的向量,忽略 z 分量
vector.z = 0;
// 叉積的 z 分量可以判斷順時(shí)針還是逆時(shí)針
if (forword == 'z')
sum += (current.x * next.y - next.x * current.y);
else if (forword == 'x')
sum += (current.z * next.y - next.z * current.y);
else if (forword == 'y')
sum += (current.x * next.z - next.x * current.z);
/**
*如果業(yè)務(wù)需要 可以在這里判斷sum大小變化確定 如果增或者減反向 則可判斷這里出現(xiàn)凹點(diǎn)
*/
}
// 如果 sum 大于 0,則路徑是逆時(shí)針的;如果 sum 小于 0,則路徑是順時(shí)針的
return sum > 0;
}
使用
使用isClick判斷路徑方向性,并轉(zhuǎn)為順時(shí)針
let reverse = isClockwise(vertices)
if (reverse) vertices.reverse()
到了這里,關(guān)于【JavaScript&&Threejs】判斷路徑在二維平面上投影的方向順逆時(shí)針的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!