I'm making a simple 2d exploration game in replit (hoping to have a nice base for a future game I'm making) and I have all my map tiles as images
WATER = pygame.image.load(r'water.jpg')
SAND = pygame.image.load(r'sand.jpg')
GRASS = pygame.image.load(r'grass.jpg')
FOREST = pygame.image.load(r'Forest.jpg')
VILLAGE = pygame.image.load(r'village.jpg')
and I have my dictionary which compresses them into a single letter
TileMap = {'W': WATER, 'S': SAND, 'G': GRASS, 'F': FOREST, 'V': VILLAGE }
and I have my map which should usually come up with the image after the code:
map1 = ["WWWWWWWWWWWWWWWWWWWWWWW",
"WWWWWWWWWGGGWWWWWWWWWWW",
"WWWWWGGGGGGGGGGGWWWWWWW",
"WWWWGGGGGFFFGGGGGVWWWWW",
"WWWGGGGGFFFFFFGGGGGWWWW",
"WWWGGGGGGFFFFFGGGGGGWWW",
"WWGGGGGGGGGFFGGGGGGGWWW",
"WWGGGGGGGGGGGGGGGGGGGWW",
"WWGGGGGGSSSSSSSGGGGGGGW",
"WWGGGGSSSSSSSSSSGGGGGGW",
"WGGGGGGGSSGGGGGGGGGGGSW",
"WGGGGGGGGGGGGGGGGGGGSSW",
"WSGGGGGGGGFFGGGGGGGGSSW",
"WSSGGGGGGFFFGGGGGFFGGSW",
"WSSGGGGGFFFFFFGGFFFFFGW",
"WSGGGGFFFFFFFFFFFFFFGGW",
"WWGGGGGFFFFFFFFFFFFGGWW",
"WWGGGGGGGFFFFFFFFGGGWWW",
"WWWWGGGGGGGGFFGGGGGWWWW",
"WWWWWWSSSSSGGGGSSSWWWWW",
"WWWWWWWWWSSSSSSSSWWWWWW",
"WWWWWWWWWWWWWWSWWWWWWWW",
"WWWWWWWWWWWWWWWWWWWWWWW"
]
and I have a attempt at showing the images
pygame.image.load_basic(TileMap(map1))
and I get this error message:
pygame 2.1.2 (SDL 2.0.16, Python 3.8.12)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
File "main.py",line 74, in <module>
pygame.image,load_basic(TileMap(map1))
TypeError: 'dict' object is not callable
>>>
does anyone have any suggestions as to how to make this work?
here is the link to the replit code: my game
WATER, SAND, etc are already pygame.Surface objects. You do not need to load them again. Just blit the images:
# application loop
while run:
# [...]
for row in range(MAPHEIGHT):
for col in range(MAPWIDTH):
c = map1[row][col]
image = TileMap[c]
x = col * TILESIZE
y = row * TILESIZE
DISPLAY.blit(image, (x, y))
# [...]
(The code is based on the code in your previous question: how do you make the map more detailed?)
I'm relatively new to Python and I'm attempting to make a fun little project using Pyautogui and Python3.6. The goal of this project is to create a tensorflow powered project that learns to play chess. The problem I am now encountering is that whenever I try to use any of the pixel commands - e.g. pyautogui.pixel(...) or screenshot.getpixel(...) - an error pops up and says this:
Traceback (most recent call last):
File "main.py", line 109, in <module>
Score()
File "main.py", line 100, in Score
if gui.pixelMatchesColor(tempX, tempY, (87, 83, 82), tolerance=20):
File "/Users/student/Library/Python/3.6/lib/python/site-packages/pyscreeze/__init__.py", line 413, in pixelMatchesColor
pix = pixel(x, y)
File "/Users/student/Library/Python/3.6/lib/python/site-packages/pyscreeze/__init__.py", line 436, in pixel
return RGB(*screenshot().getpixel((x, y)))
TypeError: __new__() takes 4 positional arguments but 5 were given
I just want to note that all other commands work fine and that it's only the pixel ones that don't work.
I have installed everything including pyautogui(duh), pyscreeze, pymsgbox, pytweening, xlib, opencv, and any other package I could think of. These were installed using this command: pip3 install package-name-here --user. I needed the --user because I don't currently have administrator rights to my computer so I'm wondering if that could have something to do with my current predicament.
I also encountered an earlier post in my search for an answer but I forgot where I found it, so I'm sorry but I can't link it, but basically it said that I should go through and remove all pycache folders. I did this using the terminal command in the ~/Library/Python/3.6 folder:
find . -name "__pycache__" -type f -o -name "__pycache__" -type d -exec rm -rf {} \
I am in no need of an exact solution to this problem, but I'm wondering if there's some way to use the pyautogui.pixelMatchesColor(...) function or any similar one that you recommend that can have a tolerance - e.g. that the RGB values can be 10 units off and still return true.
For those of you that are interested, here is my full code:
#
# IMPORT ALL NECESSARY THINGS
#
import os, time, sys, pyautogui as gui, argparse as arg
#
# FAILSAFES
#
gui.FAILSAFE = True
gui.PAUSE = 0.1
#
# SET UP ARGUMENT PARSER
#
parser = arg.ArgumentParser(description='A machine learning script powered by TensorFlow designed to be run on "chess.com" using Python.')
parser.add_argument("-s", "--sleep", nargs='?', type=int, default='5', help='Number of seconds that the program should sleep before starting. This gives you time to move over to the website before the program looks for the gamboard on screen.')
args = parser.parse_args()
#
# ASKS USER FOR WHAT SIDE IT IS ON
#
side = input("Are you white or black? ")
if side == "W" or side == "w" or side == "white" or side == "White":
side = "W"
elif side == "B" or side == "b" or side == "black" or side == "Black":
side = "B"
else:
print("Invalid selection for which side!")
side = None
sys.exit(0)
#
# PRINT "READY" AND THEN WAIT FOR SPECIFIED AMOUNT OF TIME - DEFAULT 5 SECONDS
#
print("Ready! Waiting for " + str(args.sleep) + " seconds!")
time.sleep(int(args.sleep))
#
# GET AREA OF GAMEBOARD ON SCREEN
#
if side == "W":
gameboard = gui.locateOnScreen('./img/white/chessboard_white.png', confidence=0.55, grayscale=True)
left = gameboard.left - 10
top = gameboard.top - 5
right = gameboard.left + gameboard.width + 10
bottom = gameboard.top + gameboard.height + 15
elif side == "B":
gameboard = gui.locateOnScreen('./img/black/chessboard_black.png', confidence=0.55, grayscale=True)
left = gameboard.left - 10
top = gameboard.top - 5
right = gameboard.left + gameboard.width + 10
bottom = gameboard.top + gameboard.height + 15
widthInterval = (right - gameboard.left) / 8
heightInterval = (bottom - gameboard.top) / 8
#
# DEFINES A FUNCTION THAT COUNTS THE SCORE
# - NUMBER OF YOU SIDE AND THEN SUBTRACT THE NUMBER OF OPPOSITE SIDE
#
def Score():
for i in range(8):
for j in range(8):
tempX = 32 + (i * widthInterval)
tempY = 32 + (j * heightInterval)
if gui.pixelMatchesColor(tempX, tempY, (87, 83, 82), tolerance=20):
print("True!")
if side == "W":
print("White!")
elif side == "B":
print("Black!")
Score()
Note: The problem occurs in the last 10ish lines of the above code.
Thank you so much for your help and please don't hesitate to let me know if you need any more info from me!
Max
I'm trying visualise the sine waves addition in python using tkinter, and I'm trying to build lines between each circles center, but what I've tried so far didnt work as I thought it would. is there a way to fix what I've tried (see code), or a way to move only one coordinates point of a line independantly from the other?
As you'll see in the code if you run it, I've tried a method where each iteration the previous line is erased and a new one is created. When I run the code there is actually a line between each center of the circles just like I want, but facts are those lines persist and won't erase themselves; for some reason it seems like the canvas.delete(line) doesnt work as I expected it to.
here's the full code. The interesting part is in the 'updateline' fonction, into 'act()' func.
import math
import tkinter as tk
##important to know! -- the way I'm creating the circles is by setting an object, the bounds of the circle, depending on amplitude asked by user.
##then the programs calculates the path of these bounds, depending on circles, amplitude, phase and frequency of the sine waves asked by the user from the tkinter GUI.
##finally, the program creates and moves along this path a circle, representing visually the sine wave.
top = tk.Tk()
top.title('Superposition')
choice = tk.Tk()
choice.title('Parametres')
f = tk.Frame(choice,bd=3)
f.pack(side='top')
g = tk.Frame(choice,bd=3)
g.pack(side='bottom')
tk.Label(f,text="nbre ondes:",width = 10).grid(row=0,column=0)
sines = tk.Spinbox(f,from_=1,to=50,width=10,textvariable=tk.DoubleVar(value=2))
sines.grid(row=0,column=1)
sines.delete(0,5)
sines.insert(0,2)
delai = tk.Scale(g, orient='vertical', from_=100, to=1,resolution=1, length=100,label='delai')
delai.grid(row=0,column=0)
hauteur = tk.Scale(g, orient='vertical', from_=1100, to=100,resolution=100, length=100,label='fenetre')
hauteur.grid(row=0,column=1)
taillec1 = tk.Scale(g, orient='vertical', from_=3.5, to=0.1,resolution=0.1, length=100,label='taille')
taillec1.grid(row=0,column=2)
delai.set(20)
hauteur.set(600)
taillec1.set(1.5)
def grilledechoix():
numberofsines = int(sines.get())
for i in f.grid_slaves():
if int(i.grid_info()["row"]) > numberofsines+2:
i.grid_forget()
for i in range(1,numberofsines+1):
tk.Label(f,text="phase n."+str(i),width = 10).grid(row=i+2,column=4)
phase = tk.Spinbox(f,from_=-180,to=180,width=10)
phase.grid(row=i+2,column=5)
phase.delete(0,5)
phase.insert(0, 0)
for i in range(1,numberofsines+1):
tk.Label(f,text="amp. n."+str(i),width = 10).grid(row=i+2,column=0)
ampli = tk.Spinbox(f,from_=1,to=10000000,width=10)
ampli.grid(row=i+2,column=1)
ampli.delete(0,5)
ampli.insert(0,10)
for i in range(1,numberofsines+1):
tk.Label(f,text="freq n."+str(i),width = 10).grid(row=i+2,column=2)
freq = tk.Spinbox(f,from_=-1000,to=1000,width=10)
freq.grid(row=i+2,column=3)
freq.delete(0,5)
freq.insert(0,5)
def act():
h = g.grid_slaves()[1].get()
delai = g.grid_slaves()[2].get()
taillec1 = g.grid_slaves()[0].get()
w = h
ampdict = {'box1':100 * ((h/700)*taillec1)}
frqdict = {}
aaadict = {}
fffdict = {}
phadict = {}
numberofsines = int(sines.get())
sin = lambda degs: math.sin(math.radians(degs))
cos = lambda degs: math.cos(math.radians(degs))
for i in range(1,numberofsines+1):
fffdict['box'+str(numberofsines-i+1)] = f.grid_slaves()[(2*i)-2].get()
aaadict['box'+str(numberofsines-i+1)] = f.grid_slaves()[(2*i)-2+2*numberofsines].get()
phadict['box'+str(numberofsines-i+1)] = f.grid_slaves()[(2*i)-2+4*numberofsines].get()
for i in range(1,numberofsines+1):
ampdict['box'+str(i)] = (float(ampdict['box1'])/float(aaadict['box1'])) * float(aaadict['box'+str(i)])
frqdict['box'+str(i)] = float(fffdict['box'+str(i)])/float(fffdict['box1'])
class obj(object):
cos0, cos180 = cos(0), cos(180)
sin90, sin270 = sin(90), sin(270)
def __init__(i, x, y, rayon):
i.x, i.y = x, y
i.rayon = rayon
def bounds(i):
return (i.x + i.rayon*i.cos0, i.y + i.rayon*i.sin270,
i.x + i.rayon*i.cos180, i.y + i.rayon*i.sin90)
def updateposition(canvas, id, cent, obj, path):
obj.x, obj.y = next(path)
x0, y0, x1, y1 = canvas.coords(id)
oldx, oldy = (x0+x1) // 2, (y0+y1) // 2
dx, dy = obj.x - oldx, obj.y - oldy
canvas.move(id, dx, dy)
canvas.move(cent, dx, dy)
canvas.after(delai, updateposition, canvas, id, cent, obj, path)
def updateline(canvas, line, robj0, cent0, robj1, cent1):
x00, y00, x01, y01 = canvas.coords(cent0) ##defining coords of the two ovals asked, representing centers of circles
x10, y10, x11, y11 = canvas.coords(cent1)
oldx0, oldy0 = (x00+x01) // 2, (y00+y01) // 2 ##defining center coords of the two ovals
oldx1, oldy1 = (x10+x11) // 2, (y10+y11) // 2
dx0, dy0 = robj0.x - oldx0, robj0.y - oldy0 ##defining the deltax and deltay, difference of movements between frames, of the two ovals
dx1, dy1 = robj1.x - oldx1, robj1.y - oldy1
canvas.after(delai, canvas.delete, line) ##deleting previous line, does not work and I don't know why. I've also tried 'canvas.delete(line)', giving same results
canvas.create_line(oldx0+dx0, oldy0+dy0, oldx1+dx1, oldy1+dy1) ##creating new line
canvas.after(delai, updateline, canvas, line, robj0, cent0, robj1, cent1) ##function invoking itself after delay 'delai'
def posobj(pt,ang,deltang):
while True:
yield pt.x + pt.rayon*cos(ang), pt.y + pt.rayon*sin(ang)
ang = (ang+deltang)%360
try:
top.pack_slaves()[0].destroy()
except:
pass
canvas = tk.Canvas(top, bg='white', height=h, width=w)
canvas.pack(side='right')
robj = {}
r = {}
posobjet = {}
line = {}
cent = {}
## the following 'for' loop creates a number of circles corresponding to sine waves, as much as the user asked.
for i in range(1,int(sines.get())+2):
if i != int(sines.get())+1:
if i == 1:
robj[str(i)] = obj(h/2,h/2,float(ampdict['box'+str(i)]))
r[str(i)] = canvas.create_oval(robj[str(i)].bounds(),fill='',outline='black')
cent[str(i)] = canvas.create_oval(h/2+h/200,h/2+h/200.,h/2-h/200,h/2-h/200, fill='white', outline='red')
posobjet[str(i)] = posobj(robj[str(i)],float(phadict['box'+str(i)]),float(frqdict['box'+str(i)]))
else:
robj[str(i)] = obj(robj[str(i-1)].x,robj[str(i-1)].y,float(ampdict['box'+str(i)]))
r[str(i)] = canvas.create_oval(robj[str(i)].bounds(),fill='',outline='black')
cent[str(i)] = canvas.create_oval(robj[str(i)].x+h/200,robj[str(i)].y+h/200,robj[str(i)].x-h/200,robj[str(i)].y-h/200, fill='white', outline='blue')
line[str(i)] = canvas.create_line(0,0,0,0)
posobjet[str(i)] = posobj(robj[str(i)],float(phadict['box'+str(i)]),float(frqdict['box'+str(i)]))
top.after(delai, updateposition, canvas, r[str(i)], cent[str(i)], robj[str(i)], posobjet[str(i-1)])
##here I'm invoking the updateline function using the constant 'delai', the line i, and objects defining the bounds of the center objects, the little blue/red dots appearing as the center of each circles(run the code, it'll be easier to understand)
top.after(delai, updateline, canvas, line[str(i)], robj[str(i-1)], cent[str(i-1)], robj[str(i)], cent[str(i)])
else:
robj[str(i)] = obj(robj[str(i-1)].x,robj[str(i-1)].y,h/200)
r[str(i)] = canvas.create_oval(robj[str(i)].bounds(),fill='white',outline='red')
cent[str(i)] = canvas.create_oval(robj[str(i)].x+h/200,robj[str(i)].y+h/200,robj[str(i)].x-h/200,robj[str(i)].y-h/200, fill='white', outline='red')
line[str(i)] = canvas.create_line(0,0,0,0)
top.after(delai, updateposition, canvas, r[str(i)], cent[str(i)], robj[str(i)], posobjet[str(i-1)])
##2nd and last time invoking the updateline function, for the line between the last circle's point and the final red point.
top.after(delai, updateline, canvas, line[str(i)], robj[str(i-1)], cent[str(i-1)], robj[str(i)], cent[str(i)])
top.mainloop()
ok = tk.Button(f,text='NBRE',command=grilledechoix)
ok.grid(row=0,column=2)
ac = tk.Button(f,text='APPLY',command=act)
ac.grid(row=0,column=3)
grilledechoix()
act()
I expected the lines to disappear once the updateline function called itself again, because of that 'canvas.delete(line)' line into updateline, and I can't really understand why it does that.
anyway if you have a solution to make the lines move, without creating and deleting them each time the function is called, feel free to tell me.
Thanks!
If I understand the problem correctly, I believe the issue is with this code:
canvas.after(delai, canvas.delete, line)
canvas.create_line(oldx0+dx0, oldy0+dy0, oldx1+dx1, oldy1+dy1)
canvas.after(delai, updateline, canvas, line, robj0, cent0, robj1, cent1)
It fails to reassign the new line to the line variable for the next call. Instead try:
canvas.after(delai, canvas.delete, line)
line = canvas.create_line(oldx0+dx0, oldy0+dy0, oldx1+dx1, oldy1+dy1)
canvas.after(delai, updateline, canvas, line, robj0, cent0, robj1, cent1)
Which gets rid of the extra lines when I run it. Let me know if I've missed the point.
I have a red pixeled image and i wanted another image to be blitted at the red pixel, so I did this code:
import sys, pygame
pygame.init()
from pygame.locals import *
import time
#the function with get at
def colorscan(rect):
red = ( 255 , 0 , 0 , 255 )
for x in range(rect[0],rect[0]+rect[2]+1):
for y in range(rect[1],rect[1]+rect[3]+1):
print(x,y)
if tuple(screen.get_at((x,y)))==red:
print(x,y,"done")
return (x,y)
def load(path):
x = pygame.image.load(path)
return x
beam = load("menu/beam.png")
w_plat = load("menu/w_plat.png")
videoinfo = pygame.display.Info()
fullscreen = pygame.FULLSCREEN
screen = pygame.display.set_mode((videoinfo.current_w,videoinfo.current_h), fullscreen, 32)
time = pygame.time.Clock()
#main loop
while True:
beamrect = screen.blit(beam,(0,0))
xtl,ytl=beamrect.topleft
w_pos=colorscan( (xtl,ytl,35,+35) )
screen.blit(w_plat, w_pos)
my code is too large so i just wrote here what's important. Anyways, when i run it I get this error:
Traceback (most recent call last):
File "C:\Users\André Luiz\Desktop\Equilibrium\Equilibrium.py", line 171, in
screen.blit(w_plat, w_pos)
TypeError: invalid destination position for blit
after checking, printing w_pos returned "None", but I'm sure the red pixel has been ""scanned"".
I think what happens is that either your for loops are broken
for x in range(rect[0],rect[0]+rect[2]+1):
for y in range(rect[1],rect[1]+rect[3]+1):
by not executing, or the if statement is not executed because its conditions are not met:
if tuple(screen.get_at((x,y)))==red: (eg: not executed if != red)
because it's the only location you return a value. Otherwise when a function is not specified a return value, it returns None.
colorscan() has no default return value, this is why you get a None.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I want to draw a triangle like this:
I have tried different ways of solving it, but I have not done it correctly. How to add median lines in the triangle? Could someone please help and explain this to me?
from turtle import *
import random
def allTriMedian (w=300):
speed (0)
vertices = []
point = turtle.Point(x,y)
for i in range (3):
x = random.randint(0,300)
y = random.randint(0,300)
vertices.append(trutle.Point(x,y))
point = turtle.Point(x,y)
triangle = turtle.Polygon(vertices)
a = triangle.side()
b = triangle.side()
c = triangle.side()
m1 = tirangle.median
m2 = triangle.median
m3 = triangle.median
I tried to put the equation directly
def Median (a, b, c):
m1 = sqrt((((2b^2)+(2c^2)-(a^2))))
m2 = sqrt((((2a^2)+(2c^2)-(b^2))))
m3 = sqrt((((2a^2)+(2b^2)-(c^2))))
triangle.setFill("yellow")
triangle.draw(allTriMedian)
Or I thought to find a midpoint and draw a line segment to connect the vertices and midpoints.
def getMid(p1,p2):
return ( (p1[0]+p2[0]) / 2, (p1[1] + p2[1]))
mid1 = Line((point(p1[0]+p2[0]) / 2),point(x))
mid2 = Line((point(p2[1]+p3[1]) / 2),point(y))
I hate doing math. Let's see if we can solve this by throwing turtles at the problem. Lots of turtles.
We'll randomly generate the verticies of the triangle. Taking pairs of verticies in turn, we'll start a turtle at each heading toward the other. When the turtles collide (at the midpoint), we'll eliminate one turtle and send the other toward the vertex not in the pair. Once we've done this three times (with six turtles), we should have the drawing in question. Well, mostly (no fill in my solution):
from turtle import Turtle, Screen
from random import seed, randint
WIDTH, HEIGHT = 640, 480
def meet_in_the_middle(turtle_1, turtle_2):
position_2 = turtle_2.position()
while True:
turtle_1.setheading(turtle_1.towards(turtle_2))
turtle_1.forward(1)
position_1 = turtle_1.position()
if int(position_1[0]) == int(position_2[0]) and int(position_1[1]) == int(position_2[1]):
break
turtle_2.setheading(turtle_2.towards(turtle_1))
turtle_2.forward(1)
position_2 = turtle_2.position()
if int(position_2[0]) == int(position_1[0]) and int(position_2[1]) == int(position_1[1]):
break
seed()
screen = Screen()
screen.setup(WIDTH * 1.25, HEIGHT * 1.25)
vertices = []
for _ in range(3):
x = randint(-WIDTH//2, WIDTH//2)
y = randint(-HEIGHT//2, HEIGHT//2)
vertices.append((x, y))
A, B, C = vertices
turtle_AtoB = Turtle(shape='turtle')
turtle_AtoB.penup()
turtle_AtoB.goto(A)
turtle_AtoB.pendown()
turtle_BtoA = Turtle(shape='turtle')
turtle_BtoA.penup()
turtle_BtoA.goto(B)
turtle_BtoA.pendown()
meet_in_the_middle(turtle_AtoB, turtle_BtoA)
turtle_BtoA.hideturtle()
turtle_AtoB.setheading(turtle_AtoB.towards(C))
turtle_AtoB.goto(C)
turtle_AtoB.hideturtle()
turtle_BtoC = Turtle(shape='turtle')
turtle_BtoC.penup()
turtle_BtoC.goto(B)
turtle_BtoC.pendown()
turtle_CtoB = Turtle(shape='turtle')
turtle_CtoB.penup()
turtle_CtoB.goto(C)
turtle_CtoB.pendown()
meet_in_the_middle(turtle_BtoC, turtle_CtoB)
turtle_CtoB.hideturtle()
turtle_BtoC.setheading(turtle_BtoC.towards(A))
turtle_BtoC.goto(A)
turtle_BtoC.hideturtle()
turtle_CtoA = Turtle(shape='turtle')
turtle_CtoA.penup()
turtle_CtoA.goto(C)
turtle_CtoA.pendown()
turtle_AtoC = Turtle(shape='turtle')
turtle_AtoC.penup()
turtle_AtoC.goto(A)
turtle_AtoC.pendown()
meet_in_the_middle(turtle_CtoA, turtle_AtoC)
turtle_AtoC.hideturtle()
turtle_CtoA.setheading(turtle_CtoA.towards(B))
turtle_CtoA.goto(B)
turtle_CtoA.hideturtle()
screen.exitonclick()
Turtles at work:
Finished drawing:
thanks to cdlane, I took his code and put some functionality into functions to make it a Little clearer (at least for me)
# -*- coding: cp1252 -*-
import turtle
from turtle import Turtle, Screen
from random import seed, randint
WIDTH, HEIGHT = 640, 480
def create_screen(width, height):
screen = Screen()
screen.setup(width * 1.25, height * 1.25)
return screen
def create_points(count,width = WIDTH, height = HEIGHT):
vertices = []
for _ in range(count):
x = randint(-width//2, width//2)
y = randint(-height//2, height//2)
vertices.append((x, y))
return vertices
def create_turtle_at_position(position):
turtle = Turtle(shape='turtle')
turtle.hideturtle()
turtle.penup()
turtle.goto(position)
turtle.showturtle()
turtle.pendown()
return turtle
def meet_in_the_middle(turtle_1, turtle_2):
position_2 = turtle_2.position()
while True:
turtle_1.setheading(turtle_1.towards(turtle_2))
turtle_1.forward(1)
position_1 = turtle_1.position()
if int(position_1[0]) == int(position_2[0]) and int(position_1[1]) == int(position_2[1]):
break
turtle_2.setheading(turtle_2.towards(turtle_1))
turtle_2.forward(1)
position_2 = turtle_2.position()
if int(position_2[0]) == int(position_1[0]) and int(position_2[1]) == int(position_1[1]):
break
turtle_1.hideturtle()
turtle_2.hideturtle()
return create_turtle_at_position(position_2)
def draw_median(P1st, P2nd, POpposite):
turtle_AtoB = create_turtle_at_position(P1st)
turtle_BtoA = create_turtle_at_position(P2nd)
turtle_AandBmiddle = meet_in_the_middle(turtle_AtoB, turtle_BtoA)
turtle_AandBmiddle.setheading(turtle_AandBmiddle.towards(POpposite))
turtle_AandBmiddle.goto(POpposite)
return turtle_AandBmiddle
seed()
sc = create_screen(WIDTH, HEIGHT)
for _ in range(5):
sc = create_screen(WIDTH, HEIGHT)
A, B, C = create_points(3)
draw_median(A,B,C)
draw_median(B,C,A)
draw_median(C,A,B)
sc.exitonclick()
mathematical it is the easiest way to calculate this by vector. Let me say you have a triangle ABC and want to draw a line from A to the middle of BC so your vector starts at A and ends on A + AB + 1/2 BC or A + AC + 1/2 CB (vectorial)
(ax) + (bx - ax) + 0.5 (cx - bx)
(ay) (by - ay) (cy - by)
that results in the coordinates for the opposite Point of
x = 0.5(cx + bx)
y = 0.5(cy + by)