Home > front end >  Trajectory plalnification
Trajectory plalnification

Time:11-29

I have a program that generates circles and lines, where the circles can not collide with each other and the lines can not collide with the circles, the problem is that it only draws a line but not the others, it does not mark any error and as much as I think the reason I do not understand why, (I'm new to python, so excuse me if maybe the error is obvious)

I tried to remove the for from my CreaLin class and it does generate the lines but they all collide with the circles, I also thought that the collisionL function could be the problem since the method does not belong as such to the line class, but I need values from the circle class, so I don't know what would be another way to do it, I would like to know a method.

my code:

class CreaCir:
    def __init__(self, figs):
        self.figs = figs
        
    def update(self):
        if len(self.figs) <70:
            choca = False
            r = randint(5, 104)
            x = randint(0, 600   r)
            y = randint(0, 400   r) 
            creOne = Circulo(x, y, r)
            for  fig in (self.figs):
                choca = creOne.colisionC(fig)
                if choca == True:
                    break
            if choca == False:
                self.figs.append(creOne)
           
    def dibujar(self, ventana):
        pass

class CreaLin:
    def __init__(self, lins):
        self.lins = lins

    def update(self):
        if len(self.lins) <70:
            choca = False
            x = randint(0, 700)
            y = randint(0, 500)
            a = randint(0, 700) 
            b = randint(0, 500)
            linOne = Linea(x, y, a, b)
            for  lin in (self.lins):
                choca = linOne.colisionL(lin)
                if choca == True:
                    break
            if choca == False:
                self.lins.append(linOne)        
    
    def dibujar(self, ventana):
        pass


class Ventana:
    def __init__(self, Ven_Tam= (700, 500)):
        
        pg.init()
        self.ven_tam = Ven_Tam

        self.ven = pg.display.set_caption("Linea")
        self.ven = pg.display.set_mode(self.ven_tam)
        self.ven.fill(pg.Color('#404040'))
        self.figs = []
        self.lins = []
        self.reloj = pg.time.Clock()
        
    def check_events(self):
        for event in pg.event.get():
            if event.type == pg.QUIT or (event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE):
                quit()
        pg.display.flip()

    def run(self):
        cirCreater = CreaCir(self.figs)
        linCreater = CreaLin(self.lins)
        while True:
            self.check_events()
            cirCreater.update()
            linCreater.update()

            for fig in self.figs:
                fig.dibujar(self.ven)

            for lin in self.lins:
                lin.dibujar(self.ven)

            self.reloj.tick(60)
                 

if __name__ == '__main__':
    ven = Ventana()
    ven.run()

class Circulo:

class Circulo(PosGeo):
    def __init__(self, x, y, r):
        self.x = x
        self.y = y
        self.radio = r
        self.cx = x r
        self.cy = y r

    def __str__(self):
      return f"Circulo, (X: {self.x}, Y: {self.y}), radio: {self.radio}"

    def dibujar(self, ventana):
        pg.draw.circle(ventana, "white", (self.cx, self.cy), self.radio, 1)
        pg.draw.line(ventana, "white", (self.cx 2, self.cy 2),(self.cx-2, self.cy-2))
        pg.draw.line(ventana, "white", (self.cx-2, self.cy 2),(self.cx 2, self.cy-2))

    def update(self):
        pass

    def colisionC(self, c2):
        return self.radio   c2.radio > sqrt(pow(self.cx - c2.cx, 2)   pow(self.cy - c2.cy, 2))
    
   
   def colisionL(self, L2):
       l0 = [L2.x, L2.y]
       l1 = [L2.a, L2.b]
       cp = [self.cx, self.cy]

       x1 = l0[0] - cp[0]
       y1 = l0[1] - cp[1]
       x2 = l1[0] - cp[0]
       y2 = l1[1] - cp[1]
       dx = x2 - x1
       dy = y2 - y1
       dr = sqrt(dx*dx   dy*dy)
       D = x1 * y2 - x2 * y1
       discriminant = self.radio*self.radio*dr*dr - D*D
    
       if discriminant < 0:
          return False
       else:
          return True`

and finally my class line:

class Linea(PosGeo):
    def __init__(self, x, y, a, b):
        super().__init__(x, y)
        self.x = x
        self.y = y
        self.a = a
        self.b = b

    def dibujar(self, ventana):
        pg.draw.line(ventana, "#7B0000", (self.x, self.y), (self.a, self.b))

    def update(self):
        pass
    
    def colisionL(self, l1):
        pass

Result: enter image description here

CodePudding user response:

You need to implement the colisionC and colisionL methods in Linea and Circulo. See

import pygame as pg
from random import randint
from math import sqrt, hypot

class Linea:
    def __init__(self, x, y, a, b):
        self.x = x
        self.y = y
        self.a = a
        self.b = b

    def dibujar(self, ventana):
        pg.draw.line(ventana, "#7B0000", (self.x, self.y), (self.a, self.b))

    def update(self):
        pass

    def colisionC(self, c2):
        return c2.colisionL(self)
    
    def colisionL(self, l1):
        return Linea.intersect_line_line((self.x, self.y), (self.a, self.b), (l1.x, l1.y), (l1.a, l1.b))
    
    def intersect_line_line(P0, P1, Q0, Q1):  
        d = (P1[0]-P0[0]) * (Q1[1]-Q0[1])   (P1[1]-P0[1]) * (Q0[0]-Q1[0]) 
        if d == 0:
            return None
        t = ((Q0[0]-P0[0]) * (Q1[1]-Q0[1])   (Q0[1]-P0[1]) * (Q0[0]-Q1[0])) / d
        u = ((Q0[0]-P0[0]) * (P1[1]-P0[1])   (Q0[1]-P0[1]) * (P0[0]-P1[0])) / d
        if 0 <= t <= 1 and 0 <= u <= 1:
            return P1[0] * t   P0[0] * (1-t), P1[1] * t   P0[1] * (1-t)
        return None

class Circulo:
    def __init__(self, x, y, r):
        self.x = x
        self.y = y
        self.radio = r
        self.cx = x r
        self.cy = y r

    def __str__(self):
      return f"Circulo, (X: {self.x}, Y: {self.y}), radio: {self.radio}"

    def dibujar(self, ventana):
        pg.draw.circle(ventana, "white", (self.cx, self.cy), self.radio, 1)
        pg.draw.line(ventana, "white", (self.cx 2, self.cy 2),(self.cx-2, self.cy-2))
        pg.draw.line(ventana, "white", (self.cx-2, self.cy 2),(self.cx 2, self.cy-2))

    def update(self):
        pass

    def colisionC(self, c2):
        return self.radio   c2.radio > sqrt(pow(self.cx - c2.cx, 2)   pow(self.cy - c2.cy, 2))
    
    def colisionL(self, L2):
       l0 = [L2.x, L2.y]
       l1 = [L2.a, L2.b]
       cp = [self.cx, self.cy]
       x1 = l0[0] - cp[0]
       y1 = l0[1] - cp[1]
       x2 = l1[0] - cp[0]
       y2 = l1[1] - cp[1]
       if sqrt(x1*x1 y1*y1) < self.radio or sqrt(x2*x2 y2*y2) < self.radio:
           return True

       dx = x2 - x1
       dy = y2 - y1
       dr = sqrt(dx*dx   dy*dy)
       D = x1 * y2 - x2 * y1
       discriminant = self.radio*self.radio*dr*dr - D*D
       if discriminant < 0:
           return False
       
       sign = lambda x: -1 if x < 0 else 1
       xa = (D * dy   sign(dy) * dx * sqrt(discriminant)) / (dr * dr)
       xb = (D * dy - sign(dy) * dx * sqrt(discriminant)) / (dr * dr)
       ya = (-D * dx   abs(dy) * sqrt(discriminant)) / (dr * dr)
       yb = (-D * dx - abs(dy) * sqrt(discriminant)) / (dr * dr)
       ta = (xa-x1)*dx/dr   (ya-y1)*dy/dr
       tb = (xb-x1)*dx/dr   (yb-y1)*dy/dr
       return 0 < ta < dr or 0 < tb < dr

class CreaObjects:
    def __init__(self, figs):
        self.figs = figs
        self.no_lines = 0
        self.no_circles = 0
        
    def update(self):
        if self.no_circles <70:
            r = randint(5, 104)
            creOne = Circulo(randint(0, 600 - 2*r), randint(0, 400 - 2*r), r)
            if not any(fig.colisionC(creOne) for fig in self.figs):
                self.figs.append(creOne)
                self.no_circles  = 1
    
        if self.no_lines <70:
            linOne = Linea(randint(0, 700), randint(0, 500), randint(0, 700), randint(0, 500))
            if not any(fig.colisionL(linOne) for fig in self.figs):
                self.figs.append(linOne)
                self.no_lines  = 1 

class Ventana:
    def __init__(self, Ven_Tam= (700, 500)):
        
        pg.init()
        self.ven_tam = Ven_Tam

        self.ven = pg.display.set_caption("Linea")
        self.ven = pg.display.set_mode(self.ven_tam)
        self.figs = []
        self.reloj = pg.time.Clock()
        
    def check_events(self):
        for event in pg.event.get():
            if event.type == pg.QUIT or (event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE):
                quit()

    def run(self):
        cirCreater = CreaObjects(self.figs)
        while True:
            self.check_events()
            cirCreater.update()
            
            self.ven.fill(pg.Color('#404040'))
            for fig in self.figs:
                fig.dibujar(self.ven)
            pg.display.flip()
            self.reloj.tick(60)
                 
if __name__ == '__main__':
    ven = Ventana()
    ven.run()
  • Related