我有一個函式旨在將多邊形向左或向右旋轉 5 度并回傳它們的新點。該功能及其所需的功能如下player_center。
# finds center of player shape
# finds slope and midpoint of each vertice-midpoint line on the longer sides,
# then the intercept of them all
def player_center(player):
left_mid = line_midpoint(player[0], player[1])
right_mid = line_midpoint(player[0], player[2])
left_mid_slope = line_slope(left_mid, player[2])
right_mid_slope = line_slope(right_mid, player[1])
left_mid_line = find_equation(player[2], left_mid_slope, True)
right_mid_line = find_equation(player[1], right_mid_slope, True)
standard_left_mid_line = slope_intercept_to_standard(left_mid_line[0], left_mid_line[1], left_mid_line[2])
standard_right_mid_line = slope_intercept_to_standard(right_mid_line[0], right_mid_line[1], right_mid_line[2])
lines = sym.Matrix([standard_left_mid_line, standard_right_mid_line])
return (float(lines.rref()[0].row(0).col(2)[0]), float(lines.rref()[0].row(1).col(2)[0]))
# rotates the player using SOHCAHTOA
# divides x coordinate by radius to find angle, then adds or subtracts increment of 5 to it depending on direction
# calculates the position of point at incremented angle, then appends to new set of points
# finally, new set is returned
# direction; 1 is left, 0 is right
def rotate_player(player, direction):
increment = math.pi/36 # radian equivalent of 5 degrees
full_circle = 2 * math.pi # radian equivalent of 360 degrees
center = player_center(player)
new_player = []
for point in player:
radius = line_distance(point, center)
point_sin = (center[1] - point[1])/radius
while (point_sin > 1):
point_sin -= 1
point_angle = math.asin(point_sin)
if (direction == 1):
if ((point_angle increment) > math.pi * 2):
new_angle = (point_angle increment) - math.pi * 2
else:
new_angle = point_angle increment
else:
if ((point_angle-increment) < 0):
new_angle = 2 * math.pi (point_angle-increment)
else:
new_angle = point_angle-increment
print("The angle was {}".format(math.degrees(point_angle)))
print("The angle is now {}".format(math.degrees(new_angle))) # print lines are for debug purposes
new_point = ((radius * math.cos(new_angle)) center[0], -(radius * math.sin(new_angle)) center[1])
new_player.append(new_point)
print(new_player)
return new_player
它所依賴的幾何函式都在這個檔案中定義:
import math
import sympy as sym
# shape is in form of list of tuples e.g [(1,1), (2,1), (1,0), (2,0)]
# angle is in degrees
# def rotate_shape(shape, angle):
def line_distance(first_point, second_point):
return math.sqrt( (second_point[0] - first_point[0]) ** 2 (second_point[1] - first_point[1]) ** 2)
# undefined is represented by None in this program
def line_slope(first_point, second_point):
if (second_point[0] - first_point[0] == 0):
return None
elif (second_point[1] - first_point[1] == 0):
return 0
else:
return (second_point[1] - first_point[1])/(second_point[0] - first_point[0])
def line_midpoint(first_point, second_point):
return ( (first_point[0] second_point[0])/2, (first_point[1] second_point[1])/2 )
def find_equation(coord_pair, slope, array_form):
# Array form useful for conversion into standard form
if (array_form == True):
if (slope == 0):
intercept = coord_pair[1]
return [0, 1, intercept]
elif (slope == None):
intercept = coord_pair[0]
return [1, 0, intercept]
else:
intercept = coord_pair[1] - (coord_pair[0] * slope)
return [slope, 1, intercept]
else:
if (slope == 0):
intercept = coord_pair[1]
print("y = {0}".format(intercept))
return
elif (slope == None):
intercept = coord_pair[0]
print("x = {0}".format(intercept))
return
else:
intercept = coord_pair[1] - (coord_pair[0] * slope)
if (intercept >= 0):
print("y = {0}x {1}".format(slope, intercept))
return
else:
print("y = {0}x - {1}".format(slope, intercept))
def find_perpendicular(slope):
if (slope == 0):
return None
elif (slope == None):
return 0
else:
return -(1/slope)
def find_perp_bisector(first_point, second_point):
# This function finds the perpendicular bisector between two points, using funcs made previously
midpoint = line_midpoint(first_point, second_point)
slope = line_slope(first_point, second_point)
return find_equation(midpoint, -(1/slope))
def find_perp_equation(x, y, m, array_form):
# returns the perpendicular equation of a given line
if (array_form == True):
return [find_perpendicular(x), y, m]
else:
if (m >= 0):
print("{0}y = {1}x {2}".format(y, find_perpendicular(x), m))
else:
print("{0}y = {1}x - {2}".format(y, find_perpendicular(x), m))
def find_hyp(a, b):
return math.sqrt((a**2) (b**2))
def find_tri_area(a, b, c):
# finds area of triangle using Heron's formula
semi = (a b c)/2
return math.sqrt(semi * (semi - a) * (semi - b) * (semi - c) )
def r_tri_check(a, b, c):
if (a**2) (b**2) != (c**2):
print("This thing fake, bro.")
def find_point_section(first_point, second_point, ratio):
# I coded this half a year ago and can't remember what for, but kept it here anyway.
# separtions aren't necessary, but good for code readability
first_numerator = (ratio[0] * second_point[0]) (ratio[1] * first_point[0])
second_numerator = (ratio[0] * second_point[1]) (ratio[1] * first_point[1])
return ( first_numerator/(ratio[0] ratio[1]), second_numerator/(ratio[0] ratio[1]))
def slope_intercept_to_standard(x, y, b):
# x and y are the coeffients of the said variables, for example 5y = 3x 8 would be inputted as (3, 5, 8)
if (x == 0):
return [0, 1, b]
elif (y == 0):
return [x, 0, b]
else:
return [x, -y, -b]
它在數學上看起來很合理,但是當我嘗試應用它時,一切都變得松散了。例如,當嘗試將它與polygon_points等于的集合一起應用時[(400, 300), (385, 340), (415, 340)],所有地獄都會崩潰。
重復呼叫函式的輸出示例polygon_points(為清楚起見,手動間隔輸出):
The angle was 90.0
The angle is now 95.0
The angle was -41.633539336570394
The angle is now -36.633539336570394
The angle was -41.63353933657017
The angle is now -36.63353933657017
The angle was 64.4439547804165
The angle is now 69.4439547804165
The angle was -64.44395478041695
The angle is now -59.44395478041695
The angle was -64.44395478041623
The angle is now -59.44395478041624
The angle was 80.94458887142648
The angle is now 85.94458887142648
The angle was -80.9445888714264
The angle is now -75.9445888714264
The angle was -80.94458887142665
The angle is now -75.94458887142665
誰能解釋一下?
uj5u.com熱心網友回復:
太多不相關的代碼,很多像這樣的魔法while (point_sin > 1): point_sin -= 1- 很難重現。
要圍繞某個中心旋轉點,您只需要這個(cos(fi), sin(fi)在您的情況下預先計算的值在哪里):
new_x = center_x (old_x - center_x) * cos(fi) - (old_y - center_y) * sin(fi)
new_y = center_y (old_x - center_x) * sin(fi) (old_y - center_y) * cos(fi)
uj5u.com熱心網友回復:
這是 SymPy 中 RegularPolygon 的內置功能:
>>> from sympy import RegularPolygon, rad
>>> p = RegularPolygon((0,0), 1, 5)
>>> p.vertices[0]
Point2D(1, 0)
>>> p.rotate(rad(30)) # or rad(-30)
>>> p.vertices[0]
Point2D(sqrt(3)/2, 1/2)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/419283.html
標籤:
