How am I supposed to stop a looped function in draw? [HELP!]

asking questions

hey,

I just know that this will have a simple solution, I just can’t figure it out.

I have a function that generates random points generate ; the idea is to generate points and display them on the canvas. Without the never ending loop of generating new points every time draw() runs . I did try noLoop() , but the result is not what I want, it just halts everything and I’ll need to call loop() again at some point…and I am back to the never ending loop.

I am passing the points to ellipse through a loop in draw() , is there a way to stop the loop from destroying my frame rate and just display the random points created by generate()

import random as rn
import math

width = 600
height = 600
xl, yl = width, height

groupSize = 10000 #change this, 
time = 0

def distance(x, y, x1, y1):
    distance = math.sqrt(((x2 - x1) ** 2) + ((y2 - y1)**2))
    return distance

def pointFunction(xl, yl):
    x = rn.uniform(0, xl)
    y = rn.uniform(0, yl)
    return x, y

def generate(groupSize, xl, yl):
    groupDict = {}
    for i in range(groupSize):
            x, y = pointFunction(xl, yl)
            groupDict[i] = {
                    'xValue': x,
                    'yValue': y,
                    'status': 0 # 0 = normal, 1 = infected, 2 = in hospital, 3 = cured, 4 = dead
                    }
   # noLoop()
    return groupDict

def prepareData():
    sampleValues = generate(groupSize, xl, yl)
    for i in range(len(sampleValues)):
        x = sampleValues[i]['xValue'] 
        y = sampleValues[i]['yValue']
        status = sampleValues[i]['status']
    return x, y, status

      
def setup():
    size(width,height)
    noStroke()

def draw():
    global time
    sampleValues = generate(groupSize, xl, yl)
  #  print sampleValues
    background(0)
    stroke(255)
    fill(255, 155, 100)
    x = 0
    y = 0
    for i in range(len(sampleValues)):
     #   oldX = float(x)
     #  oldY = float(y)
        x = sampleValues[i]['xValue'] 
        y = sampleValues[i]['yValue']
        status = sampleValues[i]['status']
    #    ellipse(oldX, oldY, 5,5)
        ellipse(x, y, 2, 2)

1 Like

You want to generate … when?

When the sketch starts? Then use def setup():. When the mouse is clicked? Use def mouseReleased():. Every ten seconds? use if frameCount % 600 == 0:.

https://p5js.org/reference/#/p5/setup

https://p5js.org/reference/#/p5/mouseReleased

1 Like

Cheers @jeremydouglass I knew it was something like that…thanks again.

1 Like

@jeremydouglass

So, I am facing another issue with borders/boundaries. I just cant wrap my head around it.

I initiated my points(circles) in setup like so, which does work. I have n static circles. where f is dict.

def p(dic):
    g = generate()
    FinalDict = sa.prepareData(g)
    return FinalDict

def setup():
    global f
    size(width, height)
    smooth(8)
    colorMode(RGB)
    background(0)
    f = p(g)

def draw():
    background(0)
    #translate(300,300)
    for i in range(groupSize):
        v = f.get(i)
        x = v['x']
        y = v['y']
        s = v['status']
        d = v['distance']
        ix = v['oldX']
        iy = v['oldY']
        m.movingPoint(x, y, dia)
        u = m.update(f, i)
        m.boundry()
        m.drawPoint(u[0], u[1], rag)

where m is the Moving class and sa is the SampleGeneration class

import random as rn
import math
class Moving:
    
    def __init__(self, x, y, dia):
        self.x = float(x)
        self.y = float(y)
        self.speedX = 0
        self.speedY = 0
        self.dia = float(dia)
        self.offset = 1
    
    def movingPoint(self, xpos, ypos, psize):
        self.x = xpos
        self.y = ypos
        self.dia = psize
        self.speedX = random(-width, width)
        self.speedY = random(-height, height)

    def update(self, dic, i):
        ix = self.x
        iy = self.y
        ix += self.speedX * self.offset
        iy += self.speedY * self.offset
        #print i, dic[i]['x']
        dic[i]['x'] = ix
        dic[i]['y'] = iy
        # j['x'] = self.x 
        # j['y'] = self.y
        return ix, iy       
        
    def boundry(self):
        if self.x <= 0 or self.x > width:
            self.speedX = -self.speedX
        if self.y <= 0 or self.y > height:
            self.speedY = -self.speedY
     
            
    def drawPoint(self, status, d, rag):
        '''
        d = distance between any given point and the one before it. Distance must be called before this.
        rag = allowed range before changing colour/state later on
        '''
        
        if d < rag:
            status = 1
            self.colorCode(status)
            # self.x *= 0.1
            # self.y *= 0.1
        circle(self.x, self.y ,self.dia)
        return 
        
   
    def colorCode(self, status):
        statusColors = {
                        0: [255,255,255],
                        1: [255,0,0],
                        2: [0, 100, 0],
                        3: [0, 255, 0], 
                        4: [255, 111, 0]
                        }
        c = statusColors[status]
        return fill(c[0], c[1], c[2])
      
        
        
import random as rn
import math

class SampleGeneration:
        
    def __init__(self, x, y, groupSize):
        self.x = x
        self.y = y
        self.groupSize = groupSize
        self.groupDict = {}
        self.movers = []
        self.finalDict = {}
    
    def pointFunction(self):
        pointX = rn.uniform(0, width)
        pointY = rn.uniform(0, height)
        return pointX, pointY
    
    def generate(self):
       # self.x, self.y
        for i in range(self.groupSize):
                x, y = self.pointFunction()
                self.groupDict[i] = {
                            'xValue': math.floor(x),
                            'yValue': math.floor(y),
                            'status': 0 # 0 = normal, 1 = infected, 2 = in hospital, 3 = cured, 4 = dead
                            }
        infectedSize = math.floor(self.groupSize / 10)
        self.movers.insert(0, self.groupDict[infectedSize])
        return self.groupDict
    
    
    def distance(self, x, y, x1, y1):
        distance = math.sqrt(((x1 - x) ** 2) + ((y - y1)**2))
        return distance
    
    def prepareData(self, dic):
       # self.groupSize, self.x, self.y
        sampleValues = dic
        x = 0
        y = 0 
        for i in range(len(sampleValues)):
            #print i
            oldX = float(x)
            oldY = float(y)
            x = sampleValues[i]['xValue'] 
            y = sampleValues[i]['yValue']
            status = sampleValues[i]['status']
            d = self.distance(x, y, oldX, oldY)
            self.finalDict[i] = {
                            'x': math.floor(x),
                            'y': math.floor(y),
                            'oldX': math.floor(oldX),
                            'oldY': math.floor(oldY),
                            'distance':math.floor(d),
                            'status': 0 # 0 = normal, 1 = infected, 2 = in hospital, 3 = cured, 4 = dead
                            }
        return self.finalDict
    

My problem is with boundaries–misspelled in Moving as boundry:

def boundry(self):
        if self.x <= 0 or self.x > width:
            self.speedX = -self.speedX
        if self.y <= 0 or self.y > height:
            self.speedY = -self.speedY

I have tried calling boundry almost everywhere, I even tried calling it in within the update func…my circles are still escaping the canvas.

I would appreciate any feedback, cheers.