Vityou
Vityou

Reputation: 135

python distance formula coordinate plane error

My goal is to make a circle shape out of lines in pygame, using random endpoints around the edge of a circle and a constant starting point (the middle of the circle). So I decided that I would give the pygame.draw.line function: screen, aRandomColor, startingPosition, and endingPosition as arguments. Ending position is a tuple containing a randomly generated x value, and a helper function will calculate the y value based on the radius of the circle. My first function calculates the y value like this:

import math
import random

def findY(pos1, pos2, distance, bothValues=False):
    p1 =pos1
    p2 = pos2
    x1 = float(p1[0])
    y1 = float(p1[1])
    x2 = float(p2[0])
    d = float(distance)

    y2 = y1 - math.sqrt(d**2 - (x1-x2)**2)
    _y2 = y1 + math.sqrt(d**2 - (x1-x2)**2)
    if bothValues==True:
        return y2, _y2
    else:
        return y2

and the line drawer:

width = 500
height = 500

def randLine(surface, color=rand, start=rand, end=rand,length=rand):
    if start==rand:
        start = randPos()
    if end==rand:
        end = randPos()
    if color==rand:
        color = randColor()
    if length != rand:

        end_x = float(random.randint(0,width))
        end_pos = (end_x, "y")
        y2=findMissing(start_pos, end_pos,l,bothValues=True)
        a = random.randint(0,1)
        if a==0:
            y2 = float(y2[0])
        else:
            y2 = float(y2[1])
        lst = list(end_pos)
        lst[1] = y2
        end_pos = tuple(lst)
    pygame.draw.line(surface, color, start_pos, end_pos)

Then:

drawRandLine(screen,start=(200,200),lenght=100)

(the other functions that those ones called like randPos aren't the problem). This for some reason generated an error that I diagnosed as the value inside the math.sqrt() was a negative number. But that can't happen, since every value in there is raised to power of 2, and thats what I'm confused about. So I changed the value inside math.sqrt() to its absolute value. This made the function not raise any errors, but the circle drawn looked like this:

wacky inverted circloid

I know that pygame's coordinate plane's y values upside down, but should that make a difference?

Upvotes: 5

Views: 481

Answers (2)

Galax
Galax

Reputation: 1431

One way of getting a a uniform distribution of angles would be to generate a random angle theta between 0 and 2 * math.pi, and use trigonometry to find the co-ordinates of the end point of the line:

def drawRandLineTrig(start_pos, length):
    theta = random.rand() * 2 * math.pi
    end_pos = (start_pos[0] + length*math.cos(theta), start_pos[1] + length*math.sin(theta))
    # ...

Upvotes: 3

Vityou
Vityou

Reputation: 135

I could Do:

def randPos(origin=(0,0), xdis=width, ydis=height):
    randx = random.randint(float(origin[0])-xdis,float(origin[0])+xdis)
    randy = random.randint(float(origin[1])-ydis,float(origin[1])+ydis)
    return (randx, randy)

def drawRandLine(surface, color=random, start_pos=random, end_pos=random,l=random):
    if start_pos==random:
        start_pos = randPos()
    if end_pos==random:
        end_pos = randPos()
    if color==random:
        color = randColor()
    if l != random:
        b = random.randint(0,1)
        l=float(l)
        origin = start_pos
        dis = l
        if b==0:
            end_x = float(random.randint((origin[0]-dis),(origin[0]+dis)))
            end_pos = (end_x, "y")
            y2=findMissing(start_pos, end_pos,l,bothValues=True)
            a = random.randint(0,1)
            if a==0:
                y2 = float(y2[0])
            else:
                y2 = float(y2[1])
            lst = list(end_pos)
            lst[1] = y2
            end_pos = tuple(lst)
        else:
            end_y = float(random.randint((origin[1]-dis),(origin[1]+dis)))
            end_pos = ("x", end_y)
            x2=findMissing(start_pos, end_pos,l,bothValues=True)
            a = random.randint(0,1)
            if a==0:
                x2 = float(x2[0])
            else:
                x2 = float(x2[1])
            lst = list(end_pos)
            lst[0] = x2
            end_pos = tuple(lst)

    pygame.draw.line(surface, color, start_pos, end_pos)

Which fixes the sqrt of a negative problem, and places an even distribution of lines by either calculating the x OR the y, and setting their limits to the specified length, to avoid the strange length of some of the lines.

Upvotes: 0

Related Questions