/// <summary> /// 由点集计算平面法向量 /// </summary> /// <param name="pts">点集</param> /// <returns></returns> public static bool CalcNormalVector(sg_Vector3[] pts, out sg_Vector3 n) { n = null; int iCount = pts.Length; if (iCount < 3) { return(false); } sg_Vector3 pt1 = pts[0]; sg_Vector3 pt2 = null; for (int i = 1; i < iCount; i++) { pt2 = pts[i]; if (sg_math.isZero(pt2.DistTo(pt1))) { pt2 = null; } else { break; } } if (pt2 == null) { return(false); } sg_Vector3 v1 = pt2 - pt1; sg_Vector3 v2 = null; for (int i = 1; i < iCount; i++) { var pt3 = pts[i]; if (sg_math.isZero(pt3.DistTo(pt1)) || sg_math.isZero(pt3.DistTo(pt2))) { pt3 = null; continue; } v2 = pt3 - pt1; if (!v2.isParallel(v1)) { break; } v2 = null; } if (v2 == null) { return(false); } n = v1.crossMul(v2); // 如果与Z轴夹角大于90度 则反向 if (n.getInterAngle(new sg_Vector3(0, 0, 1)) > 90) { n.reverse(); } return(true); }
/// <summary> /// 构造函数 /// </summary> /// <param name="orgin">开挖坐标原点</param> /// <param name="H_Point">开挖坐标X(横)坐标轴上一点</param> /// <param name="V_Point">开挖坐标Y(纵)坐标轴正方向侧的任意点</param> public M1(sg_Vector3 orgin, sg_Vector3 H_Point, sg_Vector3 V_Point) { sg_Vector3 newZ = new sg_Vector3(0, 0, 1); sg_Vector3 newX = H_Point - orgin; sg_Vector3 YR1 = V_Point - orgin; sg_Vector3 newY = newZ.crossMul(newX); double angle = Math.Abs(YR1.getInterAngle(newY));// 两向量夹角 if (angle > 90) { newY.reverse(); } mTrans = new sg_Transformation(newZ, newX, newY, orgin); }
/// <summary> /// 构造函数 /// </summary> /// <param name="pt1">局部编录坐标控制点1</param> /// <param name="pt2">局部编录坐标控制点2</param> /// <param name="pt3">局部编录坐标控制点3</param> public M3(sg_Vector3 pt1, sg_Vector3 pt2, sg_Vector3 pt3, double xOffset = 0.0, double yOffset = 0.0) { ctrlPts = new sg_Vector3[3]; ctrlPts[0] = pt1; ctrlPts[1] = pt2; ctrlPts[2] = pt3; sg_Vector3 v12 = pt2 - pt1; sg_Vector3 v13 = pt3 - pt1; if (v12.isParallel(v13)) { } else { } sg_Vector3 newZ = new sg_Vector3(0, 0, 1); sg_Vector3 newX = pt2 - pt1; sg_Vector3 YR1 = pt3 - pt1; sg_Vector3 newY = newZ.crossMul(newX); double angle = Math.Abs(YR1.getInterAngle(newY)); // 两向量夹角 if (angle > 90) { newY.reverse(); } sg_Vector3 nLocalXoY = v12.crossMul(v13); // 局部编录面法向量 sg_Vector3 nGeodeticXoY = new sg_Vector3(0, 0, 1); // 大地坐标XoY面法向量 sg_Vector3 nx = nLocalXoY.isParallel(nGeodeticXoY) ? new sg_Vector3(1, 0, 0) : nLocalXoY.crossMul(nGeodeticXoY); sg_Vector3 ny = nLocalXoY.isParallel(nGeodeticXoY) ? new sg_Vector3(0, 1, 0) : nLocalXoY.crossMul(nx); sg_Vector3 nz = nx.crossMul(ny); sg_Vector3 origin = new sg_Vector3(pt1.x + xOffset, pt1.y + yOffset, pt1.z); this.mTrans = new sg_Transformation(nz, nx, ny, origin); IsValid = true; }