Is there a way to make a function that just adds motion to an object like the motion_add function from Game Maker?
Like: motion_add(speed1, direction1, speed2, direction2)
... where speed1 and direction1 is the current values of the object and
speed2 and direction2 is the additive.
I've figured it out myself.
def CoordsToDir(x1, y1, x2, y2):
return atan2(y2 - y1, x2 - x1)*180/pi
def DirToCoords(direction, length):
return [cos((direction) * pi / 180) * length, sin((direction) * pi / 180) * length]
def motion_add(speed1, direction1, speed2, direction2):
[x1, y1] = DirToCoords(direction1, speed1)
[x2, y2] = map(sum, zip([x1, y1], DirToCoords(direction2, speed2)))
speed = hypot(x2, y2)
direction = CoordsToDir(0, 0, x2, y2)
return [speed, direction]
Related
UNEXPOSED = '~'
POKEMON = "☺"
FLAG = "♥"
EXPOSED = "0"
possible_adjacent_amount = ["0", "1", "2" "3", "4", "5", "6", "7", "8"]
def draw_board(self, board):
self.delete()
index = 0
print(board)
for row in range(self._grid_size):
for column in range(self._grid_size):
x1 = column*self._cell_size
y1 = row * self._cell_size
x2 = x1 + self._cell_size
y2 = y1 + self._cell_size
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
#bounding_box = ((int (x1), int (y1)), (int (x2), int (y2)))
centre_pixel = (x1 + (x2 - x1) // 2, y1 + (y2 - y1) // 2)
self.pos_to_pixel[(row, column)] = centre_pixel
#tp = self.create_text((100, 100), text='1')
print(board[index])
if board[index] ==UNEXPOSED:
self.create_rectangle (x1, y1, x2, y2, fill="dark green", tags="rect")
if board[index] in possible_adjacent_amount :
# TODO why doesn't this work...?
self.create_text(self.position_to_pixel ((row, column)), text = board[index])
self.create_rectangle (x1, y1, x2, y2, fill="light green", tags="rect")
if board[index] == FLAG:
self.create_rectangle (x1, y1, x2, y2, fill="red", tags="rect")
if board[index] == POKEMON:
self.create_text ((centre_pixel), text=board[index])
self.create_rectangle (x1, y1, x2, y2, fill="yellow", tags="rect")
index += 1
The board input will be something like 0~~~1~~12~~3
The idea is that it will take the board index and then create text at the center pixel of the board index that will be the numbers which in this case would be 0, 1, 1, 2, 3
You if you want the numbers to be drawn on the rectangles you need to create the text after you create the rectangles otherwise you will create text behind the rectangles.
In the Python implementation of the Xiaolin Wu's line algorithm, a function is defined while being nested in another function. Part of the code:
def draw_line(img, p1, p2, color):
"""Draws an anti-aliased line in img from p1 to p2 with the given color."""
x1, y1 = p1
x2, y2 = p2
dx, dy = x2-x1, y2-y1
steep = abs(dx) < abs(dy)
p = lambda px, py: ((px,py), (py,px))[steep]
if steep:
x1, y1, x2, y2, dx, dy = y1, x1, y2, x2, dy, dx
if x2 < x1:
x1, x2, y1, y2 = x2, x1, y2, y1
grad = dy/dx
intery = y1 + _rfpart(x1) * grad
def draw_endpoint(pt):
x, y = pt
xend = round(x)
yend = y + grad * (xend - x)
xgap = _rfpart(x + 0.5)
px, py = int(xend), int(yend)
putpixel(img, p(px, py), color, _rfpart(yend) * xgap)
putpixel(img, p(px, py+1), color, _fpart(yend) * xgap)
return px
How does this work? Why didn't the programmer just define the code somewhere else and then call it in this function? If this function where to be called in a loop to draw multiple lines, wouldn't it be more efficient to just, as I said, define the nested function somewhere else?
try this:
class Humans():
def health(self, weight, height, age):
self.weight = weight
self.height = height
self.age = age
def health_health(self):
print(f'''This human is {self.age} years old; weighs {self.weight},
and has a height of {self.height}''')
Harar = Humans()
Harar.health(1,2,3)
Harar.health_health()
The reason why is because you are calling the function from the class definition, as opposed to the initialized object. You can do two things to fix this:
Call the function from the object that has been initialized:
class Foo:
def bar(x):
print(x)
a = Foo()
a.bar(10)
Or, define the function as a staticmethod:
class Foo:
#staticmethod
def bar(x):
print(x)
Foo.bar(10)
Both will output:
10
I have 3 points p1(x1, y1), p2(x2, y2) and p3(x3, y3). I am trying to calculate angle (in anti-clockwise direction) between these 3 points. I am using following dot product method as provided in multiple blogs and SE sites (like this).
def angle_between(p1, p2, p3):
x1, y1 = p1
x2, y2 = p2
x3, y3 = p3
v21 = (x1 - x2, y1 - y2)
v23 = (x3 - x2, y3 - y2)
dot = v21[0] * v23[0] + v21[1] * v23[1]
det = v21[0] * v23[1] - v21[1] * v23[0]
theta = np.rad2deg(np.arctan2(det, dot))
print(theta)
It is giving me correct angle for any points which are not on the straight line. For example
p1 = (0, 0)
p2 = (1, 0)
p3 = (1, 1)
angle_between(p1, p2, p3) # Prints -90
angle_between(p3, p2, p1) # Prints +90
However, if points are on the straight line, it is giving me same answer
p1 = (0, 0)
p2 = (1, 0)
p3 = (2, 0)
angle_between(p1, p2, p3) # Prints +180
angle_between(p3, p2, p1) # Prints +180
Here I was expecting (p3, p2, p1) to give -180. What am I missing here? If the method I am using is not correct, can someone help me point towards the correct method?
I have tried to use direct cosine law (as given here) but it only provides me angle without any sense of direction of the angle.
Check out this solution. It always provides positive angles, measured in anti-clockwise direction:
from math import atan2, degrees
def angle_between(p1, p2, p3):
x1, y1 = p1
x2, y2 = p2
x3, y3 = p3
deg1 = (360 + degrees(atan2(x1 - x2, y1 - y2))) % 360
deg2 = (360 + degrees(atan2(x3 - x2, y3 - y2))) % 360
return deg2 - deg1 if deg1 <= deg2 else 360 - (deg1 - deg2)
I want to rotate an oval around it's center. Currently I can display the static object witohut rotation, and I can't seem to find what to do wit it.
EDIT: I made a rotation function based on complex number multiplication, which seemed to work on lower polygons but the ellipse kinda looks the same.
A potato-level noob C.S. student.
also, the code:
from tkinter import*
import cmath, math
import time
def poly_rot(tup, deg):
rad=deg*0.0174533
crot=cmath.exp(rad*1j)
rotpol=[]
i=0
while i < len(tup):
x=tup[i]
y=tup[i+1]
z=crot*complex(x,y)
rotpol.append(400+z.real)
rotpol.append(400+z.imag)
i=i+2
return rotpol
def poly_oval(x0,y0, x1,y1, steps=60, rotation=0):
"""return an oval as coordinates suitable for create_polygon"""
# x0,y0,x1,y1 are as create_oval
# rotation is in degrees anti-clockwise, convert to radians
rotation = rotation * math.pi / 180.0
# major and minor axes
a = (x1 - x0) / 2.0
b = (y1 - y0) / 2.0
# center
xc = x0 + a
yc = y0 + b
point_list = []
# create the oval as a list of points
for i in range(steps):
# Calculate the angle for this step
# 360 degrees == 2 pi radians
theta = (math.pi * 2) * (float(i) / steps)
x1 = a * math.cos(theta)
y1 = b * math.sin(theta)
# rotate x, y
x = (x1 * math.cos(rotation)) + (y1 * math.sin(rotation))
y = (y1 * math.cos(rotation)) - (x1 * math.sin(rotation))
point_list.append(round(x + xc))
point_list.append(round(y + yc))
return point_list
inp= input("We need an ellipse. One to fit in a 800*800 window. Give the size of it's axes separated by ','-s (ex: lx,ly)!\n")
inpu= inp.split(',')
lx=int(inpu[0])
ly=int(inpu[1])
x0=400-lx//2
x1=400+lx//2
y0=400-ly//2
y1=400+ly//2
deg= float(input("Let's rotate this ellipse! But how much, in degrees, should we?"))
pre=poly_oval(x0, y0, x1, y1)
post=poly_rot(poly_oval(x0, y0, x1, y1), deg)
root =Tk()
w = Canvas(root, width=801, height=801)
w.config(background="dark green")
w.pack()
w.create_polygon(tuple(post), fill="yellow", outline="yellow" )
root.mainloop()
A regular polygon with N vertices. The lower side of the polygon is parallel to x axis. Given two point (x1, y1) and (x2, y2) if we draw a line through these points then the line would be parallel to the x axis. That means the lower side of the polygon is given. How to find the other n - 2 points. Each point could have floating value but it is grantee that x1, y1, x2, y2 is integer.
As example if N = 5 and (x1, y1) = (0, 0) and (x2, y2) = (5, 0)
I have to find these remaining 3 points (6.545085, 4.755283), (2.500000, 7.694209), (-1.545085 4.755283)
I am trying with vector rotation, but can't figure out any solution. How can I calculate ?
Given points x1, y1, x2, y2, number N.
Middle point of this edge is
xm = (x1 + x2) / 2
ym = y1
The center of polygon has coordinates
xc = xm
yc = y1 + Abs(x1 - x2)/2 * Ctg(Pi/N)
Radius of circumcircle is (Edit: 0.5 coefficient was missed)
R = 0.5 * Abs(x1 - x2) / Sin(Pi/N)
Kth (k=3..N) vertice of polygon has coordinates
xk = xc + R * Cos(-Pi/2 + Pi/N + (k - 2) * 2 * Pi/ N)
yk = yc + R * Sin(-Pi/2 + Pi/N + (k - 2) * 2 * Pi/ N)