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编辑

相关文章
|
5天前
|
Java
承压计算 Java
承压计算 Java
9 1
|
5天前
|
算法 安全 Java
性能工具之 JMeter 自定义 Java Sampler 支持国密 SM2 算法
【4月更文挑战第28天】性能工具之 JMeter 自定义 Java Sampler 支持国密 SM2 算法
35 1
性能工具之 JMeter 自定义 Java Sampler 支持国密 SM2 算法
|
4天前
|
缓存 算法 Java
数据结构~缓存淘汰算法--LRU算法(Java的俩种实现方式,万字解析
数据结构~缓存淘汰算法--LRU算法(Java的俩种实现方式,万字解析
|
4天前
|
NoSQL 算法 Java
【redis源码学习】持久化机制,java程序员面试算法宝典pdf
【redis源码学习】持久化机制,java程序员面试算法宝典pdf
|
5天前
|
算法 调度 UED
作业调度算法(含详细计算过程)和进程调度算法浅析
作业调度算法(含详细计算过程)和进程调度算法浅析
36 1
作业调度算法(含详细计算过程)和进程调度算法浅析
|
5天前
|
资源调度 算法 块存储
m基于遗传优化的LDPC码OMS译码算法最优偏移参数计算和误码率matlab仿真
MATLAB2022a仿真实现了遗传优化的LDPC码OSD译码算法,通过自动搜索最佳偏移参数ΔΔ以提升纠错性能。该算法结合了低密度奇偶校验码和有序统计译码理论,利用遗传算法进行全局优化,避免手动调整,提高译码效率。核心程序包括编码、调制、AWGN信道模拟及软输入软输出译码等步骤,通过仿真曲线展示了不同SNR下的误码率性能。
10 1
|
5天前
|
算法 Serverless
m基于遗传优化的LDPC码NMS译码算法最优归一化参数计算和误码率matlab仿真
MATLAB 2022a仿真实现了遗传优化的归一化最小和(NMS)译码算法,应用于低密度奇偶校验(LDPC)码。结果显示了遗传优化的迭代过程和误码率对比。遗传算法通过选择、交叉和变异操作寻找最佳归一化因子,以提升NMS译码性能。核心程序包括迭代优化、目标函数计算及性能绘图。最终,展示了SNR与误码率的关系,并保存了关键数据。
19 1
|
5天前
|
安全 Java
【亮剑】Java中的`Future`接口代表异步计算结果,常与`ExecutorService`配合启动任务并获取结果
【4月更文挑战第30天】Java中的`Future`接口代表异步计算结果,常与`ExecutorService`配合启动任务并获取结果。`Future`接口提供`isDone()`、`get()`、`get(timeout, unit)`和`cancel(mayInterruptIfRunning)`等方法。`FutureTask`是`Future`的实现类,可作为`Runnable`执行并返回结果。
|
5天前
|
算法 TensorFlow 算法框架/工具
基于直方图的图像阈值计算和分割算法FPGA实现,包含tb测试文件和MATLAB辅助验证
这是一个关于图像处理的算法实现摘要,主要包括四部分:展示了四张算法运行的效果图;提到了使用的软件版本为VIVADO 2019.2和matlab 2022a;介绍了算法理论,即基于直方图的图像阈值分割,通过灰度直方图分布选取阈值来区分图像区域;并提供了部分Verilog代码,该代码读取图像数据,进行处理,并输出结果到"result.txt"以供MATLAB显示图像分割效果。
|
5天前
|
设计模式 算法 Java
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式