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

相关文章
|
7月前
|
机器学习/深度学习 Java 编译器
解锁硬件潜能:Java向量化计算,性能飙升W倍!
编译优化中的机器相关优化主要包括指令选择、寄存器分配、窥孔优化等,发生在编译后端,需考虑目标平台的指令集、寄存器、SIMD支持等硬件特性。向量化计算利用SIMD技术,实现数据级并行,大幅提升性能,尤其适用于图像处理、机器学习等领域。Java通过自动向量化和显式向量API(JDK 22标准)支持该技术。
303 4
|
6月前
|
算法 机器人
基于SOA海鸥优化算法的PID控制器最优控制参数计算matlab仿真
本课题研究基于海鸥优化算法(SOA)优化PID控制器参数的方法,通过MATLAB仿真对比传统PID控制效果。利用SOA算法优化PID的kp、ki、kd参数,以积分绝对误差(IAE)为适应度函数,提升系统响应速度与稳定性。仿真结果表明,SOA优化的PID控制器在阶跃响应和误差控制方面均优于传统方法,具有更快的收敛速度和更强的全局寻优能力,适用于复杂系统的参数整定。
|
5月前
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
915 35
|
5月前
|
存储 算法 搜索推荐
《数据之美》:Java数据结构与算法精要
本系列深入探讨数据结构与算法的核心原理及Java实现,涵盖线性与非线性结构、常用算法分类、复杂度分析及集合框架应用,助你提升程序效率,掌握编程底层逻辑。
|
5月前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
9月前
|
存储 算法 安全
Java中的对称加密算法的原理与实现
本文详细解析了Java中三种常用对称加密算法(AES、DES、3DES)的实现原理及应用。对称加密使用相同密钥进行加解密,适合数据安全传输与存储。AES作为现代标准,支持128/192/256位密钥,安全性高;DES采用56位密钥,现已不够安全;3DES通过三重加密增强安全性,但性能较低。文章提供了各算法的具体Java代码示例,便于快速上手实现加密解密操作,帮助用户根据需求选择合适的加密方案保护数据安全。
563 58
|
8月前
|
自然语言处理 Java Apache
在Java中将String字符串转换为算术表达式并计算
具体的实现逻辑需要填写在 `Tokenizer`和 `ExpressionParser`类中,这里只提供了大概的框架。在实际实现时 `Tokenizer`应该提供分词逻辑,把输入的字符串转换成Token序列。而 `ExpressionParser`应当通过递归下降的方式依次解析
427 14
|
8月前
|
机器学习/深度学习 算法 Java
Java实现林火蔓延路径算法
记录正在进行的森林防火项目中林火蔓延功能,本篇文章可以较好的实现森林防火蔓延,但还存在很多不足,如:很多参数只能使用默认值,所以蔓延范围仅供参考。(如果底层设备获取的数据充足,那当我没说)。注:因林火蔓延涉及因素太多,如静可燃物载量、矿质阻尼系数等存在估值,所以得出的结果仅供参考。
209 5
|
8月前
|
存储 负载均衡 算法
我们来说一说 Java 的一致性 Hash 算法
我是小假 期待与你的下一次相遇 ~
323 1
|
7月前
|
运维 监控 算法
基于 Java 滑动窗口算法的局域网内部监控软件流量异常检测技术研究
本文探讨了滑动窗口算法在局域网流量监控中的应用,分析其在实时性、资源控制和多维分析等方面的优势,并提出优化策略,结合Java编程实现高效流量异常检测。
291 0

热门文章

最新文章