math.js官方文档
math.js是一个广泛应用于JavaScript 和 Node.js的数学库,特点是灵活表达式解析器,支持符号计算,内置大量函数与常量,并提供集成解决方案来处理不同的数据类型,如数字,大数字,复数,分数,单位和矩阵。
安装方法:
npm install mathjs
math.js里自带了一个方法,可以计算线与线的交点(结果不是很准确),线与三维平面的交点
math.intersect(endPoint1Line1, endPoint2Line1, endPoint1Line2, endPoint2Line2)
math.intersect(endPoint1, endPoint2, planeCoefficients)
注:平面方程需要类似于 a1x + b1y + c1z = d
const math = require('mathjs')
math.intersect([0, 0], [10, 10], [10, 0], [0, 10]) // 二维线段 Returns [5, 5]
math.intersect([0, 0, 0], [10, 10, 0], [10, 0, 0], [0, 10, 0]) // 三维线段 Returns [5, 5, 0]
math.intersect([1, 0, 1], [4, -2, 2], [1, 1, 1, 6]) // 线与平面 Returns [7, -4, 3]
用nodejs代码自己实现:
const math = require('mathjs')
//主函数:判断两线段是否相交,并求出焦点
function find3dCrossPoint (point1, point2, point3, point4) {
// 空间直线方程 参数形式
const deltax_s1 = point2[0] - point1[0]
const deltay_s1 = point2[1] - point1[1]
const deltaz_s1 = point2[2] - point1[2]
const deltax_s2 = point4[0] - point3[0]
const deltay_s2 = point4[1] - point3[1]
const deltaz_s2 = point4[2] - point3[2]
// 解开方程组
const x0 = [deltax_s1, -deltax_s2]
const b0 = point3[0] - point1[0]
const x1 = [deltay_s1, -deltay_s2]
const b1 = point3[1] - point1[1]
const x2 = [deltaz_s1, -deltaz_s2]
const b2 = point3[2] - point1[2]
const tempDic = [
{ 'thex': [x0, x1], 'theb': [b0, b1], 'theIsCross': 2 },
{ 'thex': [x0, x2], 'theb': [b0, b2], 'theIsCross': 1 },
{ 'thex': [x1, x2], 'theb': [b1, b2], 'theIsCross': 0 }
]
// 系数矩阵
let x = tempDic[0]['thex']
// 常数项
let b = math.transpose(tempDic[0]['theb'])
let isExitX = false
let theIsCrossNum = 2
for (let i = 0; i < 3; i++) {
x = tempDic[i]['thex']
b = math.transpose(tempDic[i]['theb'])
theIsCrossNum = 2 - i
if (math.det(x) != 0) {
isExitX = true
break
}
}
if (!isExitX) {
return false
} else {
const theSolve = math.lusolve(x, b)
const t1 = theSolve[0]
const t2 = theSolve[1]
// 要求0<=t1,t2<=1,否则还是不相交
if (t1 > 0 && t2 < 1) {
const theIsCross = [
point1[2] + deltaz_s1 * t1 == point3[2] + deltaz_s2 * t2,
point1[1] + deltay_s1 * t1 == point3[1] + deltay_s2 * t2,
point1[0] + deltax_s1 * t1 == point3[0] + deltax_s2 * t2
]
const isCross = theIsCross[theIsCrossNum]
if (isCross) {
const crossPointX = point1[0] + deltax_s1 * t1
const crossPointY = point1[1] + deltay_s1 * t1
const crossPointZ = point1[2] + deltaz_s1 * t1
const crossPoint = math.flatten([crossPointX, crossPointY, crossPointZ])
// 交点在两条线段上
if (isPointOnLine(crossPoint, [point1, point2]) && isPointOnLine(crossPoint, [point3, point4])) {
return crossPoint
} else {
return false
}
}
} else {
return false
}
}
}
function isPointOnLine (point, line) {
//已知点在线上
const p1 = line[0]
const p2 = line[1]
const xmax = math.max(p1[0], p2[0])
const xmin = math.min(p1[0], p2[0])
const ymax = math.max(p1[1], p2[1])
const ymin = math.min(p1[1], p2[1])
const zmax = math.max(p1[2], p2[2])
const zmin = math.min(p1[2], p2[2])
if (point[0] <= xmax && point[0] >= xmin && point[1] <= ymax && point[1] >= ymin && point[2] <= zmax && point[2] >= zmin) {
return true
} else {
return false
}
}
测试:
const result = find3dCrossPoint([0, 0, 0], [1, 1, 1], [1, 0, 0], [0, 1, 1])
console.log(result) //交点为:[ 0.5, 0.5, 0.5 ]
math.js简单用法
python实现三维空间线段的交点