然后还有一些辅助,都是数学问题,可以网上搜,cc应该也有自带(不过庆幸手写了,使得从193版本用208重写时省了点事):
1.计算投影长度
/**
* 计算向量v1在另一个向量v2上的投影(长度)
*/
public static vectorShadow (v1:cc.Vec2, v2:cc.Vec2): number {
return (v1.x * v2.x + v1.y * v2.y) / Math.sqrt(Math.pow(v2.x, 2) + Math.pow(v2.y, 2));
}
2.计算向量之间夹角
/**
* 计算向量夹角的cos值,为-负数表示钝角,为正数表示锐角
*
*/
public static chekDirection(p1: cc.Vec2, p2: cc.Vec2, len1: number, b1: cc.Vec2, b2: cc.Vec2, len2: number):number {
if(VerticalUtil.checkEqual(p1, p2) || VerticalUtil.checkEqual(b1, b2)) {
return -1;
}
let v1 = {x: (p2.x - p1.x) , y: (p2.y - p1.y)};//线段p1->p2向量
let v2 = {x: (b2.x - b1.x), y: (b2.y - b1.y)};//线段b1->b2向量
//let v3 = {x: v1.x + v2.x, y:v1.y + v2.y};//v3 = v2 + v1
let cosval = (v1.x * v2.x + v1.y * v2.y) / (len1 * len2);
return cosval;
//0° 1 60° 0.5 75° 0.2588 90° 可算出为0
//100° -0.173 120°为-0.5 140°为0.766 150°为-0.866
//160°为-0.9397 165°为-0.9659 170°为-0.9848 172 -0.99 175为-0.9962 178为-0.9993 179为-0.99985
//大于等于90°当作同方向,否则当作反方向
}
public static chekDirection2(p1: cc.Vec2, p2: cc.Vec2, b1: cc.Vec2, b2: cc.Vec2):number {
return VerticalUtil.chekDirection(p1, p2, p1.sub(p2).mag(), b1, b2, b1.sub(b2).mag());
}
计算点离线段最近距离(线段,不是直线,注意这点)
/**
* 计算点离线段的最短距离的平方
* p1 p2 线段的两端端点
* p 点
/
public static dotLeveaveLineSQ (p1: cc.Vec2, p2: cc.Vec2, p: cc.Vec2):number {
let len = 0;
let cross = (p2.x - p1.x) * (p.x - p1.x) + (p2.y - p1.y) * (p.y - p1.y);
if (cross <= 0) {
len = (p.x - p1.x) * (p.x - p1.x) + (p.y - p1.y) * (p.y - p1.y);
} else {
let d = (p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y);
if (cross >= d) {
len = (p2.x - p.x) * (p2.x - p.x) + (p2.y - p.y) * (p2.y - p.y);
} else {
let px = p1.x + (p2.x - p1.x) * cross / d;
let py = p1.y + (p2.y - p1.y) * cross / d;
len = (p.x - px) * (p.x - px) + (p.y - py) * (p.y - py);
}
}
return len;
}
/*
* 计算点离线段的最短距离
* p1 p2 线段的两端端点
* p 点
*/
public static dotLeveaveLine (p1: cc.Vec2, p2: cc.Vec2, p: cc.Vec2):number {
//首先p的x和y要在p1 p2的范围之内
let len = VerticalUtil.dotLeveaveLineSQ(p1, p2, p);
return Math.sqrt(len);
}