I'm not really a programmer but I wanted to see if I could help. Sorry if this is a useless distraction!
So what we want is a membrane around a cell that looks quite "cell-like" which the player can click and drag to move around? Right?
This is what I could do.
So basically it just starts with a random set of points and then smooths them out. The longer you run the smoothing for the smoother it gets. I think it looks quite cell like.
The membrane goes green when it is very stretched which is useful in game.
I guess you could generate the set of points with some randomness. Run the smoothing (as much as you wanted). Then that is the shape of your cell.
If you get attacked in game your cell get's deformed and either tears (causing spillage) or doesn't. Then you run the smoothing again for a bit to get the new, deformed, shape.
It would be kind of cool to carry your battle scars with you.
I think this should work fine in 3D, it's just a case of using a 2D laplacian term.
To generate the intital set of points you could either
A) find the organelle furthest from the centre and pick some random points 2x as far as this or
B) project from the centre though some points on the outside of the hjex grid and put a point at double this distance.
Like this
Spoiler:
What do you guys think? It's just a suggestion, I have no idea how ogre works so sorry I can't implement this myself. Here is the code I was using (apologies for the quality)
Code:
import pygame import math import sys import random from pygame.locals import *
while count <= max: points.append(point(count)) count += 0.01
running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == KEYDOWN: if event.key == K_ESCAPE: running = False if event.key == K_SPACE: for i in range(10): points[50 + i].r += 100
screen.fill(background_colour)
for i in range(len(points)): points[i].display() points[i].smooth(i)
pygame.display.flip()
pygame.quit()
tjwhale Theorist
Posts : 87 Reputation : 26 Join date : 2014-09-07
Subject: Re: Cell Membrane Wed Jan 14, 2015 2:17 pm
Three examples of a dynamic membrane encapsulating control points.
Code:
import pygame import math import sys import random from pygame.locals import *
while count <= maximum: points.append(point(count)) count += 0.01
for i in range(random.randint(5,10)): controlpoints.append(controlpoint()) for j in range(len(points)): if points[j].angle >= (controlpoints[i].angle - 0.2) and points[j].angle <= (controlpoints[i].angle + 0.2): distance = controlpoints[i].r*1.5 points[j].r = max(200,distance)
Hold = True while Hold: for event in pygame.event.get(): if event.type == KEYDOWN: if event.key == K_SPACE: Hold = False
running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == KEYDOWN: if event.key == K_ESCAPE: running = False if event.key == K_SPACE: for i in range(10): points[50 + i].r += 100
screen.fill(background_colour)
for i in range(len(points)): points[i].display() points[i].smooth(i)
for i in range(len(controlpoints)): controlpoints[i].display()
pygame.display.flip()
pygame.quit()
MitochondriaBox Learner
Posts : 188 Reputation : 7 Join date : 2013-01-29 Age : 24 Location : Houston, Texas
Subject: Re: Cell Membrane Wed Jan 14, 2015 6:42 pm
Is this intended to work alongside the idea of the cell's shape being based on the "body tiles" by being tightened a bit, or is it meant for amoeboid cells with looser membranes?
tjwhale Theorist
Posts : 87 Reputation : 26 Join date : 2014-09-07
Subject: Re: Cell Membrane Wed Jan 14, 2015 7:58 pm
It's an attempt to generate a membrane that looks relatively biological around a set of points (which would be the organelles).
What do you think? Does it look "celley"?
This is the kind of thing you get for a more regular pattern of control nodes (organelles). This is how I would imagine a player microbe might look.
Spoiler:
https://servimg.com/view/18993042/32
MitochondriaBox Learner
Posts : 188 Reputation : 7 Join date : 2013-01-29 Age : 24 Location : Houston, Texas
Subject: Re: Cell Membrane Wed Jan 14, 2015 9:57 pm
tjwhale wrote:
It's an attempt to generate a membrane that looks relatively biological around a set of points (which would be the organelles).
What do you think? Does it look "celley"?
This is the kind of thing you get for a more regular pattern of control nodes (organelles). This is how I would imagine a player microbe might look.
Spoiler:
https://servimg.com/view/18993042/32
Looks "celley" to me. Just wondering how it fits into the other developments in progress.
Other Developments:
https://www.youtube.com/watch?v=W20rDBK70_0
Not sure if it's still being worked on, but, if it is, hopefully it can fit into this... Maybe the cell body hexes can be the set points?
tjwhale Theorist
Posts : 87 Reputation : 26 Join date : 2014-09-07
Subject: Re: Cell Membrane Thu Jan 15, 2015 8:13 am
Basically that's the system the programmers are working on. They know what they are doing and that will probably work better.
I thought I'd try a different approach which is a bit more experimental. It's good programming practice for me and I think it works well enough.
Here is an example of body deformation movement (rippling) and what engulfment / feeding would look like.
tjwhale Theorist
Posts : 87 Reputation : 26 Join date : 2014-09-07
Subject: Re: Cell Membrane Thu Jan 15, 2015 5:07 pm
Here's something in 3D, it's not quite perfect (you can see a hillarious number of points mapped to the pole) but it is in 3D and it does work.
Think of it like looking down on a dome. The redder it is the higher it is. The blue blobs are the organelles.
Code:
import pygame import math import sys import random from pygame.locals import *
Subject: Re: Cell Membrane Sat Jan 24, 2015 9:17 pm
So here's my next attempt.
This time it calculates the vertices and the triangles between them and fills them in. You can't see the organelles anymore (they are inside the mesh, at least I think it's a mesh now).
Also it starts with the points layed out in a cube which I think is better than the spherical distribution which I was using before (as that mapped too many points to the poles).
The first two runs are general examples. The third has all the organelles in a plane. You can see the outline turn into a puck pretty quickly.
The fourth run has the two green points fixed (as if the player had click and dragged them there) and the rest of the surface shapes around that. (there's a weird jump in the video, don't know what that is, apologies)
Anyway hope you like it.
Code:
I have tried to put comments in the code to hopefully make it easier to understand in case anyone is reading it.
#make a cube around the organelles which is then smoothed into place, compute all triangles in the mesh
#setup
import pygame import math import sys import random from pygame.locals import * import time start_time = time.time()
# this is where the vertices get smoothed. They try sum the distances from their neighbours to the origin. # then they subtract their own distance multiplied by the number of neighbours. # this gives a measure of if they are above or below average. They then move to become more average
def smooth(self): laplacian = 0 for i in range(len(self.nbrs)): laplacian += self.nbrs[i].r laplacian -= len(self.nbrs)*self.r self.r += 0.1*laplacian self.x = self.r*math.sin(self.theta)*math.cos(self.phi) self.y = self.r*math.sin(self.theta)*math.sin(self.phi) self.z = self.r*math.cos(self.theta)
#if a vertx gets too close to an organelle is moves further away
def checkdistance(self): for i in range(len(controlpoints)): if distance(self.x,self.y,self.z,controlpoints[i].x,controlpoints[i].y,controlpoints[i].z) <= 150: self.r += 5
vertices = [] controlpoints = [] triangles = []
maxdist = 0
#place some random organelles
for i in range(0,10): controlpoints.append(controlpoint()) controlpoints[0].r = 0
for i in range(len(controlpoints)): if controlpoints[i].r >= maxdist: maxdist = controlpoints[i].r
maxdist += 30
#compute the size of gaps between vertices
print 'maxdist', maxdist gap = float(2*maxdist)/sidelength print 'gap', gap
#put vertices on the top and bottom of the cube
for i in range(sidelength + 1): for j in range(sidelength + 1): vertices.append(vertex(-maxdist + i*gap, -maxdist + j*gap, -maxdist)) vertices.append(vertex(-maxdist + i*gap, -maxdist + j*gap, +maxdist))
for i in range(len(vertices)): for j in range(len(vertices)): if (distance(vertices[i].x,vertices[i].y, vertices[i].z, vertices[j].x, vertices[j].y, vertices[j].z) <= 1.1*gap): if (distance(vertices[i].x,vertices[i].y, vertices[i].z, vertices[j].x, vertices[j].y, vertices[j].z) >= 0.5*gap): vertices[i].nbrs.append(vertices[j])
#compute a list of triangles which connect the vertices
for i in range(len(vertices)): for j in range(len(vertices[i].nbrs)): for k in range(j, len(vertices[i].nbrs)): vector1 = [vertices[i].nbrs[j].x - vertices[i].x, vertices[i].nbrs[j].y - vertices[i].y, vertices[i].nbrs[j].z - vertices[i].z] vector2 = [vertices[i].nbrs[k].x - vertices[i].x, vertices[i].nbrs[k].y - vertices[i].y, vertices[i].nbrs[k].z - vertices[i].z] crossproduct = cross(vector1, vector2) if crossproduct >= 1: triangles.append((vertices[i],vertices[i].nbrs[j],vertices[i].nbrs[k]))
Posts : 318 Reputation : 56 Join date : 2013-09-30 Age : 29 Location : hanging from the chandelier
Subject: Re: Cell Membrane Sun Jan 25, 2015 12:17 am
Hey, this is all really, really great work. I managed to get your latest prototype working (the previous ones I couldn't for some reason), and I fiddled around with it and added some more controls. Mouse can drag organelles, lshift disables vertex rendering leaving just the mesh, enter will randomize organelle positions (it actually replaces them with new ones, but same diff), and rshift will toggle the pinned constraint vertices.
Code:
#I have tried to put comments in the code to hopefully make it easier to understand in case anyone is reading it.
#make a cube around the organelles which is then smoothed into place, compute all triangles in the mesh
#setup
import pygame import math import sys import random from pygame.locals import * import time from pygame.mouse import get_pos start_time = time.time()
def handleMouse(self, x, y, clicking_edge = False): # convert to internal render coords x /= scale y /= scale y -= 500 mouseray = [None, None, None] # convert to effective 3D coordinates if x > 1000: # if click was on side view (ie, on xz plane) x -= 1500 mouseray[0] = x mouseray[2] = y else: # click was on xy plane x -= 500 mouseray[0] = x mouseray[1] = y # so mouseray holds a line, where the None coordinate is allowed to vary if clicking_edge: # runs if this was called on mouse-click-down if within(mouseray[0], self.x): if mouseray[1] is not None and within(mouseray[1], self.y): self.clicked = True elif mouseray[2] is not None and within(mouseray[2], self.z): self.clicked = True if self.clicked: self.x = mouseray[0] if mouseray[1]: self.y = mouseray[1] elif mouseray[2]: self.z = mouseray[2]
#define vertices
class vertex: def __init__(self, x,y,z): self.x = x self.y = y self.z = z self.r = distance(self.x,self.y,self.z,0,0,0) self.theta = math.acos(float(self.z)/self.r) self.phi = math.atan2(self.y,self.x) self.colour = (255,0,0, pointalpha) self.nbrs = []
# this is where the vertices get smoothed. They try sum the distances from their neighbours to the origin. # then they subtract their own distance multiplied by the number of neighbours. # this gives a measure of if they are above or below average. They then move to become more average
def smooth(self): laplacian = 0 for i in range(len(self.nbrs)): laplacian += self.nbrs[i].r laplacian -= len(self.nbrs)*self.r self.r += 0.1*laplacian self.x = self.r*math.sin(self.theta)*math.cos(self.phi) self.y = self.r*math.sin(self.theta)*math.sin(self.phi) self.z = self.r*math.cos(self.theta)
#if a vertx gets too close to an organelle is moves further away
def checkdistance(self): for pt in controlpoints: if distance(self.x,self.y,self.z,pt.x,pt.y,pt.z) <= 150: self.r += 5
vertices = [] controlpoints = [] triangles = []
maxdist = 0
#place some random organelles
def makeOrganelles(n): controlpoints[:] = [] # clear contents of the list for i in range(0, n): controlpoints.append(controlpoint()) controlpoints[0].r = 0
makeOrganelles(10)
for i in range(len(controlpoints)): if controlpoints[i].r >= maxdist: maxdist = controlpoints[i].r
maxdist += 30
#compute the size of gaps between vertices
print 'maxdist', maxdist gap = float(2*maxdist)/sidelength print 'gap', gap
#put vertices on the top and bottom of the cube
for i in range(sidelength + 1): for j in range(sidelength + 1): vertices.append(vertex(-maxdist + i*gap, -maxdist + j*gap, -maxdist)) vertices.append(vertex(-maxdist + i*gap, -maxdist + j*gap, +maxdist))
for i in range(len(vertices)): for j in range(len(vertices)): if (distance(vertices[i].x,vertices[i].y, vertices[i].z, vertices[j].x, vertices[j].y, vertices[j].z) <= 1.1*gap): if (distance(vertices[i].x,vertices[i].y, vertices[i].z, vertices[j].x, vertices[j].y, vertices[j].z) >= 0.5*gap): vertices[i].nbrs.append(vertices[j])
#compute a list of triangles which connect the vertices
for i in range(len(vertices)): for j in range(len(vertices[i].nbrs)): for k in range(j, len(vertices[i].nbrs)): vector1 = [vertices[i].nbrs[j].x - vertices[i].x, vertices[i].nbrs[j].y - vertices[i].y, vertices[i].nbrs[j].z - vertices[i].z] vector2 = [vertices[i].nbrs[k].x - vertices[i].x, vertices[i].nbrs[k].y - vertices[i].y, vertices[i].nbrs[k].z - vertices[i].z] crossproduct = cross(vector1, vector2) if crossproduct >= 1: triangles.append((vertices[i],vertices[i].nbrs[j],vertices[i].nbrs[k]))
for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == KEYDOWN: if event.key == K_ESCAPE: running = False elif event.key == K_RCTRL: toggle = not toggle elif event.key == K_RSHIFT: lock = not lock elif event.key == K_RETURN: makeOrganelles(10) elif event.key == K_LSHIFT: showVertices = not showVertices elif event.key == K_LCTRL: for pt in controlpoints: pt.clicked = False elif event.type == MOUSEBUTTONDOWN: for pt in controlpoints: pt.handleMouse(*mousepos, clicking_edge = True) elif event.type == MOUSEBUTTONUP: for pt in controlpoints: pt.clicked = False
bg.fill(background_colour)
#draw the control points and the triangles
for pt in controlpoints: pt.handleMouse(*mousepos) pt.display()
for i in range(len(triangles)): drawTriangle((0,0,100,linealpha), triangles[i], xoff=500, yoff=500) drawTriangle2((0,0,100,linealpha), triangles[i], xoff=1500, yoff=500)
# draw and update the vertices
for i in range(len(vertices)): if showVertices: vertices[i].display() if toggle: vertices[i].smooth() vertices[i].r = vertices[i].r*0.99 vertices[i].checkdistance()
if lock: # lock two of the vertices in place vertices[27].r = 600 vertices[27].colour = (0,255,0) vertices[29].r = 600 vertices[29].colour = (0,255,0)
Anyway, you're worried this is all unappreciated. It isn't, it's a great prototype, and you're showing awesome initiative with all this work. It's also really useful, cuz the current method you're using to mesh is what we'll likely be doing. Even if we use a different set of control parameters (for example, a user-defined spline that gets converted to 3D somehow), we'll still be doing the mesh-morphing thing you've figured out, so it's good to see that it will work. What other ideas do you have for what you could do with this? Is there any way you can force the neighborhoods of constrained points to be smooth?
tjwhale Theorist
Posts : 87 Reputation : 26 Join date : 2014-09-07
Subject: Re: Cell Membrane Sun Jan 25, 2015 8:01 am
Great! That's awesome. Thanks for all the encouragement I really appreciate it.
The stuff you've done to the program is really cool too, it's works really well now and looks beautiful!
I'll have a think about smoothing constrained points. It's not really a problem if the constraints are close to where the surface wants to be. It only looks sharp if you drag them really far out. I suppose it would be partially solved by having a "volume" control as well as a click and drag. That way if you wanted it bigger you would just pump it up a bit and only if you want specific shapes would you click and drag vertices around.
Another way would be to have the user grab a bigger chunk. So if a vertex is set to 600 then all it's neighbours are constrained to 575-625.
I tried it, it's a bit better
Code:
if lock: # lock two of the vertices in place vertices[27].r = 600 vertices[27].colour = (0,255,0) for i in range(len(vertices[27].nbrs)): vertices[27].nbrs[i].r = 575
Another option is to let the user put in "shadow organelles" which morph the surface more naturally and smoothly. That way if you want it sharp you can move the vertices, if you want it soft you put in a shadow oragnelle.
tjwhale Theorist
Posts : 87 Reputation : 26 Join date : 2014-09-07
Subject: Re: Cell Membrane Sun Jan 25, 2015 1:43 pm
Taking this video as inspiration
I tried adding movement and some lunging behavior. I think it looks quite good, it's not as dynamic as the real cell. I'd like a more focussed / pointy lunge aswell but that is hard to get right (with the system I am currently using).
Code:
#This code is a tiny bit different from what I used to make the video but basically the same.
#I have tried to put comments in the code to hopefully make it easier to understand in case anyone is reading it.
#make a cube around the organelles which is then smoothed into place, compute all triangles in the mesh
#setup
import pygame import math import sys import random from pygame.locals import * import time from pygame.mouse import get_pos start_time = time.time()
# this is where the vertices get smoothed. They try sum the distances from their neighbours to the origin. # then they subtract their own distance multiplied by the number of neighbours. # this gives a measure of if they are above or below average. They then move to become more average
def smooth(self): laplacian = 0 for i in range(len(self.nbrs)): laplacian += self.nbrs[i].r laplacian -= len(self.nbrs)*self.r self.r += 0.1*laplacian self.x = self.r*math.sin(self.theta)*math.cos(self.phi) self.y = self.r*math.sin(self.theta)*math.sin(self.phi) self.z = self.r*math.cos(self.theta) self.norm = distance(self.x,self.y,self.z,0,0,0)
#if a vertx gets too close to an organelle is moves further away
def checkdistance(self): for pt in controlpoints: if distance(self.x,self.y,self.z,pt.x,pt.y,pt.z) <= 150: self.r += 20
def makeOrganelles(n): controlpoints[:] = [] # clear contents of the list for i in range(0, n): controlpoints.append(controlpoint()) controlpoints[0].r = 0
makeOrganelles(10)
for i in range(len(controlpoints)): if controlpoints[i].r >= maxdist: maxdist = controlpoints[i].r
maxdist += 30
#compute the size of gaps between vertices
print 'maxdist', maxdist gap = float(2*maxdist)/sidelength print 'gap', gap
#put vertices on the top and bottom of the cube
for i in range(sidelength + 1): for j in range(sidelength + 1): vertices.append(vertex(-maxdist + i*gap, -maxdist + j*gap, -maxdist)) vertices.append(vertex(-maxdist + i*gap, -maxdist + j*gap, +maxdist))
for i in range(len(vertices)): for j in range(len(vertices)): if (distance(vertices[i].x,vertices[i].y, vertices[i].z, vertices[j].x, vertices[j].y, vertices[j].z) <= 1.1*gap): if (distance(vertices[i].x,vertices[i].y, vertices[i].z, vertices[j].x, vertices[j].y, vertices[j].z) >= 0.5*gap): vertices[i].nbrs.append(vertices[j])
#compute a list of triangles which connect the vertices
for i in range(len(vertices)): for j in range(len(vertices[i].nbrs)): for k in range(j, len(vertices[i].nbrs)): vector1 = [vertices[i].nbrs[j].x - vertices[i].x, vertices[i].nbrs[j].y - vertices[i].y, vertices[i].nbrs[j].z - vertices[i].z] vector2 = [vertices[i].nbrs[k].x - vertices[i].x, vertices[i].nbrs[k].y - vertices[i].y, vertices[i].nbrs[k].z - vertices[i].z] crossproduct = cross(vector1, vector2) if crossproduct >= 1: triangles.append((vertices[i],vertices[i].nbrs[j],vertices[i].nbrs[k]))
for i in range(len(triangles)): drawTriangle((0,0,100,linealpha), triangles[i], xoff=centre[0], yoff=centre[1])
# draw and update the vertices
for i in range(len(vertices)): if showVertices: vertices[i].display() if toggle: vertices[i].smooth() vertices[i].r = vertices[i].r*0.99 vertices[i].checkdistance() if counter <= off: vertices[i].lunge() counter += 1 if counter >= on: counter = 0
Posts : 318 Reputation : 56 Join date : 2013-09-30 Age : 29 Location : hanging from the chandelier
Subject: Re: Cell Membrane Sun Jan 25, 2015 8:38 pm
So after playing around with it a bit, i see too much pinching going on in the trailing edge. I think, to get the lunging behaviour you want, you should move the organelles instead, and let the membrane naturally flow towards the changing equilibrium position, instead of making the membrane itself do the lunging.
Maybe set the organelles up as their own dynamical system, using a linear attraction term and inverse-square repulsion (or similar), which should keep them constantly tumbling past each other, but never too close. Then, have a time-varying attraction-to-mouse term, which falls off with distance. This is the tricky bit I suspect, since you want the microbe to not just shift towards the attractant, but lunge, which requires one or two control points to move substantially faster than the rest at times.
tjwhale Theorist
Posts : 87 Reputation : 26 Join date : 2014-09-07
Subject: Re: Cell Membrane Mon Jan 26, 2015 6:38 am
That sounds cool.
One way I guess is to give the organelles different masses. So the nucleus can be big and then that is the center from which the mesh is measured. Then there are other smaller organelles which move around a lot quicker. They would lunge first towards something and then the bulky big organelles would be dragged along behind them.
I'll have a go later at getting it working.
tjwhale Theorist
Posts : 87 Reputation : 26 Join date : 2014-09-07
Subject: Re: Cell Membrane Mon Jan 26, 2015 3:11 pm
Moopli your suggestion worked pretty well. I rewrote a lot of the code to work with vectors (as that made thinking about the formulas a lot easier).
This verison makes half as many triangles, which is weird. Also I haven't got the attraction effect decreasing if the mouse is further away, in fact it increases!
You can see all the little organelles move around quickly and they drag the big nucleus behind them. The mesh is always centered on the nucleus.
Code:
import pygame import math import sys import random from pygame.locals import * import time from pygame.mouse import get_pos start_time = time.time()
# this is where the vertices get smoothed. They try sum the distances from their neighbours to the origin. # then they subtract their own distance multiplied by the number of neighbours. # this gives a measure of if they are above or below average. They then move to become more average
def smooth(self): laplacian = 0 spherical = tospherical(self.pos) for i in range(len(self.nbrs)): laplacian += self.nbrs[i].r laplacian -= len(self.nbrs)*self.r spherical.x += 0.1*laplacian self.r = spherical.x self.pos = tocartesian(spherical) self.norm = norm(self.pos)
#if a vertx gets too close to an organelle is moves further away
def checkdistance(self): truelocation = self.pos + Vector(centre[0],centre[1],centre[2]) for pt in controlpoints: if distance(truelocation, pt.pos) <= 100: spherical = tospherical(self.pos) spherical.x += 30 self.pos = tocartesian(spherical)
#initialise
vertices = [] controlpoints = [] triangles = []
#place some random organelles
def makeOrganelles(n): controlpoints[:] = [] # clear contents of the list for i in range(0, n): controlpoints.append(controlpoint()) controlpoints[0].pos = Vector(500,500,0) controlpoints[0].mass = 20
makeOrganelles(10)
maxdist = 0
for i in range(len(controlpoints)): if distance(controlpoints[i].pos, controlpoints[0].pos) >= maxdist: maxdist = distance(controlpoints[i].pos, controlpoints[0].pos)
maxdist += 30
#compute the size of gaps between vertices
print 'maxdist', maxdist gap = float(2*maxdist)/sidelength print 'gap', gap
#put vertices on the top and bottom of the cube
for i in range(sidelength + 1): for j in range(sidelength + 1): vertices.append(vertex(-maxdist + i*gap, -maxdist + j*gap, -maxdist)) vertices.append(vertex(-maxdist + i*gap, -maxdist + j*gap, +maxdist))
for i in range(len(vertices)): for j in range(len(vertices)): if (distance(vertices[i].pos,vertices[j].pos) <= 1.1*gap): if (distance(vertices[i].pos, vertices[j].pos) >= 0.5*gap): vertices[i].nbrs.append(vertices[j])
#compute a list of triangles which connect the vertices
for i in range(len(vertices)): for j in range(len(vertices[i].nbrs)): for k in range(j, len(vertices[i].nbrs)): vector1 = direction( vertices[i].pos, vertices[i].nbrs[j].pos ) vector2 = direction( vertices[i].pos, vertices[i].nbrs[k].pos ) crossproduct = cross(vector1, vector2) if norm(crossproduct) >= 1: triangles.append((vertices[i],vertices[i].nbrs[j],vertices[i].nbrs[k]))
for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == KEYDOWN: if event.key == K_ESCAPE: running = False elif event.key == K_RCTRL: toggle = not toggle elif event.key == K_RSHIFT: lock = not lock elif event.key == K_RETURN: makeOrganelles(10) elif event.key == K_LSHIFT: showVertices = not showVertices elif event.key == K_LCTRL: for pt in controlpoints: pt.clicked = False
bg.fill(background_colour)
for i in range(len(controlpoints)): controlpoints[i].display() if not lock: controlpoints[i].move() if counter <= 10: controlpoints[i].pos += (waytogo*0.8)/controlpoints[i].mass else: controlpoints[i].pos += (waytogo*0.3)/controlpoints[i].mass
for i in range(len(triangles)): drawTriangle((0,0,100,linealpha), triangles[i], xoff=centre[0], yoff=centre[1])
for i in range(len(vertices)): if showVertices: vertices[i].display() if toggle: vertices[i].smooth() vertices[i].pos = vertices[i].pos*0.99 vertices[i].checkdistance()