主要用途:计算控制器等比缩放时,鼠标在对角控制器投射位置
如下图,拖动(x2,y2)到m1,m2时,投影位置为(a,b):
相关算法:
const vx1 = x2-x1
const vy1 = y2-y1
const vx2 = m1-x1
const vy2 = m2-y1
const v = MathUtil.getVec2ShadowVector(vx2, vy2, vx1, vy1);
const a = v.x+x1
const b = v.y+y1
参考帮助类:
class MathUtil {
/**
* 计算向量vec1在vec2的分量
* @param {Number} vec1
* @param {Number} vec2
*/
static getVec2Component(vec1X: number, vec1Y: number, vec2X: number, vec2Y: number) {
const cross = this.vectorCross(vec1X, vec1Y, vec2X, vec2Y)
const x = cross < 0 ? -vec2Y : vec2Y
const y = cross < 0 ? vec2X : -vec2X
const shadow = this.getVec2ShadowVector(vec1X, vec1Y, x, y)
return shadow
}
/**
* 计算向量vec1在vec2的投影
* @param {Number} vec1X
* @param {Number} vec1Y
* @param {Number} vec2X
* @param {Number} vec2Y
/
static getVec2ShadowVector(vec1X: number, vec1Y: number, vec2X: number, vec2Y: number) {
const dot = this.dotCross(vec1X, vec1Y, vec2X, vec2Y)
const length = this.getVecLength(vec2X, vec2Y)
const dl = length == 0 ? 0 : dot / length
const normalx = vec2X / length
const normaly = vec2Y / length
return { x: dl normalx, y: dl * normaly }
}
/**
* 计算投影长度
* @param {Number} vec1X
* @param {Number} vec1Y
* @param {Number} vec2X
* @param {Number} vec2Y
* @returns
/
static getVec2ShadowLength(vec1X: number, vec1Y: number, vec2X: number, vec2Y: number) {
const dot = this.dotCross(vec1X, vec1Y, vec2X, vec2Y)
const length = this.getVecLength(vec2X, vec2Y)
return length == 0 ? 0 : dot / length
}
static vectorCross(vec1X: number, vec1Y: number, vec2X: number, vec2Y: number) {
return vec1X vec2Y - vec1Y * vec2X
}
static dotCross(vec1X: number, vec1Y: number, vec2X: number, vec2Y: number) {
return vec1X * vec2X + vec1Y * vec2Y
}
static getVecLength(x: number, y: number) {
return Math.sqrt(x * x + y * y)
}
static getRateValue(value: number) {
let result = value
if (value <= 5) {
result = 0.1 + (value / 5) * 0.9
} else {
result = 1 + ((value - 5) / 5) * 9
}
result = parseFloat(String(Math.round(result * 10) / 10))
return result
}
}
export default MathUtil