Day20200713—点在三角形内
Day20200713—点在三角形内
文章目录
- Day20200713—点在三角形内
- 前言
- 参考
- 题目
- 描述
- 示例
- 解题
- 关键词与细节
- 条件
- 解题思路
- 算法实现
- 程序代码
- 运行截图
- 思考
- 后续
前言
因为各种原因,有一段时间没有开始计划性刷题了。在现在看来,无疑是浪费很多时间。
直到某一天,看到一位大牛每天都有计划性地学习,也看到了其中一道非常有趣的题,想起了高中刷题的日子。
所以从今天开始,开始计划性刷题。
关于标题,是因为这一道算法题的重点在于点在三角形内的运用。
参考
题目来源
Point in triangle test
虽然没有使用这个思路,但是非常具有参考价值
题目
描述
示例
解题
关键词与细节
不知道动物园的具体位置,动物园在三角形ABC范围内(包括边界与顶点)
3|OA|+2|OB|+|OC|最小,其中点O为动物园
O、A、B、C均为整点,均在同一个平面
条件
点O在三角形内,且满足3|OA|+2|OB|+|OC|最小
这两个条件只保证了点O的3|OA|+2|OB|+|OC|只有一个最小值
但无法保证只有一个点O,因为可能存在多个点O都具有相同的3|OA|+2|OB|+|OC|最小值。
解题思路
条件1
以三角形的三个顶点获取一个正方形区域即可,如下:
则点O即在正方形区域内,由于O、A、B、C均为整点,数量是有限的。
通过条件1获取点O集合
条件2:点O在三角形区域内
将条件1获取的集合进行筛选,需要满足条件:点O在三角形内
1.点O,A,B,C的坐标分别为:(x0,y0),(x1,y1),(x2,y2),(x3,y3)−−−−−2.如果点O在三角形ABC内的话,会满足以下条件:SABO∗OC→+SACO∗OB→+SBCO∗OA→=0→−−−−−3.已知三角形顶点坐标,可以通过以下公式计算:SABC=(1/2)∗(x1y2+x2y3+x3y1−x1y3−x2y1−x3y2)1.点O,A,B,C的坐标分别为:(x0,y0),(x1,y1),(x2,y2),(x3,y3)\\ -----\\ 2.如果点O在三角形ABC内的话,会满足以下条件:\\ S_{ABO}*\overrightarrow{OC}+S_{ACO}*\overrightarrow{OB}+S_{BCO}*\overrightarrow{OA}=\overrightarrow{0}\\ -----\\ 3.已知三角形顶点坐标,可以通过以下公式计算:\\ S_{ABC}=(1/2)*(x1y2+x2y3+x3y1-x1y3-x2y1-x3y2) 1.点O,A,B,C的坐标分别为:(x0,y0),(x1,y1),(x2,y2),(x3,y3)−−−−−2.如果点O在三角形ABC内的话,会满足以下条件:SABO∗OC+SACO∗OB+SBCO∗OA=0−−−−−3.已知三角形顶点坐标,可以通过以下公式计算:SABC=(1/2)∗(x1y2+x2y3+x3y1−x1y3−x2y1−x3y2)
条件3:取得最小值
有两个思路
思路1:使用一个标记对象,当出现更小的值时,将产生该值的对象赋予给标记对象
思路2:
使用两个集合,集合1存储所有所有满足条件1和条件2的点O
集合2存储对应产生的3|OA|+2|OB|+|OC|值。获得集合2中最小值的索引,返回集合1对应索引上的值即可
思路1和思路2产生的结果不同,当存在多个点O时,思路2,将返回多个点O,但思路1只能返回一个点O
由于示例返回一个即可,所以使用思路1即可
算法实现
程序代码
import math
class Node(object):def __init__(self,x,y):self.x = xself.y = y
class parrot(object):def __init__(self,a,b,c):""" a,b,c is a Node """self.a = aself.b = bself.c = cself.list_node = [self.a,self.b,self.c]def getDist(self,a,b):return math.sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))def getSum(self,node_o):return 3*self.getDist(node_o,self.a)+\2*self.getDist(node_o,self.b)+self.getDist(node_o,self.c)def areaoftriangle(self,node_a,node_b,node_c):#S=(1/2)*(x1y2+x2y3+x3y1-x1y3-x2y1-x3y2)"""node_a.x node_b.x node_c.xnode_a.y node_b.y node_c.y"""area = (1/2)*abs(node_a.x*node_b.y+node_b.x*node_c.y+node_c.x*node_a.y\-node_a.x*node_c.y-node_b.x*node_a.y-node_c.x*node_b.y)return areadef buildvector(self,node_1,node_2):return Node(node_2.x-node_1.x,node_2.y-node_1.y)def vectorofmultiply(self,k,vector):return Node(k*vector.x,k*vector.y)def vectorofsum(self,vector1,vector2,vector3):return Node(vector1.x+vector2.x+vector3.x,vector1.y+vector2.y+vector3.y)def check_in_out(self,node_o:Node):# Nodevector_oa = self.buildvector(self.a,node_o)vector_ob = self.buildvector(self.b,node_o)vector_oc = self.buildvector(self.c,node_o)# areaarea_aco = self.areaoftriangle(self.a,self.c,node_o)area_bco = self.areaoftriangle(self.b,self.c,node_o)area_abo = self.areaoftriangle(self.a,self.b,node_o)# sum = Sbco*Vector(oa)+Saco*Vector(ob)+Sabo*Vector(oc)=Vector(0,0)sum = self.vectorofsum(self.vectorofmultiply(area_bco,vector_oa),self.vectorofmultiply(area_aco,vector_ob),self.vectorofmultiply(area_abo,vector_oc))if sum.x == 0 and sum.y == 0:return Truereturn Falsedef run(self):list_x,list_y = [],[]for i in self.list_node:list_x.append(i.x)list_y.append(i.y)max_x,min_x = max(list_x),min(list_x)max_y,min_y = max(list_y),min(list_y)result,sumList = [],[]minSum = float('inf')flag = Nonefor i in range(min_x,max_x+1):for j in range(min_y,max_y+1):if self.check_in_out(Node(i,j)):if minSum > self.getSum(Node(i,j)):minSum = self.getSum(Node(i,j))flag = Node(i,j)return flag
if __name__ == "__main__":a = Node(0,1)b = Node(0,0)c = Node(2,0)o = Node(1,0)parrotObj = parrot(a,b,c)flag = parrotObj.run()print(flag.x,flag.y)
运行截图
思考
这一道题,更加侧重于数学思维,例如三角形面积公式,点在三角形内等等知识,都是一个很好的切入点。
三角形面积公式拓展下去,就有很多知识点,例如海伦公式等等。
而点在三角形内,则有重心法等等。
而大多数题都是侧重于经典数据结构和经典的算法。这也验证了当初那句
算法+数据结构=程序
算法和数据结构都同等重要。
后续
将会在这段时间内抽出时间,补充关于点在三角形内的更多方法和证明。
Day20200713—点在三角形内相关推荐
- 射线与三角形求交,并判断是否在三角形内的完整代码(带测试)
// Det.cpp : Defines the entry point for the console application. // #include "stdafx.h" # ...
- 编程之美---点是否在三角形内
已知三角形的三个顶点坐标,判断某个点是否在三角形中(在三角形的边上,我们也视作在三角形中) 解法一:通过点和三个顶点连接起来,从而计算点和三角形的每条边构成的三角形计算面积,然后把这三个面积加起来和原 ...
- 三角形内随机生成一个点
将三角形扩充成一个矩形 将矩形的两条边分别线性映射成一个随机生成器,这两个随机生成器相互独立 如果生成的D点在三角形外,将D以靠近的边为对称轴映射到三角形内的D'上. 显然随机生成的点在矩形内的分布是 ...
- 利用叉乘快速判断点是否在三角形内
利用叉乘快速判断点是否在三角形内 判断P是否在三角形ABC内: 向量: pa = P - A, ca = C - A; ba = B - A; 如果向量 cross(ca, pa)与向量 cross ...
- 判断一个点是否在指定三角形内(1)
问题:判断点P是否在三角形ABC内 判断一个点是否在在三角形内,最常用的两种方法:面积法.向量同向法.算法虽然很简单,但要做到高效却不容易,要考虑到二维.三维的区别,还要考虑到坐标是用浮点数还是用整数 ...
- 判断一个点是否在三角形内
转自:https://www.cnblogs.com/simplekinght/p/9218310.html 面积法:若点P在三角形ABC内,则三角形ABP+三角形ACP+三角形BCP的面积等于三角形 ...
- Java黑皮书课后题第3章:**3.27(几何:点是否在三角形内)假设一个平面上有一个直角三角形。编写程序,提示用户输入一个点的x坐标和y坐标,然后判断这个点是否在该三角形内
**3.27(几何:点是否在三角形内)假设一个平面上有一个直角三角形.编写程序,提示用户输入一个点的x坐标和y坐标,然后判断这个点是否在该三角形内 题目 题目描述 破题 运行示例 代码 题目 题目描述 ...
- hdu4353 Finding Mine三角形内的点数
http://acm.hdu.edu.cn/showproblem.php?pid=4353 题意: 求多边形面积和这个多边形内的金矿数的比值的最小值. 当xi<xj<xk时: 三角形内的 ...
- 判断点是否在三角形内
本文只是翻译和整理,原文在此http://www.blackpawn.com/texts/pointinpoly/default.html 概述 给定三角形ABC和一点P(x,y,z),判断点P是否在 ...
最新文章
- django mysql save_python,django,向mysql更新数据时save()报错不能用
- EOSIO.DCT 1.3以上版本工具编写EOS智能合约重大更新
- bash-shell高级编程--条件判断
- 通过这5个简单的技巧减少GC开销
- MFC中,多个Button响应同一个事件
- java频繁查询数据库_如何解决Cookie登录 频繁查询数据库问题?
- jquery tmpl的使用
- Linux基础知识汇总、有这一篇就够了(2021最新整理)
- 什么是测试开发工程师?
- openstack镜像格式转换
- Caused by: java.security.NoSuchAlgorithmException: SunTlsRsaPremasterSecret KeyGenerator not availab
- Java序列化神器——Jprotobuf(小白篇)
- java对焦_Android camera摄像头对焦,zoom的通知事件回调,告诉java应用层已经对焦完成...
- uniapp离线打包apk安装在android12上无法安装
- maven手工安装依赖包
- 垃圾桶--360安全浏览器插件,用于自助过滤不良信息;
- web前端开发需要学什么(包含前端学习路线)
- Docker 基本使用与常用环境
- 【webrtc】 socket 运行机制以及 stun 收发过程
- MAX6675应用注意事项