We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello!
I am trying to randomly place and orient ellipsoids in 3D space using Shapes 3D Library. The ultimate goal is to model the random placement and orientation of synapses (components of brain cells) in 3D space.
Here is a drawing of what I hope to do
So far, I have been able to place just one ellipsoid in 3D space using Shapes 3D Library (see code below). I am unsure as to how to proceed to randomly place several ellipsoids.
Specifically, I am very confused about what parameters synapse.draw() can take. Could I input random x, y, and z values? What if I want to rotate the ellipsoids in random orientations?
Before you answer... I am not looking for a fully-coded answer to how to achieve my ultimate goal (this defeats the purpose of learning, I think). Rather, I am looking for some helpful advice on how to take the next steps going forward.
Note: I am using Mac OS X and Processing 2
// PeasyCam library for an easy-to-use camera
import processing.opengl.*;
import peasy.*;
PeasyCam cam;
// Shapes 3D library for creating 3D shapes like ellipsoids
import shapes3d.utils.*;
import shapes3d.animation.*;
import shapes3d.*;
// A "synapse" is part of a brain cell that can be modeled as an ellipsoid
Ellipsoid synapse;
void setup() {
size(500, 500, OPENGL);
cam = new PeasyCam(this, 100);
cam.setMinimumDistance(50);
cam.setMaximumDistance(500);
synapse = new Ellipsoid(this, 15, 15);
synapse.setRadius(15, 10, 10);
synapse.fill(#19BF38);
synapse.drawMode(Shape3D.TEXTURE);
}
void draw() {
lights();
directionalLight(255, 255, 255, -1, 0, 0); // Ambient white light
background(0);
synapse.draw();
}
Answers
you need to learn about transformations. http://processing.org/tutorials/p3d/
to position the object in 3d space you need a translate: http://processing.org/reference/translate_.html
to rotate it you use http://processing.org/reference/rotate_.html
transformation are a bit hard to get used to. maybe you check out first how this is done in 2d space: http://processing.org/tutorials/transform2d/
You need to look at the examples and reference that come with Shapes3D but just to give a brief explanation why the draw() method takes no parameters.
Every shape that you create with Shapes3D stores its own current position and rotation in 3D space. The draw() method will draw the shape in its current position and with its current rotation. If you want it to appear somewhere else or with a different rotation then there are a whole bunch of methods that you can use to move and rotate the shape e.g. moveTo(), moveBy, rotateTo, rotateBy etc. You can find them in the Shape3D class API reference that comes with the library.
Thanks so much, @mschi and @quark !
I think I got this all figured out except that... - My camera (using PeasyCam Library) does not work - All of my synapses are oddly clustered in the bottom right corner of the window
Any help would be much appreciated!
OK you are getting the idea but there are several mistakes/errors. Of these two are particularly important
1) You create a single Ellipsoid and try and draw it in different locations. Instead you should create a new Ellipsoid for every location you want to see one.
2) The drawSynapse method is being called every frame but a new Ellipsoid is being created in line 83. You should try and avoid creating complex objects inside the draw loop it will have significant impact on performance.
The other mistakes are straightforward
In Processing and this library angles are expressed in radians not degrees so instead of using the range 0-360 it should be 0-2 Pi.
The reason the synapses all occur in one quadrant is because the calculated x/y/z values are positive and the origin (0,0,0) is in the centre of the display.
Anyway I have recreated the sketch taking into account all these points so you have a good base to work from. PeasyCam also works in this example.
BTW
drawMode(Shape3D.TEXTURE);
is only needed if you have set the texture using a bitmap image.Hi @quark
Thank you so much for the thorough help! I'm guessing you are the author of the Shapes 3D library so thank you for that as well!
I've been working for two and a half hours since you posted your latest reply in an attempt to ensure that no synapses overlap with one another.
If you don't mind, I had just a few more questions:
-- Every now and then when I run the program, two or more synapses will overlap despite my best efforts. Can you see any problems in my code?
Screenshot of overlap
-- Sometimes when I run the program, I will get a grey screen and java.lang.NullPointerException. Where is this coming from?
Screenshot of error in console
-- What should I use instead of drawMode(Shape3D.TEXTURE); ?
Note: Any code specifically written for the purposes of preventing synapses from overlap is preceded by a comment of the form:
Yes I am the creator of Shapes3D if you are interested inmy other libraries and tools have a look at my website.
The algorithm you are using is very inefficient in that the time taken to calculate the synapse positions is proportional to the square of number of synapses. It means that if you double the number of synapses then you quadruple the time needed.
So I have not modified your code, but I have modified mine. The algorithm is linear so that the time taken is proportional to the number of synapses. It means that if you double the number of synapses then you only double the time needed.
The only thing to watch out for is that
`8 * gmax * gmax * gmax > 10 * nbrSynapses'
This would mean at worst there is a 1 in 10 chance of having to recalculate values of gx, gy and gz.
Hi @quark
I sincerely appreciate you sticking with me. I'm sure you've got a lot of other stuff going on so thank you for your time.
Regarding your new code, I worked through it and was wondering about two things:
First, are we taking into account the possibility that gx, gy, or gz could equal zero? That would mean for example that gx could be -3, -2, -1, 0, 1, 2, 3 amounting to 7 not 6 possible values.
In total, there would then be 7x7x7 = 343 possible positions rather than 216 possible positions, correct?
Second, would it make sense to better ensure absolute uniqueness of each synapse position by calculating:
Instead of:
Or is such a modification superfluous?
Thanks so much once again for your help :)
Update:
I realized that
Does not work but I can't figure out why.
maybe because gx etc. can be negative
you could add gmax to a copy of them before your formula
Sorry there was a mistake in the code line 54 (well spotted) it should have been
gvalue = 1000000 * gz + 1000 * gy + gx;
this will guarantee that gvalue is unique for any combination of gx, gy and gz and it doesn't matter if they are negative or positive provided gmax < 1000 (which shouldn't be a problem).
PS I have corrected the original code posted above.
Normally random(a, b) will produce a float in the range >=a and <b but I am rounding the output so whether there are 216 or 343 possible values then mmmm... :-/ I will leave that for you to discover.
Hi Quark,
Thanks again for the reply.
The use of gvalue is pretty cool!
@Chrisir, thanks for the suggestion. I think it works with negative numbers where say,
would give you a gValue of 1,000,977. While not explicitly representative of gX, gY, and gZ, the gValue is nonetheless unique to the particular gX, gY, and gZ.
Also, Quark, I am going to go with the notion that there are 343 possible positions given your definition of rounding.
Thanks again so much for all your help these past couple of days!
I ran the following code
and the output below shows that the range is -3 to +3 inclusive, 343 possibilities are it
Hi @quark,
I ran my code by the graduate student with whom I am working (no surprise here but I'm an undergraduate dabbling in code) and we came upon a roadblock to achieving our goal:
Our goal is to model the random placement and orientation of synapses in 3D space as accurately as possible.
The program, however, keeps synapses from touching with the following condition:
The centers of two synapses cannot be closer than
2*maxSemiAxis
The issue here is that this does not allow for the situation in which the centers of two synapses are CLOSER than
2*maxSemiAxis
BUT still do not touch.An example of this is two synapses nearly stacked upon each other. Their centers are closer than
2*maxSemiAxis
but the synapses most definitely do not touch. Such a situation is never drawn by the program. I have made a drawing of this here:http://prntscr.com/34h33e
Would you happen to have any ideas on how to keep synapses from touching in every situation? I know this makes the problem a whole lot more complicated and I am at a loss about where to start.
Many Thanks,
Ian
Spheres would be easy but you are talking about the intersection of two 'rugby ball shaped' objects and the maths would be horrendous. I did a quick Google and even the maths for two 2D-ellipses was beyond me.
Effectively you are looking at collision detection and this is a very time consuming process so most techniques work on using spheres and axis-aligned boxes to reduce the level of computation. For more complex shapes the level of computation can be reduced by modeling them with one or more simpler (sphere/box) shapes and in most scenarios this is close enough.
The problem will get worse as you increase the number of synapses. Consider the situation where you have
n
synapses then to prevent collisions you have to test every synapse against every other synapse, in other wordsn(n-1)
or ~n
squared. So you double the number of synapses and quadruple the number of collision detections. There are techniques to improve on that e.g. quadtrees for 2D (see it in action here) and octrees for 3D but they are sophisticated techniques.Before making a reaching a decision you need to consider
1) How many ellipsoids are there going to be?
2) The density of synapses. The greater the density (smaller the distance between them) the more likely to get collisions.
3) The level of intersection permitted. As you move the viewpoint away from the synapses the less likely you are to notice any intersection.
The other thing to consider is that in real life synapses are not solid ellipsoids so maybe you are being a little over zealous.
One other question, because human biology is not my specialist area, are synapses randomly orientated or are they not aligned, perhaps with just minor random deviation, along some axis?