-2

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?

TheDasher
  • 31
  • 6
  • 1
    What other will *scale* do than multiply the digits by a given amount? Why dont you do that in the first place and on your own? Therefor, where is your code and your honest attempt to solve this by yourself? – Thingamabobs Nov 06 '21 at 01:30
  • one approach you can use is to normalize your points to the size of your viewbox, [here](https://stackoverflow.com/a/1735122/7540911) is a way to do the normalization – Nullman Nov 06 '21 at 01:33
  • Does this answer your question? [How do I scale tkinter canvas window without changing objects](https://stackoverflow.com/questions/32900061/how-do-i-scale-tkinter-canvas-window-without-changing-objects) – user202729 Nov 06 '21 at 01:36
  • @user202729 thanks for the link, but turns out there's not much I can do about this problem. – TheDasher Nov 06 '21 at 02:14
  • Can you post a sample of the points? – Reblochon Masque Nov 06 '21 at 02:45
  • I don't understand why the `scale` command of the canvas won't solve your problem. Once you draw the data on the screen, it only changes the coordinates used by the canvas, it doesn't change your original data. – Bryan Oakley Nov 06 '21 at 05:13
  • @BryanOakley Now I'm confused, I got linked to another similar question by user202729 and on that post, the `scale` method was mentioned by someone but they also said that it actually modifies the values if I didn't read that incorrectly, and I don't want that to happen. – TheDasher Nov 06 '21 at 05:37

1 Answers1

3

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!)

Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80