Home > Software engineering >  Any way to scale up points (x, y) in Python tkinter gui?
Any way to scale up points (x, y) in Python tkinter gui?

Time:11-06

I am working on the TSP problem and reading some points from a file (have to use the points I'm given) and want to plot the points on to a GUI. But the problem is that the points are all only 2 digit and when I plot them using the tkinter.Canvas(), they all look really smudged up and tiny, almost like they're overlapping on top of each other.

Like this:

enter image description here

I got the problem working but just want to use this GUI to show it working instead of outputting it all to the console but can't cause it just looks stupid even worse when the lines are being drawn. So is there some way I can scale up that canvas or modify the points some way to make them look better. Can I do really anything or am I just stuck throwing it all to the console?

CodePudding user response:

Given nodes values centered at (0, 0) in any coordinate system, you need to manipulate the given coordinates to comply to what your screen and canvas needs to properly render the drawing

You can rescale your points by a scalar factor, then translate the origin to the center of the screen (or at any location for that matter), in order to visualize them more easily:

Maybe like this:

enter image description here

import tkinter as tk

WIDTH = 600
HEIGHT = 400

given_nodes = ((-1, -1), (-1, 1), (1, 1), (1, -1), (0, -1.5))
scale = 100
scaled_nodes = [(x * scale, y * scale) for x, y in given_nodes]
translated_to_center_nodes = [(x   WIDTH/2, y   HEIGHT/2) for x, y in scaled_nodes]

app = tk.Tk()
canvas = tk.Canvas(app, width=WIDTH, height=HEIGHT, bg='cyan')
canvas.pack()

# Draw connecting lines
line_nodes = translated_to_center_nodes   [translated_to_center_nodes[0]]
for idx, node in enumerate(line_nodes[:-1]):
    x0, y0 = node
    x1, y1 = line_nodes[idx 1]
    canvas.create_line(x0, y0, x1, y1, fill='black')

# draw nodes
for node in translated_to_center_nodes:
    x, y = node
    dx, dy = 2, 2
    canvas.create_oval(x-dx, y dy, x dx, y-dy, fill='white')

# draw origin & coordinate system at rescaled drawing scale
canvas.create_line(0, 0, 0   scale, 0, width=9, fill='blue', arrow=tk.LAST)
canvas.create_line(0, 0, 0, scale, width=9, fill='blue', arrow=tk.LAST)
canvas.create_text(40, 40, text='SCALED\nCANVAS\nORIGIN')

# draw moved origin & coordinate system at rescaled drawing scale
canvas.create_line(0, HEIGHT/2, WIDTH, HEIGHT/2, fill='black', dash=(1, 3))
canvas.create_line(WIDTH/2, HEIGHT/2, WIDTH/2   scale, HEIGHT/2, width=3, fill='black', arrow=tk.LAST)
canvas.create_line(WIDTH/2, 0, WIDTH/2, HEIGHT, fill='black', dash=(1, 3))
canvas.create_line(WIDTH/2, HEIGHT/2, WIDTH/2, HEIGHT/2   scale, width=3, fill='black', arrow=tk.LAST)

canvas.create_text(WIDTH/2, HEIGHT/2, text='MOVED\nORIGIN')

if __name__ == '__main__':

    app.mainloop()

This is commonly done with matrix multiplication and homogeneous coordinates (look it up), but the machinery needed to demonstrate a simple example is a little too heavy. The process of using the coordinates of an object and drawing it at scale, at the proper place, maybe rotated of skewed is called instantiation (look it up too!)

  • Related