4.4 给定的点是否在三角形之内

2024-05-28 15:58

本文主要是介绍4.4 给定的点是否在三角形之内,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 前言

本文的一些图片, 资料 截取自编程之美

2. 问题描述

这里写图片描述

3. 问题分析

假设给定的三角形为ABC, 给定的点为D, 使用S(ABC) 表示ABC三个点构成的三角形的面积
解法一 : 连接AD, BD, CD, 然后求解S(ABC); S(DBC), S(ADC), S(ABD), 如果S(ABC) == S(DBC) + S(ADC) + S(ABD), 则说明给定的点D是在三角形ABC内部, 否则后者的面积是会大于ABC的面积的

解法二 : 逆时针遍历ABC的三个边, AB, BC, CA, 如果相对于这三个边, D**均**在左边, 则说明D在三角形ABC的内部

可能上面的描述比较抽象, 特别是第二种解法, 下面是一些图解
解法一 :
1 D在ABC内部
这里写图片描述
2 D在ABC外部
这里写图片描述

解法二 :
1 D在ABC内部
这里写图片描述
2 D在ABC外部
这里写图片描述

4. 代码

/*** file name : Test13IsPointInTriangle.java* created at : 9:34:57 AM May 30, 2015* created by 970655147*/package com.hx.test04;public class Test13IsPointInTriangle {// 判断给定的点是否在三角形内部public static void main(String []args) {Point point = new Point(0, 6);Triangle tri = new Triangle(new Point(0, 0), new Point(5, 0), new Point(0, 7) );isPointInTriangle01(point, tri);isPointInTriangle02(point, tri);}// 思路 : 将tri的三个顶点和point连接起来, 然后判断(abd + acd + bcd) 是否大于abc// 如果大于   则说明d在abc之外, 否则说明d在abc之内public static void isPointInTriangle01(Point point, Triangle tri) {double offset = 0.001;Triangle abd = new Triangle(tri.vertex01, tri.vertex02, point);Triangle acd = new Triangle(tri.vertex01, tri.vertex03, point);Triangle bcd = new Triangle(tri.vertex02, tri.vertex03, point);if(abd.getArea() + acd.getArea() + bcd.getArea() > (tri.getArea() + offset) ) {Log.log(false);} else {Log.log(true);}}// 从d开始逆时针旋转   可以发现  点d在边ab, bc, ca的左边   于是便有了下面的方法// 如果点d 在ab, bc, ca的左边   则说明点d存在于该三角形内// 否则  点d在三角形内public static void isPointInTriangle02(Point point, Triangle tri) {if(crossProduct(tri.vertex01, tri.vertex02, point) >= 0.0d && crossProduct(tri.vertex02, tri.vertex03, point) >= 0.0d && crossProduct(tri.vertex03, tri.vertex01, point) >= 0.0d) {Log.log(true);} else {Log.log(false);}}// 表示向量 ab x ad// 如果ab x ad > 0,  则说明d在ab的左边// 如果ab x ad < 0,  则说明d在ab的右边// 如果ab x ad == 0,  则说明d在ab的上private static double crossProduct(Point a, Point b, Point d) {return (b.x - a.x) * (d.y - a.y) - (d.x - a.x) * (b.y - a.y);}// 三角形static class Triangle {// 三个顶点  三个边长Point vertex01, vertex02, vertex03;double edge12, edge23, edge31;// 初始化public Triangle() {}public Triangle(Point vertex01, Point vertex02, Point vertex03) {this.vertex01 = vertex01;this.vertex02 = vertex02;this.vertex03 = vertex03;edge12 = calcEdge(vertex01, vertex02);edge23 = calcEdge(vertex02, vertex03);edge31 = calcEdge(vertex03, vertex01);}// 给定两个顶点  计算他们之间的距离private double calcEdge(Point vertex01, Point vertex02) {return Math.sqrt(Math.pow((vertex01.x - vertex02.x ), 2) + Math.pow((vertex01.y - vertex02.y ), 2) );}// 利用海伦公式求面积public double getArea() {double p = (edge12 + edge23 + edge31) / 2;return Math.sqrt((p - edge12) * (p - edge23) * (p - edge31) * p );}}}

5. 运行结果

这里写图片描述

6. 总结

这个问题不仅让我了解到了这两种方法, 还有一个收获就是, 了解到了海伦公式, 以及勾股定理的证明

注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!

这篇关于4.4 给定的点是否在三角形之内的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1011023

相关文章

C#比较两个List集合内容是否相同的几种方法

《C#比较两个List集合内容是否相同的几种方法》本文详细介绍了在C#中比较两个List集合内容是否相同的方法,包括非自定义类和自定义类的元素比较,对于非自定义类,可以使用SequenceEqual、... 目录 一、非自定义类的元素比较1. 使用 SequenceEqual 方法(顺序和内容都相等)2.

查询Oracle数据库表是否被锁的实现方式

《查询Oracle数据库表是否被锁的实现方式》本文介绍了查询Oracle数据库表是否被锁的方法,包括查询锁表的会话、人员信息,根据object_id查询表名,以及根据会话ID查询和停止本地进程,同时,... 目录查询oracle数据库表是否被锁1、查询锁表的会话、人员等信息2、根据 object_id查询被

shell脚本快速检查192.168.1网段ip是否在用的方法

《shell脚本快速检查192.168.1网段ip是否在用的方法》该Shell脚本通过并发ping命令检查192.168.1网段中哪些IP地址正在使用,脚本定义了网络段、超时时间和并行扫描数量,并使用... 目录脚本:检查 192.168.1 网段 IP 是否在用脚本说明使用方法示例输出优化建议总结检查 1

如何测试计算机的内存是否存在问题? 判断电脑内存故障的多种方法

《如何测试计算机的内存是否存在问题?判断电脑内存故障的多种方法》内存是电脑中非常重要的组件之一,如果内存出现故障,可能会导致电脑出现各种问题,如蓝屏、死机、程序崩溃等,如何判断内存是否出现故障呢?下... 如果你的电脑是崩溃、冻结还是不稳定,那么它的内存可能有问题。要进行检查,你可以使用Windows 11

【WebGPU Unleashed】1.1 绘制三角形

一部2024新的WebGPU教程,作者Shi Yan。内容很好,翻译过来与大家共享,内容上会有改动,加上自己的理解。更多精彩内容尽在 dt.sim3d.cn ,关注公众号【sky的数孪技术】,技术交流、源码下载请添加微信号:digital_twin123 在 3D 渲染领域,三角形是最基本的绘制元素。在这里,我们将学习如何绘制单个三角形。接下来我们将制作一个简单的着色器来定义三角形内的像素

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

easyui同时验证账户格式和ajax是否存在

accountName: {validator: function (value, param) {if (!/^[a-zA-Z][a-zA-Z0-9_]{3,15}$/i.test(value)) {$.fn.validatebox.defaults.rules.accountName.message = '账户名称不合法(字母开头,允许4-16字节,允许字母数字下划线)';return fal

【408DS算法题】039进阶-判断图中路径是否存在

Index 题目分析实现总结 题目 对于给定的图G,设计函数实现判断G中是否含有从start结点到stop结点的路径。 分析实现 对于图的路径的存在性判断,有两种做法:(本文的实现均基于邻接矩阵存储方式的图) 1.图的BFS BFS的思路相对比较直观——从起始结点出发进行层次遍历,遍历过程中遇到结点i就表示存在路径start->i,故只需判断每个结点i是否就是stop

linux 判断某个命令是否安装

linux 判断某个命令是否安装 if ! [ -x "$(command -v git)" ]; thenecho 'Error: git is not installed.' >&2exit 1fi

CSS实现DIV三角形

本文内容收集来自网络 #triangle-up {width: 0;height: 0;border-left: 50px solid transparent;border-right: 50px solid transparent;border-bottom: 100px solid red;} #triangle-down {width: 0;height: 0;bor