0

Thanks for taking a look at my question.

So I want to know if you can rotate a canvas object from an anchor point. For example, a square is at 0,100 and the anchor point is at 0,0, then the square rotates from the anchor point. If you got a way to do that please also explain how it works and why, I would appreciate that.

  • Does this answer your question? [Rotating a Square on Tkinter Canvas](https://stackoverflow.com/questions/36620766/rotating-a-square-on-tkinter-canvas). You can implement something similar in your code. – TheLizzard Jun 05 '21 at 18:58
  • @willywillycow there are some points to understand. The first is, you cant use the built in command `create_rectangle` for this. Because all 4 points needs to be adjusted while the built in gives you two. The math behind uses *simply* the [trigonometric function](https://en.wikipedia.org/wiki/Trigonometric_functions) also note that if you want to rotate from a point, like the middle you need to *translate*. You could either achive this by calculating the point or by setting thr oringin of canvas in the middle, means use the scrollregion for. – Thingamabobs Jun 05 '21 at 19:12
  • Also see my answer to [How to rotate a polygon?](https://stackoverflow.com/questions/45508202/how-to-rotate-a-polygon) – martineau Jun 05 '21 at 19:15
  • @willywillycow can you show me your code? – Thingamabobs Jun 05 '21 at 19:41
  • @Atlas435 Sorry I cannot find the original file – willywillycow Jun 05 '21 at 20:15

1 Answers1

0

I highly recommand martineaus answer here

import tkinter as tk
import math
from itertools import islice

def draw_square(x,y,w,h):
    lu = (x,y)#left upper corner
    ru = (x+w,y)#right upper corner
    rb = (x+w,y+h)#right bottom corner
    lb = (x,y+h)#left bottom corner
    square = cnvs.create_polygon(lu,ru,rb,lb)
#using polygon for simple fill and getting the dots
    return square #return square_id

def pair_it(itr):#function to chunk list into x,y pairs
    itr = iter(itr)
    return iter(lambda:tuple(islice(itr,2)),())

def rotate_polygon(_id,angle):
    pns = cnvs.coords(_id)
    xy = list(pair_it(pns))
    mid_x=sum([p[0] for p in xy])/len(xy)#sumerize x and divide through len
    mid_y=sum([p[1] for p in xy])/len(xy)#sumerize y and divide through len
    # I was stealen it from martineau, since my bbox method failed
##    bbox = cnvs.bbox(square_id)
##    r1 = (bbox[2]-bbox[0])/2
##    r2 = (bbox[3]-bbox[1])/2
##    mid_x,mid_y=bbox[0]+r1,bbox[1]+r2
##    worked for an amount of rotations but messed up till it got stable again
    radians=angle*math.pi/180
    new_coords = []
    for edge in xy:
        edx,edy = edge[0]-mid_x,edge[1]-mid_y#here it "translates the surface" to mid point
        x = edx*math.cos(radians)-edy*math.sin(radians)+mid_x#here we translate back
        y = edx*math.sin(radians)+edy*math.cos(radians)+mid_y#here we translate back
        new_coords.extend((x,y))
    cnvs.coords(_id,new_coords)
    root.after(1,rotate_polygon,_id,angle)

root = tk.Tk()
cnvs = tk.Canvas(root)
square_I = draw_square(150,50, 100,200)
cnvs.itemconfig(square_I, fill='red')
root.bind('<Button-1>',lambda e:rotate_polygon(square_I,20))
cnvs.pack()

root.mainloop()
Thingamabobs
  • 4,666
  • 3
  • 8
  • 33