Java计算四边形中心点和两条线段交点算法

简介: Java计算四边形中心点和两条线段交点算法

需求

 已知四边形的四个点位,求四边形的中心点,即求四边形两条对角线的交点即为中心点。

image.gif编辑

先来复习下三角形面积公式: 已知三角形三点a(x,y) b(x,y) c(x,y), 三角形面积为:

double triArea=( (a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x) ) /2 ;

image.gif

因为 两向量叉乘==两向量构成的平行四边形(以两向量为邻边)的面积 , 所以上面的公式也不难理解.

而且由于向量是有方向的, 所以面积也是有方向的, 通常我们以逆时针为正, 顺时针为负数.


如果"线段ab和点c构成的三角形面积"与"线段ab和点d构成的三角形面积" 构成的三角形面积的正负符号相异,

那么点c和点d位于线段ab两侧.

图中虚线所示的三角形, 缠绕方向(三边的定义顺序)不同, 所以面积的正负符号不同.


下面还是先看代码:

由于我们只要判断符号即可, 所以前面的三角形面积公式我们就不需要后面的 除以2 了.

java计算两条线段的交点完整代码

import lombok.AllArgsConstructor;
import lombok.Data;
import java.math.BigDecimal;
public class Test {
    @Data
    @AllArgsConstructor
    static class Point{
        private BigDecimal x;
        private BigDecimal y;
    }
    public static void main(String[] args) {
        Point p1=getPoint(3630940.601591212,39438876);
        Point p2=getPoint(3630272.41274585,39441716);
        Point p3=getPoint(3630016.340373975,39441636);
        Point p4=getPoint(3630652.5201728526,39438848);
        Point point=segmentsInstr(p1,p3,p4,p2);
        if(point==null){
            System.out.print("未相交");
        }else{
            System.out.print("相交于:"+point.toString());
        }
    }
    public  static Point getPoint(double a,double b){
        BigDecimal aa=BigDecimal.valueOf(a);
        BigDecimal bb=BigDecimal.valueOf(b);
        return new Point(aa,bb);
    }
    private static  Point segmentsInstr(Point a, Point b, Point c, Point d){
        // 三角形abc 面积的2倍
        BigDecimal acxPoor=a.getX().subtract(c.getX());
        BigDecimal bcyPoor=b.getY().subtract(c.getY());
        BigDecimal acyPoor=a.getY().subtract(c.getY());
        BigDecimal bcxPoor=a.getX().subtract(c.getX());
        BigDecimal adxPoor=a.getX().subtract(d.getX());
        BigDecimal bdyPoor=b.getY().subtract(d.getY());
        BigDecimal adyPoor=a.getY().subtract(d.getY());
        BigDecimal bdxPoor=b.getX().subtract(d.getX());
        BigDecimal acx_bcy=acxPoor.multiply(bcyPoor);
        BigDecimal acy_bcx=acyPoor.multiply(bcxPoor);
        BigDecimal adx_bdy=adxPoor.multiply(bdyPoor);
        BigDecimal ady_bdx=adyPoor.multiply(bdxPoor);
        BigDecimal area_abc=acx_bcy.subtract(acy_bcx);
        // 三角形abd 面积的2倍
        BigDecimal area_abd=adx_bdy.subtract(ady_bdx);
        // 面积符号相同则两点在线段同侧,不相交 (对点在线段上的情况,本例当作不相交处理);
        BigDecimal area_abc_abd=area_abc.multiply(area_abd);
       if ( area_abc_abd.compareTo(BigDecimal.valueOf(0))==1 ) {
           System.out.println(666);
          return null;
        }
        BigDecimal caxPoor=c.getX().subtract(a.getX());
        BigDecimal dayPoor=d.getY().subtract(a.getY());
        BigDecimal cayPoor=c.getY().subtract(a.getY());
        BigDecimal daxPoor=d.getX().subtract(a.getX());
        BigDecimal cax_day=caxPoor.multiply(dayPoor);
        BigDecimal cay_dax=cayPoor.multiply(daxPoor);
        // 三角形cda 面积的2倍
        BigDecimal area_cda=cax_day.subtract(cay_dax);
        // 三角形cdb 面积的2倍
        // 注意: 这里有一个小优化.不需要再用公式计算面积,而是通过已知的三个面积加减得出.
        BigDecimal area_cda_abd=area_cda.add(area_abc);
        BigDecimal area_cdb=area_cda_abd.subtract(area_abd);
        BigDecimal area_cda_cdb=area_cda.multiply(area_cdb);
        if (area_cda_cdb.compareTo(BigDecimal.valueOf(0))==1 ) {
            return null;
        }
        BigDecimal area_abd_abc=area_abd.subtract(area_abc);
        //计算交点坐标
        BigDecimal t = area_cda.divide(area_abd_abc,3,BigDecimal.ROUND_HALF_UP);
        BigDecimal bax=b.getX().subtract(a.getX());
        BigDecimal dx=t.multiply(bax);
        BigDecimal bay=b.getY().subtract(a.getY());
        BigDecimal dy=t.multiply(bay);
        BigDecimal x=a.getX().add(dx);
        BigDecimal y=a.getY().add(dy);
        return new Point(x,y);
    }
}

image.gif

控制台输出结果

image.gif编辑

相关文章
|
1月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
69 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
1月前
|
存储 分布式计算 算法
大数据-106 Spark Graph X 计算学习 案例:1图的基本计算、2连通图算法、3寻找相同的用户
大数据-106 Spark Graph X 计算学习 案例:1图的基本计算、2连通图算法、3寻找相同的用户
60 0
|
11天前
|
存储 分布式计算 Java
存算分离与计算向数据移动:深度解析与Java实现
【11月更文挑战第10天】随着大数据时代的到来,数据量的激增给传统的数据处理架构带来了巨大的挑战。传统的“存算一体”架构,即计算资源与存储资源紧密耦合,在处理海量数据时逐渐显露出其局限性。为了应对这些挑战,存算分离(Disaggregated Storage and Compute Architecture)和计算向数据移动(Compute Moves to Data)两种架构应运而生,成为大数据处理领域的热门技术。
32 2
|
16天前
|
分布式计算 Java MaxCompute
ODPS MR节点跑graph连通分量计算代码报错java heap space如何解决
任务启动命令:jar -resources odps-graph-connect-family-2.0-SNAPSHOT.jar -classpath ./odps-graph-connect-family-2.0-SNAPSHOT.jar ConnectFamily 若是设置参数该如何设置
|
1月前
|
机器学习/深度学习 算法 搜索推荐
让星星⭐月亮告诉你,Java冒泡排序及其时间复杂度计算
冒泡排序是一种简单的排序算法,通过多次遍历数组,每次比较相邻元素并交换位置,将较小的元素逐步移至数组前端。第一轮结束后,最小值会位于首位;第二轮则将次小值置于第二位,依此类推。经过 (n-1) 轮遍历后,数组完成排序。冒泡排序的时间复杂度为 O(n²),在最优情况下(已排序数组)时间复杂度为 O(n)。示例代码展示了如何实现冒泡排序。
51 1
|
1月前
|
JSON 算法 数据可视化
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
这篇文章是关于如何通过算法接口返回的目标检测结果来计算性能指标的笔记。它涵盖了任务描述、指标分析(包括TP、FP、FN、TN、精准率和召回率),接口处理,数据集处理,以及如何使用实用工具进行文件操作和数据可视化。文章还提供了一些Python代码示例,用于处理图像文件、转换数据格式以及计算目标检测的性能指标。
58 0
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
|
1月前
|
算法 搜索推荐 Java
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
这篇文章介绍了如何使用Java后端技术,结合Graphics2D和Echarts等工具,生成包含个性化信息和图表的海报,并提供了详细的代码实现和GitHub项目链接。
105 0
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
|
16天前
|
Java API Apache
java集合的组内平均值怎么计算
通过本文的介绍,我们了解了在Java中计算集合的组内平均值的几种方法。每种方法都有其优缺点,具体选择哪种方法应根据实际需求和场景决定。无论是使用传统的循环方法,还是利用Java 8的Stream API,亦或是使用第三方库(如Apache Commons Collections和Guava),都可以有效地计算集合的组内平均值。希望本文对您理解和实现Java中的集合平均值计算有所帮助。
23 0
|
1月前
|
分布式计算 资源调度 Hadoop
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
88 3
|
1月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
67 2