Move base coordinates Tkinter - python

I want to move the coordinates on a tkinter canvas so that the bottom left corner is (0, 0), meaning that the top right corner is (height, width).
How would I do this?

Simplest way is to write a function that inverts your vertical coordinate, given the canvas height and desired element height passed in.

You can't. You'll have to do math on all of your coordinates to translate them from one coordinate system to another.

Related

How Can I Find the Area/Vertices Occupied By a Widget in Kivy?

I have a 10 x 10 GridLayout with 100 Image widgets, and on_touch_down, I want the picture that was touched to change to a different picture. Since the touch signal will bubble through GridLayout and all its 100 Image children, I want to do a check in on_touch_down to see if the touch coordinates are within the area occupied by the Image that was touched. How can I find the vertices of the Image, or is there an alternative to my approach? Calculating each Image's four vertices as they are added would be rather difficult since I am stretching these Images.
Many thanks in advance. :)
self.pos and self.size would have sufficed. How silly of me.
The collide_point method looks to be well suited for this.
For example:
def on_touch_down(self, touch):
x, y = touch
for child in self.children():
if child.collide_point(x, y):
do_something
From the docs:
Check if a point (x, y) is inside the widget's axis aligned bounding
box.
:Parameters:
`x`: numeric
X position of the point (in window coordinates)
`y`: numeric
Y position of the point (in window coordinates)
:Returns:
bool, True if the point is inside the bounding box.
..
>>> Widget(pos=(10, 10), size=(50, 50)).collide_point(40, 40)
True

How can I convert coordinate in tkinter?

I already tried to google it but I couldn't find anything ...
I created tkinter canvas with width 800, height 600
apparently, the left upside will be (0,0)
I want to change left downside to (0,0)
How can I do this???
You cannot change the coordinate system of the canvas. You can scroll the canvas so that 0,0 is in the bottom left, but the y coordinates will be negative going up.
In order to do that, you have to define your own function. Such:
def conv( coordinatePair ):
return { "x":coordinatePair["x"], "y":canvas.height-coordinatePair["y"]}
Where coordinatePair is a dictionary. That function will take your coordinate, flip the y, and return a new coordinate dictionary.

Pygame, rotating images by axis

Im trying to rotate a loaded image but I need it rotated by a specific axis.
I was doing this:
arm = pygame.image.load('w1.png').convert()
arms = [pygame.transform.rotate(arm, deg) for deg in range(0, 360, 4)]
I was then iterating through the indicies of arms with:
count+=1
arms[count]
The rotation does work but it is not rotating on the axis properly. I have written algorithms that rotate lines made with pygame.draw.line but I do not know how to achieve this with an image.
Any and all insight appreciated,
thanks
After rotating your image, and before blitting, get the new rect for the image, and change the positional attributes of the rect back to the original position.
IE: save rect center, rotate image, get new rect, set newrect center, blit.
Using the center attribute with only rotate it around the center of the image, but maybe using one of the corners will put you on the right path.
def RESET_ROTATED_RECT(old_rect,rotated_image):
old_pos=old_rect.center
newrect=rotated_image.get_rect()
newrect.center=old_pos
return newrect
I use the center often, but haven't used the other positions. It may be worth tinkering with.

Python/Pygame: Drawing graph origin mathematically?

I am working on a graphing program that I am calling PyGraph.
It allows you to create a graph of any size and draw on it, and later in development I will provide coordinates and things, but for now I have one question: How can I draw a intersecting lines through the center to represent the origin?
Here is what I have so far:
#pygraph
import pygame
from pygame.locals import *
pygame.init()
screen=pygame.display.set_mode((640,480))
x=0
y=0
size=16
screen.fill((255,255,255))
pygame.draw.line(screen, (0,0,0), (screen.get_width()/2,0),(screen.get_width()/2,screen.get_height()),5)
pygame.draw.line(screen, (0,0,0), (0,screen.get_height()/2),(screen.get_width(),screen.get_height()/2),5)
while True:
while y<480:
pygame.draw.rect(screen,(0,0,0),(x,y,size,size),1)
if x>640:
x=0
y+=size
pygame.draw.rect(screen,(0,0,0),(x,y,size,size),1)
x+=size
for e in pygame.event.get():
if e.type==QUIT:
exit()
if e.type==KEYUP:
if e.key==K_SPACE:
x=0
y=0
screen.fill((255,255,255))
pygame.draw.line(screen, (0,0,0), (screen.get_width()/2,0),(screen.get_width()/2,screen.get_height()),5)
pygame.draw.line(screen, (0,0,0), (0,screen.get_height()/2),(screen.get_width(),screen.get_height()/2),5)
size=input('Enter size: ')
pygame.display.flip()
The lines go though the center, but it doesn't work for every size graph. I'm not the best at math, but I hope this isn't obvious.. any advice?
The problem is that you draw the grid using the top left corner as your anchor. That is, all your grid rectangles have one corner in the top left. This becomes a problem when the distance between the center line and the screen edge is not divisible by the size - you can't divide a line of 640 units into even divisions of 15, for example.
A far better solution would be to use the center as the anchor. So basically, all the grid rectangles have one corner in the center of the graph, which means you will never get any "remainder" on the center line, and the "remainder" will instead be on the border of the graph, which looks much nicer.
Here is code for anchoring your rectangles at the center (should replace your original while y<480 loop):
while y<=480/2+size:
pygame.draw.rect(screen,(0,0,0),(640/2+x, 480/2+y,size,size),1)
pygame.draw.rect(screen,(0,0,0),(640/2-x, 480/2+y,size,size),1)
pygame.draw.rect(screen,(0,0,0),(640/2+x, 480/2-y,size,size),1)
pygame.draw.rect(screen,(0,0,0),(640/2-x, 480/2-y,size,size),1)
x+=size
if x>=640/2+size:
x=0
y+=size
Brief explanation:
I change the anchor of the rectangle (the point you pass into pygame.draw.rect) to the center of the graph, and instead of drawing one rectangle, I draw four - one in each quadrant of the graph.
I also fixed the code a bit to not need to call pygame.draw.rect() in the if statement.
A minor style tip:
Replace 480 and 640 with "screen.width" and "screen.height", so you can adjust the width and height later without problems.

How to make rect from the intersection of two?

I'm working on a breakout clone and I've been trying to figure out how to get the intersection rect of two colliding rects so I can measure how deep the ball entered the block in both x and y axis and decide which component of the velocity I'll reverse.
I figured I could calculate the depth for each case like this:
But if I had the intersection rect than I woudn't have to worry if the ball hits the block from the left/right or top/bottom (since I would be only reversing the x and y axis respectively), thus saving me a lot of typing.
I've looked on Pygame's docs but seems it doesn't have a function for that. How would I go about solving this problem?
Assuming you have rectangles r1 and r2, with .left, .right, .top, and .bottom edges, then
left = max(r1.left, r2.left);
right = min(r1.right, r2.right);
top = max(r1.top, r2.top);
bottom = min(r1.bottom, r2.bottom);
(with the usual convention that coordinates increase top to bottom and left to right). Finally, check that left<right and top<bottom, and compute the area:
Area = (right - left) * (top - bottom);
Alternatively, you can use the clip() function. From the docs you linked in your question:
clip(Rect) -> Rect Returns a new rectangle that is cropped to be
completely inside the argument Rect. If the two rectangles do not
overlap to begin with, a Rect with 0 size is returned.

Categories

Resources