python 2.7 中的以下方法可能是您的问题的公平解决方案。
from itertools import combinations, product
import matplotlib.pyplot as plt
import numpy as np
class Triangle(object):
def __str__(self):
return "Triangle: " + str(self.vertices)
def __init__(self,A,B,C):
""" Creates a Triangle of vertices A,B,C """
self.A = A
self.B = B
self.C = C
self.vertices = [A,B,C]
def area(self):
""" Area of the triangle """
x1 = self.A[0]
y1 = self.A[1]
x2 = self.B[0]
y2 = self.B[1]
x3 = self.C[0]
y3 = self.C[1]
return abs((x1 * (y2 - y3) + x2 * (y3 - y1)
+ x3 * (y1 - y2)) / 2.0)
def isInside(self,X):
""" Function to check whether X lies inside the triangle """
area = self.area()
area1 = Triangle(X,self.B,self.C).area()
area2 = Triangle(self.A,X,self.C).area()
area3 = Triangle(self.A,self.B,X).area()
# Check if sum of area1, area2 and area3 is same as area
if(area == area1 + area2 + area3):
return True
else:
return False
def findPosibleIntegerTriangles(self):
""" Find posible triangles moving vertices to next integer values (512 posible triangles) """
posibleA = posiblePoints(self.A)
posibleB = posiblePoints(self.B)
posibleC = posiblePoints(self.C)
listPosibleVertices = list(product(*[posibleA, posibleB, posibleC]))
posibleTriangles = [Triangle(A,B,C) for A,B,C in listPosibleVertices ]
return posibleTriangles
def findPosibleIncludingIntegerTriangles(self):
""" Find those posible triangles that include the original triangle """
posibleIncludingTriangles = list()
posibleTriangles = self.findPosibleIntegerTriangles()
for triangle in posibleTriangles:
if self.isTriangleIncluded(triangle):
posibleIncludingTriangles.append(triangle)
return posibleIncludingTriangles
def isTriangleIncluded(self,triangle):
""" Checks if it's included in the triangle selected (DEF) """
DNotInside = not self.isInside(triangle.A)
ENotInside = not self.isInside(triangle.B)
FNotInside = not self.isInside(triangle.C)
D = triangle.A
E = triangle.B
F = triangle.C
ABdoNotIntersectDE = not segmentsIntersect(self.A,self.B,D,E)
ABdoNotIntersectEF = not segmentsIntersect(self.A,self.B,E,F)
ABdoNotIntersectFD = not segmentsIntersect(self.A,self.B,F,D)
BCdoNotIntersectDE = not segmentsIntersect(self.B,self.C,D,E)
BCdoNotIntersectEF = not segmentsIntersect(self.B,self.C,E,F)
BCdoNotIntersectFD = not segmentsIntersect(self.B,self.C,F,D)
CAdoNotIntersectDE = not segmentsIntersect(self.C,self.A,D,E)
CAdoNotIntersectEF = not segmentsIntersect(self.C,self.A,E,F)
CAdoNotIntersectFD = not segmentsIntersect(self.C,self.A,F,D)
return DNotInside and ENotInside and FNotInside and \
ABdoNotIntersectDE and ABdoNotIntersectEF and ABdoNotIntersectFD and \
BCdoNotIntersectDE and BCdoNotIntersectEF and BCdoNotIntersectFD and \
CAdoNotIntersectDE and CAdoNotIntersectEF and CAdoNotIntersectFD
def findMinimumIntegerTriangle(self):
""" Find the minimum triangle enlarged by integer values that includes the original triangle """
minimumIntegerTriangle = None
area = None
for triangle in self.findPosibleIncludingIntegerTriangles():
if area == None:
area = triangle.area()
minimumIntegerTriangle = triangle
else:
if triangle.area() < area:
area = triangle.area
minimumIntegerTriangle = triangle
return minimumIntegerTriangle
def plot(self, color = "blue"):
pol = plt.Polygon(np.array(self.vertices),color = color)
plt.gca().add_patch(pol)
plt.autoscale()
def posiblePoints(P):
""" Determine posible points to move to """
posibleX = range(P[0]-1,P[0]+2)
posibleY = range(P[1]-1,P[1]+2)
posibleP = []
for x in posibleX:
for y in posibleY:
if x!=P[0] or y!=P[1]:
posibleP.append((x,y))
return posibleP
def segmentsIntersect(A,B,C,D):
""" Check if segment AB instersects with CD """
def ccw(A,B,C):
return (C[1]-A[1]) * (B[0]-A[0]) > (B[1]-A[1]) * (C[0]-A[0])
return ccw(A,C,D) != ccw(B,C,D) and ccw(A,B,C) != ccw(A,B,D)
# Select the vertices of original triangle
A = (-2,0)
B = (4,0)
C = (-1,3)
# Define the triangle
T = Triangle(A,B,C)
# Find the minimum triangle enlarged by integer values that includes the original triangle and print it
Tmin = T.findMinimumIntegerTriangle()
print Tmin
# Plot the found minimum triangle and the original one
Tmin.plot("red")
T.plot("blue")
plt.axis('equal')
plt.grid()
plt.show()
代码有一个Triangle 类。 Triangle 对象由三个顶点定义,它们是元组,并定义了函数area 用于计算三角形面积,isInside 用于检查点是否在三角形内,findPosibleIntegerTriangles 用于查找可能的三角形,isTriangleIncluded检查它是否包含在某个三角形中,findMinimumIntegerTriangle 会找到它的“最小三角形”(如果有的话)。
要找到“最小三角形”,它会查找所有可能的“整数三角形”,这些“整数三角形”是通过将每个方向上的三个顶点移动一个单位(总共 512 种可能性)而产生的。然后从这些可能的三角形中检查顶点是否在原始三角形之外,并确保它的任何边都不与原始三角形的任何线段相交(如果两个条件都为真,则三角形将包括原始三角形)。最后从那些可能的“整数三角形”中找出面积最小的。
程序输出“最小三角形”的顶点坐标(通过打印作为解找到的Triangle 对象Tmin)并绘制“最小三角形”和原始三角形。
输出是:
>>>
Triangle: [(-3, -1), (5, 0), (-1, 4)]