Java计算点到面、点到线的距离

public class DistanceUtils {
	
	public static void main(String[] args) {
		float[] p = {80, 80, -5};	//测量点
		float[] p1 = {1, 1, 1};	//平面上的点1
		float[] p2 = {50, 50, 50};	//平面上的点2
		float[] p3 = {80, 20, -1};	//平面上的点3
		
//		float[] p = {4, 4, -5};
//		float[] p1 = {-2, 2, 0};	//平面上的点1
//		float[] p2 = {-2, 0, 2};	//平面上的点2
//		float[] p3 = {-2, 5, 5};	//平面上的点3
		
		System.out.println(distance2area(p, p1, p2, p3));
		
		
	}
	
	/**
	 * 计算点到平面的距离
	 * @param point 点的坐标
	 * @param area 平面的一般方程式 Ax + By + Cz + D = 0;area = [A, B, C, D];
	 * @return
	 */
	public static float distance2area(float[] point, float[] area){
		float distance = (float)(absSum(point, area) / Math.sqrt(sqrtSum(area)));
		BigDecimal a = BigDecimal.valueOf(distance);
		return a.setScale(2, RoundingMode.HALF_UP).floatValue();
	}

	/**
	 * 计算点到平面的距离
	 * @param point 点的坐标
	 * @param areaPoint1 平面上点的坐标1
	 * @param areaPoint2 平面上点的坐标2
	 * @param areaPoint3 平面上点的坐标3
	 * @return
	 */
	public static float distance2area(float[] point, float[] areaPoint1, float[] areaPoint2, float[] areaPoint3){
		float[] area = buildArea(areaPoint1, areaPoint2, areaPoint3);
		return (float)distance2area(point, area);
	}
	
	/**
	 * 计算点到直线的距离
	 * @param point 点的坐标
	 * @param linePoint1 直线上的点的坐标1
	 * @param linePoint2 直线上的点的坐标2
	 * @return
	 */
	public static float point2line(float[] point, float[] linePoint1, float[] linePoint2) {
	 
		//直线上的2个点
		float x1 = linePoint1[0];
		float y1 = linePoint1[1];
		float z1 = linePoint1[2];

		float x2 = linePoint2[0];
		float y2 = linePoint2[1];
		float z2 = linePoint2[2];
	 
		float normal01_x = x2 - x1;
		float normal01_y = y2 - y1;
		float normal01_z = z2 - z1;
	 
		float normal02_x = point[0] - x1;
		float normal02_y = point[1] - y1;
		float normal02_z = point[2] - z1;
	 
		//求取两个向量的夹角:弧度
		float fenzi = normal01_x*normal02_x + normal01_y*normal02_y + normal01_z*normal02_z;
		float lengthN1 = (float)(Math.sqrt(normal01_x*normal01_x + normal01_y*normal01_y + normal01_z*normal01_z));
		float lengthN2 = (float)(Math.sqrt(normal02_x*normal02_x + normal02_y*normal02_y + normal02_z*normal02_z));
		float hudu = (float)(Math.acos(fenzi / (lengthN1*lengthN2)));
	 
		//再求取点到直线的距离
		float ds = (float)(Math.abs(lengthN2 * Math.sin(hudu)));
		return ds;
	}
	
	private static float[] buildArea(float[] areaPoint1, float[] areaPoint2, float[] areaPoint3) {
		float[] area = new float[4];
		
    	area[0] = (areaPoint3[1] - areaPoint1[1])*(areaPoint3[2] - areaPoint1[2]) - (areaPoint2[2] -areaPoint1[2])*(areaPoint3[1] - areaPoint1[1]);

    	area[1] = (areaPoint3[0] - areaPoint1[0])*(areaPoint2[2] - areaPoint1[2]) - (areaPoint2[0] - areaPoint1[0])*(areaPoint3[2] - areaPoint1[2]);

    	area[2] = (areaPoint2[0] - areaPoint1[0])*(areaPoint3[1] - areaPoint1[1]) - (areaPoint3[0] - areaPoint1[0])*(areaPoint2[1] - areaPoint1[1]);
    	
    	area[3] = -1 * (area[0] * areaPoint1[0] + area[1] * areaPoint1[1] + area[2] * areaPoint1[2]);
    	
		return area;
	}

	private static float sqrtSum(float[] arr){
        float sum = 0;
        for(int i = 0 ; i < arr.length -1 ; i++){
            sum += Math.pow( arr[ i ] , 2);
        }
        return sum;
    }

	private static float absSum(float[] arr1 , float[] arr2){
		float sum = 0;
        for(int i = 0 ; i < arr1.length && i < arr2.length -1 ; i++){
            sum += (arr1[ i ] * arr2 [ i]);
        }
        sum += arr2[arr2.length - 1];
        return Math.abs(sum);
    }
    
    /**
     * 空间直角坐标系中平面方程为Ax+By+Cz+D=0。
     * 直线方程就是:A1x+B1y+C1z+D1=0,A2x+B2y+C2z+D2=0联立,
     * (联立的结果可以表示为行列式)
     * 空间直线的标准式:(类似于平面坐标系中的点斜式)
     * (x-x0)/a=(y-y0)/b=(z-z0)/c;
     * 其中(a,b,c)为方向向量,
     * 空间直线的两点式:(类似于平面坐标系中的两点式)
     * (x-x1)/(x-x2)=(y-y1)/(y-y2)=(z-z1)/(z-z2)。
     * 
     * 暂时不用
     */

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值