How to draw a line using turtle geometry?

3

I'm trying to complement my answer to a circumference intersection question . In this answer, at a given moment, I get an equation of the line through the coefficients a,b,c :

r: a*x + b*y + c = 0

I would like to represent this line on the screen using tortoise ( turtle ) preferably using only turtle geometry :

  • download / upload the pen
  • turn left / right R degrees
  • walk S steps forward

In this case, my turtle starts from the origin, facing the positive direction of the X axis (facing X + axis).

It is also appropriate to return to the place of origin of the turtle after a drawing procedure. After drawing something, staying in a random position is not positive.

What I have

Depending on the slope of the line, I have a different strategy of how to draw it.

Horizontal line

Representing the line only by (a,b,c) , if a == 0 , then we have a horizontal line, with y = -c/b .

So, I need to do the following:

subir caneta
virar 90° para a esquerda     # fico virado para o eixo Y+
andar -c/b
virar 90° para a direita      # volto a ficar voltado para o eixo X+
baixar caneta
desenha a reta                # voltando ao ponto de partida da reta
subir caneta
virar 90° para a direita      # fico virado para o eixo Y-
andar -c/b                    # retorna para a origem
virar 90° para a esquerda     # volto a ficar voltado para o eixo X+

In Python, being t the turtle:

t.penup()
t.left(90)           # fico virado para o eixo Y+
t.forward(-c/b)
t.right(90)          # volto a ficar voltado para o eixo X+
t.pendown()
# desenha a reta e volta a esse mesmo ponto
t.penup()
t.right(90)          # fico virado para o eixo Y-
t.forward(-c/b)      # retorna para a origem
t.left(90)           # volto a ficar voltado para o eixo X+

Vertical line

Representing the line only by (a,b,c) , if b == 0 , then we have a vertical line, with x = -c/a .

So, I need to do the following:

subir caneta
andar -c/a
virar 90° para a esquerda     # volto a ficar voltado para o eixo Y+
baixar caneta
desenha a reta                # voltando ao ponto de partida da reta
subir caneta
virar 90° para a esquerda     # fico virado para o eixo X-
andar -c/a                    # retorna para a origem
virar 180° para a direita     # volto a ficar voltado para o eixo X+

In Python, being t the turtle:

t.penup()
t.forward(-c/a)
t.left(90)           # volto a ficar voltado para o eixo Y+
t.pendown()
# desenha a reta e volta a esse mesmo ponto
t.penup()
t.left(90)           # fico virado para o eixo X-
t.forward(-c/a)      # retorna para a origem
t.right(180)         # volto a ficar voltado para o eixo X+

Slope line

Representing the line only by (a,b,c) , if a != 0 and b != 0 , then we have a sloped line that varies on both the X-axis and the Y-axis.

I know that it intercepts the X axis when y = 0 , so that point is (-c/a,0) . Then I must determine the direction of the line.

When the equation of the line is in the y = m*x + k format, then m is the tangent of the angle that the line makes with the X axis. This angle is the rotation of how much counterclockwise it is necessary to rotate so that pointing toward the straight. So I can get the angle in radians via math.atan(m) . As m = -a/b , then I get the angle via math.atan(-a/b) .

I can also compute the angle without making this explicit split through math.atan2 . When x varies% with% units, then b needs to vary y units:

; seja (x0,y0) o ponto inicial da reta e (x1,y1) o ponto da reta obtida deslocando x0 em b unidades
a*x0 + b*y0 + c = 0
a*x1 + b*y1 + c = 0

x1 = x0 + b
; portanto:

a*(x0 + b) + b*y1 + c = 0
a*x0 + a*b + b*y1 + c = 0
a*x0 + a*b + b*y1 + c = a*x0 + b*y0 + c
a*b + b*y1 = b*y0
b*y1 = b*y0 - a*b = b*(y0 - a)
; como b != 0, pois a reta está inclinada:
y1 = y0 - a

; portanto, a inclinação é
(b, -a)

As shown, the direction of the line points to -a , calling (b, -a) would return the appropriate angle to point in that direction.

After finding the angle in radians, only turn to degrees and use the turtle.

In Python, abstracting% with% transforming radians into degrees, would look like this to draw the line:

inclinacao = radians2degrees(math.atan2(-a, b))
t.penup()
t.forward(-c/a)      # vai ao ponto em que a reta corte o eixo X
t.left(inclinacao)   # inclina na direção da reta
t.pendown()
# desenha a reta e volta a esse mesmo ponto
t.penup()
t.right(inclinacao)  # fico virado para o eixo X+
t.left(180)          # viro para o eixo X-
t.forward(-c/a)      # retorna para a origem
t.right(180)         # volto a ficar voltado para o eixo X+

Specific point of difficulty

Being anywhere on the screen, I can draw a segment of arbitrary size. You can pick up the screen dimensions in tortoise steps by calling math.atan2(-a, b) and radians2degree . I know that I can draw by occupying the screen (with surplus) drawing t.window_height() forward, turning 180 °, walking 2 times that distance, then turning 180 ° again and walking that distance again to return to the origin of the drawing (it is necessary rotate 180 ° to return to the original orientation). However, this drawing method includes a "waste" of off-screen drawing.

  

The distance t.window_length() is the largest possible between two points of a rectangular window: the distance between the left-upper and the lower-right.

Currently, with a constant of 50 back and forth, I draw a small segment, not the entire straight:

automateddrawingofthelineobtainedfromthe"subtraction" of the equation of two circles

In this case, I was purposely testing to get the equation of the line from circles whose centers always have (h**2 + w**2)**0.5 , so the lines are all vertical.

    
asked by anonymous 06.12.2017 / 03:59

0 answers