JTS Java常用空间几何算法

总结日常工作中计算家具模型需要用到的方法,需要用到JTS库
/**
 * 点(point)到直线(pt1_pt2)的垂足点
 * @param point
 * @param pt1
 * @param pt2
 * @return
 */
public static Point getFootPoint(Point point, Point pt1, Point pt2) {
    double A=pt2.getY()-pt1.getY();     //y2-y1
    double B=pt1.getX()-pt2.getX();     //x1-x2;
    double C=pt2.getX()*pt1.getY()-pt1.getX()*pt2.getY();     //x2*y1-x1*y2
    if (A * A + B * B < 1e-13) {
        return pt1;   //pt1与pt2重叠
    } else if (Math.abs(A * point.getX() + B * point.getY() + C) < 1e-13) {
        return point;   //point在直线上(pt1_pt2)
    } else {
        double x = (B * B * point.getX() - A * B * point.getY() - A * C) / (A * A + B * B);
        double y = (-A * B * point.getX() + A * A * point.getY() - B * C) / (A * A + B * B);
        return new Point(x,y);
    }
}
/**
 * 判断两条线段是否相交
 *
 * @param p1 l1的起点
 * @param p2 l1的终点
 * @param p3 l2的起点
 * @param p4 l2的终点
 * @return
 */
public static boolean lineIntersect(Point p1,Point p2,Point p3,Point p4) {
    if (Math.min(p1.getX(), p2.getX()) <= Math.max(p3.getX(), p4.getX()) &&
            Math.max(p1.getX(), p2.getX()) >= Math.min(p3.getX(), p4.getX()) &&
            Math.min(p1.getY(), p2.getY()) <= Math.max(p3.getY(), p4.getY()) &&
            Math.max(p1.getY(), p2.getY()) >= Math.min(p3.getY(), p4.getY()) &&
            mulVector(p3, p1, p4) * mulVector(p3, p4, p2) >= 0 &&
            mulVector(p1, p3, p2) * mulVector(p1, p2, p4) >= 0) {
        return true;
    }
    return false;
}


/**
 * 判定点是否在区域内
 * @param vertx 区域的所有x点
 * @param verty 区域的所有y点
 * @param point
 * @return
 */
public static boolean pnpoly(Double[] vertx,Double[] verty,Point point){
    boolean c = false;
    double testx = point.getX();
    double testy = point.getY();

    double minX = Arrays.stream(vertx).min(Double::compareTo).orElse(0D);
    double minY = Arrays.stream(verty).min(Double::compareTo).orElse(0D);
    double maxX = Arrays.stream(vertx).max(Double::compareTo).orElse(0D);
    double maxY = Arrays.stream(verty).max(Double::compareTo).orElse(0D);
    if (testx < minX || testx > maxX || testy < minY || testy > maxY) {
        return c;
    }

    int nvert = vertx.length;
    int i, j;

    for (i = 0, j = nvert-1; i < nvert; j = i++) {
        if ( ((verty[i]>testy) != (verty[j]>testy)) &&
                (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) ) {
            c = !c;
        }
    }
    //拓展,点正好在边界上
    if(!c){
        for (i = 0, j = nvert-1; i < nvert; j = i++) {
            c = onSegment(new Point(vertx[i],verty[i]),new Point(vertx[j],verty[j]),point);
            if(c){
                break;
            }
        }
    }
    return c;
}
/**
     * 根据直线方程获取在直线上且与p1距离为L的某点的坐标
     * @param l 距离 正数时取直线之间的点,负数时取直线之外的点
     * @param p1
     * @param p2
     * @return
     */
    public static Point getPointByEquation(double l, Point p1, Point p2) {
        if(l==0){
            return new Point(p1.getX(),p1.getY(),0);
        }
        double d = AlgorithmUtils.getDistance(p1,p2);
        if(l==d){
            return new Point(p2.getX(),p2.getY(),0);
        }
        Double[] equation = equation(p1, p2);
        Double k = equation[0];
        if(k.isInfinite() || Math.abs(k)==1.5707963267948966 || Math.abs(k)==4.71238898038469){
            if(p1.getY()>p2.getY()){
                return new Point(p1.getX(),p1.getY()-l,0);
            }else {
                return new Point(p1.getX(),p1.getY()+l,0);
            }
        }else if(Math.abs(k)==0){
            if(p1.getX()>p2.getX()){
                return new Point(p1.getX()-l,p1.getY(),0);
            }else {
                return new Point(p1.getX()+l,p1.getY(),0);
            }
        }else{
//            double A = Math.pow(k, 2) + 1;// A=k^2+1;
//            double B = 2 * ((b - p1.getY()) * k - p1.getX());// B=2[(b-y0)k-x0];
//            // C=(b-y0)^2+x0^2-L^2
//            double C = Math.pow(b - p1.getY(), 2) + Math.pow(p1.getX(), 2) - Math.pow(l, 2);
//            // 两根x1,x2= [-B±√(B^2-4AC)]/2A
//            double x1 = (-B + Math.sqrt(Math.pow(B, 2) - 4 * A * C)) / (2 * A);
//            double x2 = (-B - Math.sqrt(Math.pow(B, 2) - 4 * A * C)) / (2 * A);
//            double x = 0;// 最后确定是在已知两点之间的某点
//            if (x1 == x2) {
//                x = x1;
//            } else if (p1.getX() <= x1 && x1 <= p2.getX() || p2.getX() <= x1
//                    && x1 <= p1.getX()) {
//                x = x1;
//            } else if (p1.getX() <= x2 && x2 <= p2.getX() || p2.getX() <= x2
//                    && x2 <= p1.getX()) {
//                x = x2;
//            }
//            double y = k * x + b;
//            return new Point( x,  y,0);
              return JtsUtils.getExtractPoint(p1,p2,l,0);
        }
    }
/**
 * 获取点关于线的对称点
 * @param p1
 * @param p2
 * @param p
 * @return
 */
public static Point getSymmetryPoint(Point p1,Point p2, Point p){
    double a=p2.getY()-p1.getY();
    double b=p1.getX()-p2.getX();
    double c=p2.getX()*p1.getY()-p1.getX()*p2.getY();
    double k = - 2 * (a*p.getX() + b*p.getY() + c) / (a*a+b*b);
    double x = p.getX()+k*a;
    double y = p.getY()+k*b;
    return new Point(x,y);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JTS-1.14.zip是一个开源的Java Topology Suite (JTS)软件包的压缩文件。JTS是一个用于处理2D几何对象的Java API,它提供了许多易于使用和高效的空间算法数据结构。与其他对象模型不同,JTS使用了精确几何的概念,从而支持高精度的计算和可重现的结果。 该软件包包括以下组件: - JTS Core:包含用于处理几何对象的基本数据结构算法。 - JTS IO:包含用于将几何对象转换为WKT、WKB、GML和Shapefile格式的转换器。 - JTS Test:包含测试用例,可以用于测试几何算法的正确性和性能。 - JTS Example:包含一些示例代码,可以演示如何使用JTS API。 该软件包可用于开发许多空间相关的应用程序,例如GIS、CAD、网络分析和游戏。它受到许多开发人员的欢迎,因为它易于使用、可扩展性强,并且在处理空间数据和几何对象时具有出色的性能。 JTS-1.14.zip也是一个标志着JTS当前版本的压缩文件。该版本包括了许多新功能和改进,例如: - 添加新的几何类型和算法,例如曲线和三角形网格。 - 改进了JTS IO模块,支持更多的格式和选项,例如Well-Known Binary (WKB)和ISO 19107几何对象模型。 - 优化了索引和查询算法,提高了空间查询性能。 - 更新了Javadoc文档和示例代码。 总之,JTS-1.14.zip是一个高效、易于使用且功能强大的JAVA API,可用于开发许多空间相关的应用程序。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值