/** * 点到线的映射坐标 * @param {{x: Number, y: Number}} p 点 * @param {{x: Number, y: Number}} a 线段起始点 * @param {{x: Number, y: Number}} b 线段终止点 * @param {{x: Number, y: Number}} 线上的点 */ functiongetFocusPoint(p, a, b) { let point = {}; // 如果a.x === b.x 说明是条竖着的线 if (a.x - b.x === 0) { p.x = a.x; p.y = p.y; } else { let k = (a.y - b.y) / (a.x - b.x); let l = a.y - k * a.x; let m = p.x + k * p.y;
point.x = (m - k * l) / (k * k + 1); point.y = k * point.x + l; }
return point; }
/** * 计算点到线段的距离 * @param {{x: Number, y: Number}} p 点 * @param {{x: Number, y: Number}} a 线段起始点 * @param {{x: Number, y: Number}} b 线段终止点 * @return {Number} 距离 */ functionpointToSegmentDist(p, a, b) { let AB = [b.x - a.x, b.y - a.y] let AP = [p.x - a.x, p.y - a.y] let AB_AP = AB.x * AP.x + AB.y * AP.y let distAB2 = AB.x * AB.x + AB.y * AB.y let D = [a.x, a.y] if (distAB2 != 0) { let t = AB_AP / distAB2 if (t > 1) { D = [b.x, b.y] } elseif (t > 0) { D = [a.x + AB.x * t, a.y + AB.y * t] } else { D = [a.x, a.y] } } let AD = [p.x - a.x, p.y - a.y] returnMath.sqrt(AD.x * AD.x + AD.y * AD.y) }
/** * 判断点是否在多边形内部,一般用射线法 * @param {{x: Number, y: Number}} p 点 * @param {Array} polygon 多边形坐标 * @return {Number} 1: 在内部,0: 在外部 */ functionpointInPolygon(p, polygon) { // 统计p点右边交点的个数 var count = 0 for (var i = 0; i < ring.length - 1; i++) { var a = polygon[i] var b = polygon[i + 1] if ((a.y > p.y !== b.y > p.y) && (p.x < (b.x - a.x) * (p.y - a.y) / (b.y - a.y) + a.x)) count++; } return count % 2 }
/** * 判断点到多边形的最近距离 * @param {{x: Number, y: Number}} p 点 * @param {Array} polygon 多边形坐标 * @return {Number} 最短距离;点在多边形内部,距离为正;在多边形外部,距离为负;在边上,距离为零 */ functionpointToPolygonDist(p, polygon) { // 统计p点右边交点的个数 var count = 0 var minDist = Infinity for (var i = 0; i < ring.length - 1; i++) { var a = polygon[i] var b = polygon[i + 1] if ((a.y > p.y !== b.y > p.y) && (p.x < (b.x - a.x) * (p.y - a.y) / (b.y - a.y) + a.x)) count++; minDist = Math.min(minDist, pointToSegmentDist(p, a, b)) } if (count % 2 === 0) minDist = -minDist return minDist }
/** * 二维坐标围绕某个点旋转特定角度 * @param {Array} pointList 二维坐标集合 * @param {Number} theta 弧度 * @param {Object} point 旋转点 * @return {Array} 结果集合 */ functionrotationByPoint(pointList, theta, point) { let {x, y} = point; let sinTheta = Math.sin(theta); let cosTheta = Math.cos(theta);
let m00 = cosTheta; let m01 = -sinTheta; let m02 = x - x * cosTheta + y * sinTheta; let m10 = sinTheta; let m11 = cosTheta; let m12 = y - x * sinTheta - y * cosTheta;
return pointList.map(src => { let dest = {}; let xp = m00 * src.x + m01 * src.y + m02; let yp = m10 * src.x + m11 * src.y + m12; dest.x = xp; dest.y = yp; return dest; }); }
let a_coor = new jsts.geom.Coordinate(0, 0); let b_coor = new jsts.geom.Coordinate(1, 0); let c_coor = new jsts.geom.Coordinate(1, 1); let d_coor = new jsts.geom.Coordinate(0, 1);
let factory = new jsts.geom.GeometryFactory();
let ring = factory.createLinearRing([a_coor, b_coor, c_coor, d_coor, a_coor]); let line = factory.createLineString([new jsts.geom.Coordinate(0.5, 0), new jsts.geom.Coordinate(1, 0)]); let polygon = factory.createPolygon([a_coor, b_coor, c_coor, d_coor, a_coor]);
let x = 0.5 let y = 0 let mouse_coor = new jsts.geom.Coordinate(x, y); let mouse_point = factory.createPoint(mouse_coor);
let distance = new jsts.operation.distance.DistanceOp(mouse_point, ring);