Drawing the turtle module - turtle-graphics

from turtle import *
color('red', 'yellow')
begin_fill()
while True:
forward(200)
left(170)
if abs(pos()) < 1:
break
end_fill()
done()
I do not understand this part of the code. if abs(pos()) < 1: what does it mean?

This code draws a star with red lines & filled with yellow. The abs(pos()) < 1 statement is used to compare the current turtle location with the original starting turtle position after executing each iteration of the while statement. If the turtle position is less than 1 unit away, the while statement terminates and the end_fill() statement executes to complete the yellow color fill.
Comment out the if statement and watch what happens, also, experiment with different numbers in the abs(pos())<1 expression, including 10, 20, 30, etc. to see the effect.

abs(pos()) means absolute position. if abs(pos())<1: means you come back to starting point. Hope it clarifies to you.

Another option is to use 'if t.heading() == 0:'.
If my understanding isn't too incorrect,
when 'turtle.heading == 0' then the turtle is facing 'east',
the direction it started drawing from.
This has worked for all the angles I've tried so far.
Using 'if abs(pos()) < 1:' ...
I can only draw images at the origin (0,0).
(Maybe there's a way to draw images at
other locations using 'if abs(pos()) < 1:'
but I haven't figured out how.)
Using 'if t.heading() == 0:'
I can draw images anywhere on the screen.
import turtle
wn = turtle.Screen()
wn.title("Drawing Geometric Shapes")
t = turtle.Turtle()
t.color('red', 'yellow')
t.speed(0)
#=====================================
def star(x, y, length, angle):
t.penup()
t.goto(x, y)
t.pendown()
t.begin_fill()
while True:
t.forward(length)
t.left(angle)
if t.heading() == 0: #================
break
t.end_fill()
# ( x, y, length, angle)
star(-470, 300, 100, 120)
star( 360, 320, 100, 160)
star(-450, -340, 100, 100)
star( 360, -340, 100, 170)
star(-360, 0, 750, 178)
t.penup()
t.goto(-500, 0)

Related

Improve Lines Detection Using OpenCV

I have an image like
and I would like to detect most of the lines in the image. I am using HoughLines function in OpenCV.
The code looks like:
src_img = cv.imread("./snapshot_0711.png")
gray_img = cv.cvtColor(src_img, cv.COLOR_BGR2GRAY)
kernel_size = 5
blur_img = cv.GaussianBlur(gray_img, (kernel_size, kernel_size),0)
dst_img = cv.Canny(blur_img, 100, 250, None, 3)
cv.imshow("dt", dst_img)
lines = cv.HoughLines(dst_img, 1, np.pi * 1 / 180, 100, None, 0, 0)
It detected many lines, but the results (first case) is not satisfactory, like:
Is there anything doing wrong in my code? Will I need a preprocessing?
Using the LineSegmentDetector recommended by #Micka, the result looks like (second case):
I want to improve the first case. In the case output, is there way(s) connecting the small segments?
Thanks.

How can I make these horizontal zigzags go in the vertical direction in the turtle python sandbox?

I got placed in a coding class and I have no idea what I'm doing.
This is supposed to create a nametag for a project that I have to finish by tonight.
Please help me figure out how to make the horizontal zigzags vertical.
t.pensize(24)
def zig_zag_line(num_zig_zags):
zig_zag = 0
t.setheading(20)
while zig_zag < num_zig_zags:
t.forward(40)
t.right(40)
t.forward(40)
t.left(40)
zig_zag = zig_zag + 1
def write_name(id_name):
style = ('Times New Roman', 70, 'bold')
t.write(id_name, font=style, align='center')
def white_space():
t.color("white")
t.pensize(26)
for i in range(3):
t.pu()
t.goto(-260, i * 30)
t.pd()
zig_zag_line(7)
i = i + 30
color1 = input("What is color 1?: ")
color2 = input("What is color 2?: ")
color3 = input("What is color 3?: ")
for i in range(-30, 33, 3):
if i % 9 == 0:
t.color(color1)
elif i % 9 == 3:
t.color(color2)
else:
t.color(color3)
t.pu()
t.goto(-260, i * 10)
t.pd()
zig_zag_line(7)
white_space()
t.color("black")
t.pu()
t.goto(0, 5)
t.pd()
write_name("")
t.hideturtle()
I just want to change the direction in which the zigzags are going. If anyone knows how to help I would really appreciate because I know virtually nothing about how to code this. I've been trying to figure it out but I'm going solely off the notes I've taken in class and I can't seem to figure out just how to make it go from horizontal to vertical.
There are two things we need to do: first swap our sense of x and y:
t.goto(-260, i * 10)
becomes:
t.goto(i * 10, -260)
and change our initial heading:
t.setheading(20)
becomes:
t.setheading(20 + 90)
A rework of the zigzag lines part of your code to make them vertical:
import turtle as t
def zig_zag_line(num_zig_zags):
t.setheading(110)
for _ in range(num_zig_zags):
t.forward(40)
t.right(40)
t.forward(40)
t.left(40)
color1 = input("What is color 1? ")
color2 = input("What is color 2? ")
color3 = input("What is color 3? ")
width, height = t.window_width(), t.window_height()
t.setup(height, width) # swap window wide and high
t.pensize(24)
t.speed('fastest') # because I have no patience
for i in range(-30, 33, 3):
if i % 9 == 0:
t.color(color1)
elif i % 9 == 3:
t.color(color2)
else:
t.color(color3)
t.penup()
t.goto(i * 10, -260)
t.pendown()
zig_zag_line(7)
t.hideturtle()
t.exitonclick()
I've included an optional third fix which is to swap the width and height of the window itself. Since the window might be sized to fit the horizontal drawing, we need to change it to fit the vertical drawing.

Error main.lua:45: attempt to call global 'distanceFormula' (a nil value)

I keep getting this error, no matter what:
function love.load() -- love.load starts any command inthe beginning
--number = 0 (old code)
button = {}
button.x = 200
button.y = 200
button.size = 50
button.score = 0
button.time = 0
newFont = love.graphics.newFont(40)
end
end
function love.update(dt) -- changes code in delta time: every frame: love runs in 60 frames per second
--number = number + 1 (old code)
end
function love.draw() -- does anything on the screen
end
function love.draw()
--love.graphics.setColor(0, 0, 255, 5)
--love.graphics.rectangle("fill", 200, 400, 200, 100) --love.graphics.rectangle(mode, x, y, width, height) Y increases downwards;
-- width increases to the right and the height increases downward assuming positive numbers
love.graphics.setColor(255,0,0,5)
--love.graphics.print(number) (old code)
--love.graphics.circle("fill", 150, 350, 100)
--love.graphics.circle(mode, x, y, radius, segments)
love.graphics.circle("fill", button.x, button.y, button.size)
love.graphics.setFont(newFont)
love.graphics.setColor(255, 255, 255, 1)
love.graphics.print(button.score)
end
function love.mousepressed( x, y, b, isTouch)
if b == 1 then
-- use the distance formula to measure the distance/n!
if distanceFormula(button.x, button.y, love.mouse.getX(), love.mouse.getY()) < button.size then
--checks whether click is in circle.
score = score + 1
end
end
function distanceBetween(x1,y1,x2,y2)
return math.sqrt((y2-y1)^2 + (x2-x1)^2)
end
Can someone help me?
The error goes like this:
Error main.lua:45: attempt to call global 'distanceFormula' (a nil value)
Traceback
main.lua:45: in function <main.lua:42>
[C]: in function 'xpcall
I'm very sure that it probably has to do with the function place or something. Can someone help me?
Most importantly can someone please help me with preventing future errors like this??? Thank you.
It looks like you don't have a function called distanceFormula. Also I don't know why you are declaring your distanceBetween function inside of love.mousepressed. distanceFormula is "a nil value" because it doesn't exist. The error is referring to line 45 in your code
if distanceFormula(button.x, button.y, love.mouse.getX(), love.mouse.getY()) < button.size then
I changed your call to distanceFormula to be a call to distanceBetween and moved distance between to it's own function. I also had to move a few of your end around and got rid of your extra love.draw()
function love.load()
--number = 0 (old code)
button = {}
button.x = 200
button.y = 200
button.size = 50
button.score = 0
button.time = 0
newFont = love.graphics.newFont(40)
end
function love.update(dt) -- changes code in delta time: every frame: love runs in 60 frames per second
--number = number + 1 (old code)
end
function love.draw()
--love.graphics.setColor(0, 0, 255, 5)
--love.graphics.rectangle("fill", 200, 400, 200, 100) --love.graphics.rectangle(mode, x, y, width, height) Y increases downwards;
-- width increases to the right and the height increases downward assuming positive numbers
love.graphics.setColor(255,0,0,5)
--love.graphics.print(number) (old code)
--love.graphics.circle("fill", 150, 350, 100)
--love.graphics.circle(mode, x, y, radius, segments)
love.graphics.circle("fill", button.x, button.y, button.size)
love.graphics.setFont(newFont)
love.graphics.setColor(255, 255, 255, 1)
love.graphics.print(button.score)
end
function love.mousepressed(x, y, b, isTouch)
if b == 1 then
-- use the distance formula to measure the distance/n!
if distanceBetween(button.x, button.y, love.mouse.getX(), love.mouse.getY()) < button.size then
--checks whether click is in circle.
button.score = button.score + 1
end
end
end
function distanceBetween(x1,y1,x2,y2)
return math.sqrt((y2-y1)^2 + (x2-x1)^2)
end

How to split the image into chunks without breaking character - python

I am trying to read image from the text.
I am getting better result if I break the images into small chunks but the problem is when i try to split the image it is cutting/slicing my characters.
code I am using :
from __future__ import division
import math
import os
from PIL import Image
def long_slice(image_path, out_name, outdir, slice_size):
"""slice an image into parts slice_size tall"""
img = Image.open(image_path)
width, height = img.size
upper = 0
left = 0
slices = int(math.ceil(height/slice_size))
count = 1
for slice in range(slices):
#if we are at the end, set the lower bound to be the bottom of the image
if count == slices:
lower = height
else:
lower = int(count * slice_size)
#set the bounding box! The important bit
bbox = (left, upper, width, lower)
working_slice = img.crop(bbox)
upper += slice_size
#save the slice
working_slice.save(os.path.join(outdir, "slice_" + out_name + "_" + str(count)+".png"))
count +=1
if __name__ == '__main__':
#slice_size is the max height of the slices in pixels
long_slice("/python_project/screenshot.png","longcat", os.getcwd(), 100)
Sample Image : The image i want to process
Expected/What i am trying to do :
I want to split every line as separate image without cutting the character
Line 1:
Line 2:
Current result:Characters in the image are cropped
I dont want to cut the image based on pixels since each document will have separate spacing and line width
Thanks
Jk
Here is a solution that finds the brightest rows in the image (i.e., the rows without text) and then splits the image on those rows. So far I have just marked the sections, and am leaving the actual cropping up to you.
The algorithm is as follows:
Find the sum of the luminance (I am just using the red channel) of every pixel in each row
Find the rows with sums that are at least 0.999 (which is the threshold I am using) as bright as the brightest row
Mark those rows
Here is the code that will return a list of these rows:
def find_lightest_rows(img, threshold):
line_luminances = [0] * img.height
for y in range(img.height):
for x in range(img.width):
line_luminances[y] += img.getpixel((x, y))[0]
line_luminances = [x for x in enumerate(line_luminances)]
line_luminances.sort(key=lambda x: -x[1])
lightest_row_luminance = line_luminances[0][1]
lightest_rows = []
for row, lum in line_luminances:
if(lum > lightest_row_luminance * threshold):
lightest_rows.add(row)
return lightest_rows
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ... ]
After colouring these rows red, we have this image:

How to use bounding box in Love2d?

I've been using some extremely bulky code to detect collision between simple objects, and I've heard about bounding boxes. I can't find any tutorials on how to use it, so I'm asking about how to use it. Here is how I detect collision:
function platform.collision()
if player.x + player.width / 2 <= platform.x + platform.width and
player.x + player.width / 2 >= platform.x and
player.y + player.height <= platform.y + platform.height and
player.y + player.height >= platform.y then
The MDN has a rather concise article on 2D collision detection. Being the MDN, the examples are in javascript, but are easily translated to, and applicable in, any language - including Lua.
Let's take a look:
Axis-Aligned Bounding Box
One of the simpler forms of collision detection is between two rectangles that are axis aligned — meaning no rotation. The algorithm works by ensuring there is no gap between any of the 4 sides of the rectangles. Any gap means a collision does not exist.
Their example, translated to Lua:
local rect1 = { x = 5, y = 5, width = 50, height = 50 }
local rect2 = { x = 20, y = 10, width = 10, height = 10 }
if
rect1.x < rect2.x + rect2.width and
rect1.x + rect1.width > rect2.x and
rect1.y < rect2.y + rect2.height and
rect1.height + rect1.y > rect2.y
then
-- collision detected!
end
-- filling in the values =>
if
5 < 30 and
55 > 20 and
5 < 20 and
55 > 10
then
-- collision detected!
end
A live example, again in JavaScript, demonstrates this well.
Here's a quick (and imperfect) Love2D example you can throw into a main.lua and play around with.
local function rect (x, y, w, h, color)
return { x = x, y = y, width = w, height = h, color = color }
end
local function draw_rect (rect)
love.graphics.setColor(unpack(rect.color))
love.graphics.rectangle('fill', rect.x, rect.y,
rect.width, rect.height)
end
local function collides (one, two)
return (
one.x < two.x + two.width and
one.x + one.width > two.x and
one.y < two.y + two.height and
one.y + one.height > two.y
)
end
local kp = love.keyboard.isDown
local red = { 255, 0, 0, 255 }
local green = { 0, 255, 0, 255 }
local blue = { 0, 0, 255, 255 }
local dim1 = rect(5, 5, 50, 50, red)
local dim2 = rect(20, 10, 60, 40, green)
function love.update ()
if kp('up') then
dim2.y = dim2.y - 1
end
if kp('down') then
dim2.y = dim2.y + 1
end
if kp('left') then
dim2.x = dim2.x - 1
end
if kp('right') then
dim2.x = dim2.x + 1
end
dim2.color = collides(dim1, dim2) and green or blue
end
function love.draw ()
draw_rect(dim1)
draw_rect(dim2)
end
Oka explained it very well. This works for everything rectangular, not rotated and axis aligned. And you even already did it that way. This is great for buttons and the like!
But what I like doing is using (invisible) circles around objects and see if these collide. This works for everything where height is about the same as the width (which is the case for many sidescrolling platformers or top-down RPGs).
It's quite handy if you want to have the object centered at the current position. And it's especially helpful to simulate a finger on a touchscreen device, because a finger is quite a bit bigger than a mouse cursor. ;)
Here's an example on how to use this method. You can copy it as an actual game, it'll work.
--[[ Some initial default settings. ]]
function love.load()
settings = {
mouseHitbox = 5, -- A diameter around the mouse cursor.
-- For a finger (thouchscreen) this could be bigger!
}
objects = {
[1] = {
x = 250, -- Initial X position of object.
y = 200, -- Initial Y position of object.
hitbox = 100, -- A diameter around the CENTER of the object.
isHit = false -- A flag for when the object has been hit.
},
[2] = {
x = 400,
y = 250,
hitbox = 250,
isHit = false
}
}
end
--[[ This is the actual function to detect collision between two objects. ]]
function collisionDetected(x1,y1,x2,y2,d1,d2)
-- Uses the x and y coordinates of two different points along with a diameter around them.
-- As long as these two diameters collide/overlap, this function returns true!
-- If d1 and/or d2 is missing, use the a default diameter of 1 instead.
local d1 = d1 or 1
local d2 = d2 or 1
local delta_x = x2 - x1
local delta_y = y2 - y1
local delta_d = (d1 / 2) + (d2 / 2)
if ( delta_x^2 + delta_y^2 < delta_d^2 ) then
return true
end
end
--[[ Now, some LÖVE functions to give the collisionDetection() some context. ]]
function love.draw()
for i=1,#objects do -- Loop through all objects and draw them.
if ( objects[i].isHit ) then
love.graphics.setColor(255, 0, 0) -- If an object is hit, it will flash red for a frame.
objects[i].isHit = false
else
love.graphics.setColor(255, 255, 255)
end
love.graphics.circle("line", objects[i].x, objects[i].y, objects[i].hitbox/2)
end
end
-- You can use the following to check, if any object has been clicked on (or tapped on a touch screen device).
function love.mousepressed(x,y,button)
if ( button == 1 ) then
local i = objectIsHit(x,y) -- Check, if an object has been hit.
if ( i ) then
-- The object number 'i' has been hit. Do something with this information!
objects[i].isHit = true
end
end
end
function objectIsHit(x,y)
for i=1,#objects do -- Loop through all objects and see, if one of them has been hit.
if ( collisionDetected(x, y, objects[i].x, objects[i].y, settings.mouseHitbox, objects[i].hitbox) ) then
return i -- This object has been hit!
end
end
end
-- For the sake of completeness: You can use something like the following to check, if the objects themselves collide.
-- This would come in handy, if the objects would move around the screen and then bounce from each other, for example.
function love.update(dt)
if ( collisionDetected(objects[1].x, objects[1].y, objects[2].x, objects[2].y, objects[1].hitbox, objects[2].hitbox) ) then
-- The objects collided. Do something with this information!
end
end
As you can see, the collisionDetection() function is quite easy and intuitive to use.
Hopefully I could give you some more insight. And have fun with LÖVE 2D! :)

Resources