-
Notifications
You must be signed in to change notification settings - Fork 1
Lines & Curved Lines!
The line class helps you draw straight line segments very simply just like this:
from goopylib.objects.Line import Line # To only import the Line object
from goopylib.objects.imports import * # Import all the basic objects & classes required to make an application/game
window = GraphWin("Creating a line!", width=800, height=800, autoflush=False)
line_example = Line(Point(200, 200), Point(500, 300)).draw(window) # This should create a simple straight line between the 2 coordinates
while True:
window.update_win()
Lines can also be given more than 2 coordinates like this:
l = Line(Point(100, 400), Point(300, 200), Point(700, 400)).draw(window)
There are a few arguments which you can customize in the Line object and here they are listed with what type the argument expects in brackets.
-
outline
- The colour of the line, see Colours in Goopy! (Colour
) -
outline_width
- The width of the line in pixels (int
) -
arrow
- The line can have an arrow on the front, back, or both sides. This parameter must be one ofNone
(or'none'
),'both'
,'first'
,'last'
(string
orNone
)
Just as an example, here is the code used to create the image above:
from goopylib.imports import *
window = GraphWin("Test Window", width=800, height=800, autoflush=False)
Line(Point(100, 100), Point(400, 100), outline=BLACK).draw(window)
Line(Point(100, 150), Point(400, 150), outline=BLACK, arrow="first").draw(window)
Line(Point(100, 200), Point(400, 200), outline=BLACK, arrow="last").draw(window)
Line(Point(100, 250), Point(400, 250), outline=BLACK, arrow="both").draw(window)
Text(Point(250, 115), "No Arrow - 'none'", font_size=10).draw(window)
Text(Point(250, 165), "No Arrow - 'first'", font_size=10).draw(window)
Text(Point(250, 215), "No Arrow - 'last'", font_size=10).draw(window)
Text(Point(250, 265), "No Arrow - 'both'", font_size=10).draw(window)
while True:
window.update_win()
-
arrow_shape
- This defines the shape of the arrow (defaults to(8, 10, 3)
) in the form(d1, d2, d3)
(tuple
orlist
)
from anzeljg.github.io/rin2/book2/2405/docs/tkinter/create_line
-
arrow_scale
- This is0.5
by default and controls how the arrow on the line scales as the width of the line increases. If it is0.5
, the shape of the arrow will be scaled by0.5 * outline_width
. If this is0
, the arrow won't scale with the width. (int
orfloat
) -
capstyle
- This defines how the line looks at the start & end. This must be one ofround
,butt
, orprojecting
. (string
) -
joinstyle
- This defines how the line joins with other segments. This must be one ofround
,bevel
, ormiter
. (string
)
-
cursor
- What cursor should be shown when the mouse hovers over the Line? see Cursors in Goopy -
dash
- You can change this to change whether or not the line is dotted or solid. The values can be one ofsolid
,dash
,long dash
,dot
,dashdot
, orlong dashdot
or it can be a tuple as detailed here anzeljg.github.io/rin2/book2/2405/docs/tkinter/dash-patterns.
dash=(5, 1, 2, 1) and dashoff=3, the first pattern produced will be: 2 on, 1 off, 2 on, and 1 off. Subsequent patterns will be 5 on, 1 off, 2 on, and 1 off.
-
style
- This is a string referencing a config style (string
) -
bounds_width
- This dictates the thickness of the bounding box of the line, see the paragraph on clickable lines for more.
-
is_clicked(mouse_pos)
- Checks if the line has been clicked given aPoint()
object.
Clickable Lines: Lines are a very unique object because of their ability to twist and turn and the fact that they might only be a few pixels thick. The latter may become a large problem if you are working with the is_clicked()
function as the user might get frustrated due to the seeming inability to click a line just a few pixels wide.
For this reason, the bounds_width
argument is very important. By setting this argument to a higher number (say about 20 or so), the user gets more room to click the Line. That is, this argument widens the bounding box without effecting how the line looks.
-
get_anchor()
- Returns the center of the Line -
get_size()
- Returns the size (width, height
) of the line get_width()
get_height()
get_outline_width()
get_fill()
get_arrow()
get_outline()
get_cursor()
get_capstyle()
get_joinstyle()
get_arrow_shape()
get_bounds_width()
The inputs to these functions is the same as that as the __init__
function.
set_arrow(option)
remove_arrows()
set_arrow_both()
set_arrow_first()
set_arrow_last()
set_outline(outline)
-
set_outline_width(outline_width)
8set_capstyle(style)
set_joinstyle(style)
-
set_arrow_shape(shape, scale=True)
- If scale isTrue
, the arrow of the line scales with its width, ifFalse
, its size stays constant. set_dash(dash)
set_bounds_width(width)
The curved line class is almost identical to the Line class - in fact, it is a subclass of the Line class. The only major difference with the curved line object is well... its ability to be curved. Here is how you would create a curved line:
from goopylib.objects.CurvedLine import CurvedLine # To only import the Curved Line object
from goopylib.objects.imports import * # Import all the basic objects & classes required to make an application/game
window = GraphWin("Creating a curved line!", width=800, height=800, autoflush=False)
line = CurvedLine(Point(100, 400), Point(400, 100), Point(700, 400), resolution=10, interpolation="cubic").draw(window)
while True:
window.update_win()
You will notice we provided it an argument called resolution
, & interpolation
. The resolution
argument dictates how 'close' the curved line is to the interpolation provided. Essentially, a curved line is created by taking the coordinates of the normal line, and interpolating between them resolution
times. The algorithm used to interpolate is defined by the interpolation
parameter which can be any one of linear
, cosine
(default), cubic
, hermit
, or spline
.
As the resolution
increases, the more accurate the line gets to the actual curved line and the better bounding-box it has. I find a resolution of at least 3
is required and nothing more than 10
may be needed.
You can see here a comparison between the different interpolation techniques.
- 'linear' - Red
- 'cosine' - Blue
- 'cubic' - Violet
- 'spline' - Green
And here is the code used for this example:
from goopylib.imports import *
window = GraphWin("Test Window", width=800, height=800, autoflush=False)
CurvedLine(Point(100, 400), Point(400, 100), Point(700, 400), resolution=10, outline=RED, interpolation="linear").draw(window)
CurvedLine(Point(100, 400), Point(400, 100), Point(700, 400), resolution=10, outline=BLUE, interpolation="cosine").draw(window)
CurvedLine(Point(100, 400), Point(400, 100), Point(700, 400), resolution=10, outline=VIOLET, interpolation="cubic").draw(window)
CurvedLine(Point(100, 400), Point(400, 100), Point(700, 400), resolution=10, outline=GREEN, interpolation="spline").draw(window)
while True:
window.update_win()
Here is a comparison of using different resolutions with the lines. One thing to note is that even though these lines may looks very similar (resolution > 3 especially), they might not function properly with the is_clicked()
function and you may not be able to detect certain clicks. For this purpose, a resolution above 5 is recommended (10 if possible).
The code used for the above is:
from goopylib.imports import *
window = GraphWin("Test Window", width=800, height=800, autoflush=False)
x = 10
colour_grad1 = ColourGradient(LIGHTER_GREEN, DARKEST_GREEN, divisions=x)
colour_grad2 = ColourGradient(LIGHTER_BLUE, DARKEST_BLUE, divisions=x)
colour_grad3 = ColourGradient(LIGHTER_PURPLE, DARKEST_PURPLE, divisions=x)
points = [Point(50, 400), Point(150, 200), Point(200, 600), Point(400, 100), Point(500, 200), Point(700, 700)]
for p in points: # Drawing the Points
Circle(p, 5, fill=VIOLET, outline_width=0).draw(window)
for i in range(x):
CurvedLine(*points, interpolation="spline", resolution=i, outline=colour_grad1[i]).draw(window)
CurvedLine(*points, interpolation="cosine", resolution=i, outline=colour_grad2[i]).draw(window)
CurvedLine(*points, interpolation="cubic", resolution=i, outline=colour_grad3[i]).draw(window)
while True:
window.update_win()
Now you may notice that my graph doesn't contain a line with the Hermite interpolation and this is because this is slightly different. If you use the Hermite interpolation, you CAN (not required) supply 2 other variables: bias
(default 0
) and tension
(default 1
) which also dictate how the curve looks.
Feel free to use this library in any of your projects and let me know about them!
Contact Author: bhavyemathur@gmail.com