123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756 |
- import type { Cartesian3 } from "cesium";
- import type { AllPlotI } from "../../interface";
- import type { PointArr } from "../../interface";
- import { P, lonLatToCartesian } from "../../tools";
- const doubleArrowParams = {
- headHeightFactor: 0.25,
- headWidthFactor: 0.3,
- neckHeightFactor: 0.85,
- neckWidthFactor: 0.15,
- };
- // * 细直箭头与突击方向type
- type FineOrAssault = {
- tailWidthFactor: number;
- neckWidthFactor: number;
- headWidthFactor: number;
- headAngle: number;
- neckAngle: number;
- };
- const fineArrowParams: FineOrAssault = {
- tailWidthFactor: 0.15,
- neckWidthFactor: 0.2,
- headWidthFactor: 0.25,
- headAngle: Math.PI / 8.5,
- neckAngle: Math.PI / 13,
- };
- const assaultDirectionParams: FineOrAssault = {
- tailWidthFactor: 0.2,
- neckWidthFactor: 0.25,
- headWidthFactor: 0.3,
- headAngle: Math.PI / 4,
- neckAngle: Math.PI * 0.17741,
- };
- const attackArrowParams = {
- headHeightFactor: 0.18,
- headWidthFactor: 0.3,
- neckHeightFactor: 0.85,
- neckWidthFactor: 0.15,
- headTailFactor: 0.8,
- tailWidthFactor: 0.1,
- swallowTailFactor: 1,
- };
- const squadCombatParams = {
- headHeightFactor: 0.18,
- headWidthFactor: 0.3,
- neckHeightFactor: 0.85,
- neckWidthFactor: 0.15,
- tailWidthFactor: 0.1,
- swallowTailFactor: 1,
- };
- export const arrowPlot: AllPlotI = {
- version: "1.0.0",
- createTime: "2023-3-3",
- updateTime: "2023-3-3",
- author: "c-lei-en",
- algorithm: {
- // * 计算对称点
- getTempPoint4: (
- pnt1: PointArr,
- pnt2: PointArr,
- point: PointArr
- ): PointArr => {
- const midPnt = P.PlotUtils.mid(pnt1, pnt2);
- const len = P.PlotUtils.distance(midPnt, point);
- const angle = P.PlotUtils.getAngleOfThreePoints(pnt1, midPnt, point);
- let symPnt, distance1, distance2, mid;
- if (angle < P.Constants.HALF_PI) {
- distance1 = len * Math.sin(angle);
- distance2 = len * Math.cos(angle);
- mid = P.PlotUtils.getThirdPoint(
- pnt1,
- midPnt,
- P.Constants.HALF_PI,
- distance1,
- false
- );
- symPnt = P.PlotUtils.getThirdPoint(
- midPnt,
- mid,
- P.Constants.HALF_PI,
- distance2,
- true
- );
- } else if (angle >= P.Constants.HALF_PI && angle < Math.PI) {
- distance1 = len * Math.sin(Math.PI - angle);
- distance2 = len * Math.cos(Math.PI - angle);
- mid = P.PlotUtils.getThirdPoint(
- pnt1,
- midPnt,
- P.Constants.HALF_PI,
- distance1,
- false
- );
- symPnt = P.PlotUtils.getThirdPoint(
- midPnt,
- mid,
- P.Constants.HALF_PI,
- distance2,
- false
- );
- } else if (angle >= Math.PI && angle < Math.PI * 1.5) {
- distance1 = len * Math.sin(angle - Math.PI);
- distance2 = len * Math.cos(angle - Math.PI);
- mid = P.PlotUtils.getThirdPoint(
- pnt1,
- midPnt,
- P.Constants.HALF_PI,
- distance1,
- true
- );
- symPnt = P.PlotUtils.getThirdPoint(
- midPnt,
- mid,
- P.Constants.HALF_PI,
- distance2,
- true
- );
- } else {
- distance1 = len * Math.sin(Math.PI * 2 - angle);
- distance2 = len * Math.cos(Math.PI * 2 - angle);
- mid = P.PlotUtils.getThirdPoint(
- pnt1,
- midPnt,
- P.Constants.HALF_PI,
- distance1,
- true
- );
- symPnt = P.PlotUtils.getThirdPoint(
- midPnt,
- mid,
- P.Constants.HALF_PI,
- distance2,
- false
- );
- }
- return symPnt;
- },
- // * 获取箭头坐标
- getArrowHeadPoints: (points: PointArr): PointArr => {
- const len = P.PlotUtils.getBaseLength(points);
- const headHeight = len * doubleArrowParams.headHeightFactor;
- const headPnt = points[points.length - 1];
- const headWidth = headHeight * doubleArrowParams.headWidthFactor;
- const neckWidth = headHeight * doubleArrowParams.neckWidthFactor;
- const neckHeight = headHeight * doubleArrowParams.neckHeightFactor;
- const headEndPnt = P.PlotUtils.getThirdPoint(
- points[points.length - 2],
- headPnt,
- 0,
- headHeight,
- true
- );
- const neckEndPnt = P.PlotUtils.getThirdPoint(
- points[points.length - 2],
- headPnt,
- 0,
- neckHeight,
- true
- );
- const headLeft = P.PlotUtils.getThirdPoint(
- headPnt,
- headEndPnt,
- P.Constants.HALF_PI,
- headWidth,
- false
- );
- const headRight = P.PlotUtils.getThirdPoint(
- headPnt,
- headEndPnt,
- P.Constants.HALF_PI,
- headWidth,
- true
- );
- const neckLeft = P.PlotUtils.getThirdPoint(
- headPnt,
- neckEndPnt,
- P.Constants.HALF_PI,
- neckWidth,
- false
- );
- const neckRight = P.PlotUtils.getThirdPoint(
- headPnt,
- neckEndPnt,
- P.Constants.HALF_PI,
- neckWidth,
- true
- );
- return [neckLeft, headLeft, headPnt, headRight, neckRight];
- },
- // * 获取钳击箭身坐标
- getArrowBodyPoints: (
- points: PointArr,
- neckLeft: PointArr,
- neckRight: PointArr,
- tailWidthFactor: number
- ): PointArr => {
- const allLen = P.PlotUtils.wholeDistance(points);
- const len = P.PlotUtils.getBaseLength(points);
- const tailWidth = len * tailWidthFactor;
- const neckWidth = P.PlotUtils.distance(neckLeft, neckRight);
- const widthDif = (tailWidth - neckWidth) / 2;
- let tempLen = 0;
- const leftBodyPnts = [],
- rightBodyPnts = [];
- for (let i = 1; i < points.length - 1; i++) {
- const angle =
- P.PlotUtils.getAngleOfThreePoints(
- points[i - 1],
- points[i],
- points[i + 1]
- ) / 2;
- tempLen += P.PlotUtils.distance(points[i - 1], points[i]);
- const w =
- (tailWidth / 2 - (tempLen / allLen) * widthDif) / Math.sin(angle);
- const left = P.PlotUtils.getThirdPoint(
- points[i - 1],
- points[i],
- Math.PI - angle,
- w,
- true
- );
- const right = P.PlotUtils.getThirdPoint(
- points[i - 1],
- points[i],
- angle,
- w,
- false
- );
- leftBodyPnts.push(left);
- rightBodyPnts.push(right);
- }
- return leftBodyPnts.concat(rightBodyPnts);
- },
- // * 获取箭头点
- getArrowPoints: (
- pnt1: PointArr,
- pnt2: PointArr,
- pnt3: PointArr,
- clockWise: number
- ): PointArr => {
- const midPnt = P.PlotUtils.mid(pnt1, pnt2);
- const len = P.PlotUtils.distance(midPnt, pnt3);
- let midPnt1 = P.PlotUtils.getThirdPoint(pnt3, midPnt, 0, len * 0.3, true);
- let midPnt2 = P.PlotUtils.getThirdPoint(pnt3, midPnt, 0, len * 0.5, true);
- midPnt1 = P.PlotUtils.getThirdPoint(
- midPnt,
- midPnt1,
- P.Constants.HALF_PI,
- len / 5,
- clockWise
- );
- midPnt2 = P.PlotUtils.getThirdPoint(
- midPnt,
- midPnt2,
- P.Constants.HALF_PI,
- len / 4,
- clockWise
- );
- const points = [midPnt, midPnt1, midPnt2, pnt3];
- // 计算箭头部分
- const arrowPnts = arrowPlot.algorithm.getArrowHeadPoints(
- points,
- doubleArrowParams.headHeightFactor,
- doubleArrowParams.headWidthFactor,
- doubleArrowParams.neckHeightFactor,
- doubleArrowParams.neckWidthFactor
- );
- const neckLeftPoint = arrowPnts[0];
- const neckRightPoint = arrowPnts[4];
- // 计算箭身部分
- const tailWidthFactor =
- P.PlotUtils.distance(pnt1, pnt2) /
- P.PlotUtils.getBaseLength(points) /
- 2;
- const bodyPnts = arrowPlot.algorithm.getArrowBodyPoints(
- points,
- neckLeftPoint,
- neckRightPoint,
- tailWidthFactor
- );
- const n = bodyPnts.length;
- let lPoints = bodyPnts.slice(0, n / 2);
- let rPoints = bodyPnts.slice(n / 2, n);
- lPoints.push(neckLeftPoint);
- rPoints.push(neckRightPoint);
- lPoints = lPoints.reverse();
- lPoints.push(pnt2);
- rPoints = rPoints.reverse();
- rPoints.push(pnt1);
- return lPoints.reverse().concat(arrowPnts, rPoints);
- },
- // * 获取钳击箭头坐标
- getDoubleArrow: (pnts: PointArr[]): Cartesian3[] => {
- const pnt1 = pnts[0];
- const pnt2 = pnts[1];
- const pnt3 = pnts[2];
- let tempPoint4, connPoint;
- if (pnts.length == 3)
- tempPoint4 = arrowPlot.algorithm.getTempPoint4(pnt1, pnt2, pnt3);
- else tempPoint4 = pnts[3];
- if (pnts.length == 3 || pnts.length == 4)
- connPoint = P.PlotUtils.mid(pnt1, pnt2);
- else connPoint = pnts[4];
- let leftArrowPnts, rightArrowPnts;
- if (P.PlotUtils.isClockWise(pnt1, pnt2, pnt3)) {
- leftArrowPnts = arrowPlot.algorithm.getArrowPoints(
- pnt1,
- connPoint,
- tempPoint4,
- false
- );
- rightArrowPnts = arrowPlot.algorithm.getArrowPoints(
- connPoint,
- pnt2,
- pnt3,
- true
- );
- } else {
- leftArrowPnts = arrowPlot.algorithm.getArrowPoints(
- pnt2,
- connPoint,
- pnt3,
- false
- );
- rightArrowPnts = arrowPlot.algorithm.getArrowPoints(
- connPoint,
- pnt1,
- tempPoint4,
- true
- );
- }
- const m = leftArrowPnts.length;
- const t = (m - 5) / 2;
- const llBodyPnts = leftArrowPnts.slice(0, t);
- const lArrowPnts = leftArrowPnts.slice(t, t + 5);
- let lrBodyPnts = leftArrowPnts.slice(t + 5, m);
- let rlBodyPnts = rightArrowPnts.slice(0, t);
- const rArrowPnts = rightArrowPnts.slice(t, t + 5);
- const rrBodyPnts = rightArrowPnts.slice(t + 5, m);
- rlBodyPnts = P.PlotUtils.getBezierPoints(rlBodyPnts);
- const bodyPnts = P.PlotUtils.getBezierPoints(
- rrBodyPnts.concat(llBodyPnts.slice(1))
- );
- lrBodyPnts = P.PlotUtils.getBezierPoints(lrBodyPnts);
- const positions = rlBodyPnts.concat(
- rArrowPnts,
- bodyPnts,
- lArrowPnts,
- lrBodyPnts
- );
- const res = [] as Cartesian3[];
- positions.forEach((pos: PointArr) => {
- res.push(lonLatToCartesian(pos));
- });
- return res;
- },
- // * 获取细直箭头或者突击方向箭头坐标
- getFineOrAssault: (pnts: PointArr, param: FineOrAssault): Cartesian3[] => {
- const pnt1 = pnts[0];
- const pnt2 = pnts[1];
- const len = P.PlotUtils.getBaseLength(pnts);
- const tailWidth = len * param.tailWidthFactor;
- const neckWidth = len * param.neckWidthFactor;
- const headWidth = len * param.headWidthFactor;
- const tailLeft = P.PlotUtils.getThirdPoint(
- pnt2,
- pnt1,
- P.Constants.HALF_PI,
- tailWidth,
- true
- );
- const tailRight = P.PlotUtils.getThirdPoint(
- pnt2,
- pnt1,
- P.Constants.HALF_PI,
- tailWidth,
- false
- );
- const headLeft = P.PlotUtils.getThirdPoint(
- pnt1,
- pnt2,
- param.headAngle,
- headWidth,
- false
- );
- const headRight = P.PlotUtils.getThirdPoint(
- pnt1,
- pnt2,
- param.headAngle,
- headWidth,
- true
- );
- const neckLeft = P.PlotUtils.getThirdPoint(
- pnt1,
- pnt2,
- param.neckAngle,
- neckWidth,
- false
- );
- const neckRight = P.PlotUtils.getThirdPoint(
- pnt1,
- pnt2,
- param.neckAngle,
- neckWidth,
- true
- );
- return [
- lonLatToCartesian(tailLeft),
- lonLatToCartesian(neckLeft),
- lonLatToCartesian(headLeft),
- lonLatToCartesian(pnt2),
- lonLatToCartesian(headRight),
- lonLatToCartesian(neckRight),
- lonLatToCartesian(tailRight),
- ];
- },
- // * 获取细直箭头坐标
- getFineArrow: (pnts: PointArr): Cartesian3[] => {
- return arrowPlot.algorithm.getFineOrAssault(pnts, fineArrowParams);
- },
- // * 获取突击方向坐标
- getAssaultDirection: (pnts: PointArr): Cartesian3[] => {
- return arrowPlot.algorithm.getFineOrAssault(pnts, assaultDirectionParams);
- },
- // * 获取进攻方向箭头坐标
- getAttackArrowHeadPoints: (
- points: PointArr,
- tailLeft: PointArr,
- tailRight: PointArr
- ): PointArr => {
- let len = P.PlotUtils.getBaseLength(points);
- let headHeight = len * attackArrowParams.headHeightFactor;
- const headPnt = points[points.length - 1];
- len = P.PlotUtils.distance(headPnt, points[points.length - 2]);
- const tailWidth = P.PlotUtils.distance(tailLeft, tailRight);
- if (headHeight > tailWidth * attackArrowParams.headTailFactor) {
- headHeight = tailWidth * attackArrowParams.headTailFactor;
- }
- const headWidth = headHeight * attackArrowParams.headWidthFactor;
- const neckWidth = headHeight * attackArrowParams.neckWidthFactor;
- headHeight = headHeight > len ? len : headHeight;
- const neckHeight = headHeight * attackArrowParams.neckHeightFactor;
- const headEndPnt = P.PlotUtils.getThirdPoint(
- points[points.length - 2],
- headPnt,
- 0,
- headHeight,
- true
- );
- const neckEndPnt = P.PlotUtils.getThirdPoint(
- points[points.length - 2],
- headPnt,
- 0,
- neckHeight,
- true
- );
- const headLeft = P.PlotUtils.getThirdPoint(
- headPnt,
- headEndPnt,
- P.Constants.HALF_PI,
- headWidth,
- false
- );
- const headRight = P.PlotUtils.getThirdPoint(
- headPnt,
- headEndPnt,
- P.Constants.HALF_PI,
- headWidth,
- true
- );
- const neckLeft = P.PlotUtils.getThirdPoint(
- headPnt,
- neckEndPnt,
- P.Constants.HALF_PI,
- neckWidth,
- false
- );
- const neckRight = P.PlotUtils.getThirdPoint(
- headPnt,
- neckEndPnt,
- P.Constants.HALF_PI,
- neckWidth,
- true
- );
- return [neckLeft, headLeft, headPnt, headRight, neckRight];
- },
- // * 获取进攻方向箭身坐标
- getAttackArrowBodyPoints: (
- points: PointArr,
- neckLeft: PointArr,
- neckRight: PointArr,
- tailWidthFactor: number
- ): PointArr => {
- const allLen = P.PlotUtils.wholeDistance(points);
- const len = P.PlotUtils.getBaseLength(points);
- const tailWidth = len * tailWidthFactor;
- const neckWidth = P.PlotUtils.distance(neckLeft, neckRight);
- const widthDif = (tailWidth - neckWidth) / 2;
- let tempLen = 0;
- const leftBodyPnts = [],
- rightBodyPnts = [];
- for (let i = 1; i < points.length - 1; i++) {
- const angle =
- P.PlotUtils.getAngleOfThreePoints(
- points[i - 1],
- points[i],
- points[i + 1]
- ) / 2;
- tempLen += P.PlotUtils.distance(points[i - 1], points[i]);
- const w =
- (tailWidth / 2 - (tempLen / allLen) * widthDif) / Math.sin(angle);
- const left = P.PlotUtils.getThirdPoint(
- points[i - 1],
- points[i],
- Math.PI - angle,
- w,
- true
- );
- const right = P.PlotUtils.getThirdPoint(
- points[i - 1],
- points[i],
- angle,
- w,
- false
- );
- leftBodyPnts.push(left);
- rightBodyPnts.push(right);
- }
- return leftBodyPnts.concat(rightBodyPnts);
- },
- // * 获取进攻方向坐标
- getAttackArrow: (pnts: PointArr[]): Cartesian3[] => {
- // 计算箭尾
- let tailLeft = pnts[0];
- let tailRight = pnts[1];
- if (P.PlotUtils.isClockWise(pnts[0], pnts[1], pnts[2])) {
- tailLeft = pnts[1];
- tailRight = pnts[0];
- }
- const midTail = P.PlotUtils.mid(tailLeft, tailRight);
- const bonePnts = [midTail].concat(pnts.slice(2));
- // 计算箭头
- const headPnts = arrowPlot.algorithm.getAttackArrowHeadPoints(
- bonePnts,
- tailLeft,
- tailRight
- );
- const neckLeft = headPnts[0];
- const neckRight = headPnts[4];
- const tailWidthFactor =
- P.PlotUtils.distance(tailLeft, tailRight) /
- P.PlotUtils.getBaseLength(bonePnts);
- // 计算箭身
- const bodyPnts = arrowPlot.algorithm.getAttackArrowBodyPoints(
- bonePnts,
- neckLeft,
- neckRight,
- tailWidthFactor
- );
- // 整合
- const count = bodyPnts.length;
- let leftPnts = [tailLeft].concat(bodyPnts.slice(0, count / 2));
- leftPnts.push(neckLeft);
- let rightPnts = [tailRight].concat(bodyPnts.slice(count / 2, count));
- rightPnts.push(neckRight);
- leftPnts = P.PlotUtils.getQBSplinePoints(leftPnts);
- rightPnts = P.PlotUtils.getQBSplinePoints(rightPnts);
- const positions = leftPnts.concat(headPnts, rightPnts.reverse());
- const res = [] as Cartesian3[];
- positions.forEach((pos: PointArr) => {
- res.push(lonLatToCartesian(pos));
- });
- return res;
- },
- // * 获取进攻方向尾坐标
- getTailedAttackArrow: (pnts: PointArr[]): Cartesian3[] => {
- let tailLeft = pnts[0];
- let tailRight = pnts[1];
- if (P.PlotUtils.isClockWise(pnts[0], pnts[1], pnts[2])) {
- tailLeft = pnts[1];
- tailRight = pnts[0];
- }
- const midTail = P.PlotUtils.mid(tailLeft, tailRight);
- const bonePnts = [midTail].concat(pnts.slice(2));
- const headPnts = arrowPlot.algorithm.getAttackArrowHeadPoints(
- bonePnts,
- tailLeft,
- tailRight
- );
- const neckLeft = headPnts[0];
- const neckRight = headPnts[4];
- const tailWidth = P.PlotUtils.distance(tailLeft, tailRight);
- const allLen = P.PlotUtils.getBaseLength(bonePnts);
- const len =
- allLen *
- attackArrowParams.tailWidthFactor *
- attackArrowParams.swallowTailFactor;
- const swallowTailPnt = P.PlotUtils.getThirdPoint(
- bonePnts[1],
- bonePnts[0],
- 0,
- len,
- true
- );
- const factor = tailWidth / allLen;
- const bodyPnts = arrowPlot.algorithm.getAttackArrowBodyPoints(
- bonePnts,
- neckLeft,
- neckRight,
- factor
- );
- const count = bodyPnts.length;
- let leftPnts = [tailLeft].concat(bodyPnts.slice(0, count / 2));
- leftPnts.push(neckLeft);
- let rightPnts = [tailRight].concat(bodyPnts.slice(count / 2, count));
- rightPnts.push(neckRight);
- leftPnts = P.PlotUtils.getQBSplinePoints(leftPnts);
- rightPnts = P.PlotUtils.getQBSplinePoints(rightPnts);
- const positions = leftPnts.concat(headPnts, rightPnts.reverse(), [
- swallowTailPnt,
- leftPnts[0],
- ]);
- const res = [] as Cartesian3[];
- positions.forEach((pos: PointArr) => {
- res.push(lonLatToCartesian(pos));
- });
- return res;
- },
- // * 获取尾点
- getTailPoints: (points: PointArr): PointArr[] => {
- const allLen = P.PlotUtils.getBaseLength(points);
- const tailWidth = allLen * squadCombatParams.tailWidthFactor;
- const tailLeft = P.PlotUtils.getThirdPoint(
- points[1],
- points[0],
- P.Constants.HALF_PI,
- tailWidth,
- false
- );
- const tailRight = P.PlotUtils.getThirdPoint(
- points[1],
- points[0],
- P.Constants.HALF_PI,
- tailWidth,
- true
- );
- return [tailLeft, tailRight];
- },
- // * 获取分队战斗行动坐标
- getSquadCombat: (pnts: PointArr[]): Cartesian3[] => {
- const tailPnts = arrowPlot.algorithm.getTailPoints(pnts);
- const headPnts = arrowPlot.algorithm.getAttackArrowHeadPoints(
- pnts,
- tailPnts[0],
- tailPnts[1]
- );
- const neckLeft = headPnts[0];
- const neckRight = headPnts[4];
- const bodyPnts = arrowPlot.algorithm.getAttackArrowBodyPoints(
- pnts,
- neckLeft,
- neckRight,
- squadCombatParams.tailWidthFactor
- );
- const count = bodyPnts.length;
- let leftPnts = [tailPnts[0]].concat(bodyPnts.slice(0, count / 2));
- leftPnts.push(neckLeft);
- let rightPnts = [tailPnts[1]].concat(bodyPnts.slice(count / 2, count));
- rightPnts.push(neckRight);
- leftPnts = P.PlotUtils.getQBSplinePoints(leftPnts);
- rightPnts = P.PlotUtils.getQBSplinePoints(rightPnts);
- const positions = leftPnts.concat(headPnts, rightPnts.reverse());
- const res = [] as Cartesian3[];
- positions.forEach((pos: PointArr) => {
- res.push(lonLatToCartesian(pos));
- });
- return res;
- },
- // * 获取分队战斗行动尾尾点
- getTailedTailPoints: (points: PointArr): PointArr[] => {
- const allLen = P.PlotUtils.getBaseLength(points);
- const tailWidth = allLen * squadCombatParams.tailWidthFactor;
- const tailLeft = P.PlotUtils.getThirdPoint(
- points[1],
- points[0],
- P.Constants.HALF_PI,
- tailWidth,
- false
- );
- const tailRight = P.PlotUtils.getThirdPoint(
- points[1],
- points[0],
- P.Constants.HALF_PI,
- tailWidth,
- true
- );
- const len = tailWidth * squadCombatParams.swallowTailFactor;
- const swallowTailPnt = P.PlotUtils.getThirdPoint(
- points[1],
- points[0],
- 0,
- len,
- true
- );
- return [tailLeft, swallowTailPnt, tailRight];
- },
- // * 获取分队战斗行动尾坐标
- getTailedSquadCombat: (pnts: PointArr[]): Cartesian3[] => {
- const tailPnts = arrowPlot.algorithm.getTailedTailPoints(pnts);
- const headPnts = arrowPlot.algorithm.getAttackArrowHeadPoints(
- pnts,
- tailPnts[0],
- tailPnts[2]
- );
- const neckLeft = headPnts[0];
- const neckRight = headPnts[4];
- const bodyPnts = arrowPlot.algorithm.getAttackArrowBodyPoints(
- pnts,
- neckLeft,
- neckRight,
- squadCombatParams.tailWidthFactor
- );
- const count = bodyPnts.length;
- let leftPnts = [tailPnts[0]].concat(bodyPnts.slice(0, count / 2));
- leftPnts.push(neckLeft);
- let rightPnts = [tailPnts[2]].concat(bodyPnts.slice(count / 2, count));
- rightPnts.push(neckRight);
- leftPnts = P.PlotUtils.getQBSplinePoints(leftPnts);
- rightPnts = P.PlotUtils.getQBSplinePoints(rightPnts);
- const positions = leftPnts.concat(headPnts, rightPnts.reverse(), [
- tailPnts[1],
- leftPnts[0],
- ]);
- const res = [] as Cartesian3[];
- positions.forEach((pos: PointArr) => {
- res.push(lonLatToCartesian(pos));
- });
- return res;
- },
- },
- };
|