I have begun developing the first of a long series of Processing sketches for use in a high school chemistry curriculum. The idea is to use simulations of molecular activity to supplement lab and reading activity in learning chemistry concepts. So far Processing has been a great tool for this project; my supervisor has been pleased with the functionality of Processing visualizations over previous Flash and Netlogo attempts.
I've run into a particular problem with molecule interactions, however. My question:
How can I make two irregular shapes, floating across the Processing canvas, "bounce" off of one another when they overlap?
Initially, I was rendering molecules in Processing with a series of different sized ellipses; making molecules bounce was a matter of calculating the radii of the atoms in a molecule, returning these radii in an array, and checking the array against the radii array of another molecule; if any radii overlapped, the molecules would bounce. Pretty straightforward.
However, the visual sophistication and variation between various molecules, in addition to requests for frequent updates in molecular structure and appearance, has pushed me toward creating the molecules in Adobe Illustrator, and importing Illustrator SVG files into Processing for use in my sketches. Thus, since the files are SVG imports, I don't think I have access to their boundaries... the only thing I can think of is calculating which pixels the shapes occupy: this seems a horrible kluge, and I'm not sure how to do it.
Does anyone have any other ideas? I'm all ears.
If you would like to see an early version of this project (with molecules drawn via Processing ellipses):
For actual physical-like collision I would recommend to have a look at Fisica (http://www.ricardmarxer.com/fisica) However by looking at your applet, I noticed you will need to have 2 circles sticked together, and that is still not possible with the Fisica library (I still have to work out a good API for composite bodies). But maybe you can work around it by adding to rotation joints between the bodies...
The other solution is to actually build a polygonal body in Fisica and calculating yourself (or with Geomerative) the vertices of a polygon that is made by two overlapping circles.
Ups sorry... I just read further and see that you want to have SVGs. Well I guess then your best solution is the second one I posted above. Add together all the shapes in the SVG into one big polygon and create a FPoly (polygonal body) where the vertices are those of the big polygon.
I might be a little ignorant of the possible potential of using SVGs, then...
Here is an example of an irregular molecule... two hydrogen and one oxygen (H2O). It's just a PNG, but imagine it a an SVG:
So, all three irregular shapes combine to create one big irregular shape, which is then imported as an SVG. So, at this point I'm not planning on modeling the molecule in code at all... just importing an SVG to use which I made in Illustrator.
So ricardmp, are you saying I should split the SVG code into three shapes (one oxygen and two hydrogen), then rebuild them with FPoly? Please pardon my confusion.
If it is one big shape then it is great. The important thing is that the contour of your molecule is a shape on it's own so that Geomerative can break it into vertices and then Fisica can use those vertices for the FPoly.
In the image you can see highlighted in orange what I mean with the contour. This should be a separate path or group in the SVG, and to easily retrieve it in Geomerative, give it an id. In the SVG put id="contour".
If you find all this too complicated you can also just have two images:
an SVG that only has the contour of the molecule (you use it to access it's points with Geomerative's getPoints() and use them as vertices of the FPoly)
the PNG with your molecule as the image you posted on top (which you attach to the FPoly using attachImage())
@kooogy, yeah, that was my first idea! But my boss didn't like it very much. Besides, once you use an SVG, then you'll still have to calculate the circle radius somehow.
@ricardmp, I think your analysis is spot on. Now I just need to figure out how to give an id to a shape in an SVG. I'm sure I can go in with a text editor and edit each shape... but any idea if you can do this in Illustrator? [edit... turns out Illustrator simply uses layer names for ids]
I'm sure I will have plenty of questions later on about how Geomerative works, but this certainly gets me started. Thanks again.
The bounding circle (or rectangle) isn't a bad idea actually: if you first check against these simpler shapes, it will be faster to eliminate shapes not close enough. Then you can do a finer check if the bounds intersect.
Well, Geomerative is making me feel really stupid. I've spent several days banging my head against it, and I'm not getting anywhere. Would someone please help me to understand what I'm doing wrong?
I have a gray background (id="bg")in my SVG which is set to display="none". Why is Geomerative rendering it? Can I turn it off?
The edge of the molecule seems to be the edge of the sketch. If I make the sketch bigger, the molecule gets bigger. I assume this is because of the shp.centerIn() method, but all I want is to render my SVG at 1:1 size, and at the molecule's center.
How can I get the contour of my shape? I tried using shp.getChild(), but the only difference seems to be that it loses its fill colors. In fact, I can't setFill on this child shape later on... this might be a bug.
At any rate, since I can't isolate the contour, the shapes always overlap.
I see that there is a translate method for RMatrix. Is there an equivalent translate method for RShape? I assume using pushMatrix/popMatrix isn't ideal, but I don't know how else to do it.
And, what is the difference between RContour, RShape, RSubshape and RPolygon? I'm really confused... they're all asked for in different methods, and I can't seem to convert between them, even though they all seem to have the same methods.
Yep, the "display" attribute is not implemented in Geomerative. I'll check how easy it is to add.
If you want a 1:1 scale then you should not use .centerIn()
Normally you should just use RShape, the rest of classes are just there to provide backwards compatible and for optimization purposes. If you find a function that you need and it requires something else than a RShape then let me know and I will try to fix it.
Could you send me the water SVG to check what's going on?
For the time being, I just used an ellipse to get a boundary to work with, so I'm not SOL or anything. Thanks for that advice.
The Geomerative library looks stellar, very exciting. Even though last week I was a bit frustrated, I still would like to get this to work. I'll spend some more time this week seeing if I can figure it out.
Ok. I see what's going on. Even if the 'display' attribute was honoured in Geomerative (which is not!) the shape would be quite big in size and therefore hard to use directly in Fisica. However all RShape s in Geomerative have a function called transform() that can take four coordinates of a new bounding box and will rescale a shape to fit in it.
So you can simply load the whole SVG, get the child named "molecule" and transform it to fit in a rect (e.g. )
RShape mySvgShape = RG.loadShape("Water.svg");
// This is the shape that will be used for drawing
The only issue I'm still having is that my SVGs don't pop up centered on the mouse cursor
I didn't make any modifications to the source code (linked from your example). In Illustrator I removed from the SVG all non-functioning layers, the image is centered XY, and the artboard now matches the bounding box of the image. I also tried exporting the SVG from Inkscape... no dice.
processing 1.2, fisica 0.1.6, geomerative 32
[edit: turns out that Illustrator messed up my SVG... my sketch is now working correctly. Thanks Ricard, a whole lot.]
...you may ask the devil's advocate question, and I can answer sheepishly "I didn't know they existed." I guess in my google searches I wasn't using the correct keywords or something.
On the other hand, we have pretty specific needs, in that the interface and molecule shapes/colors need to be very particular (i.e. grounded in research we're currently performing), and Processing seems to offer the flexibility to allow us to modify these systems totally.
Is there any software you have used or recommend, in particular something I could interface with Processing? I'm open to other approaches, of course.
I would not do the graphics first, but first think about which force field to use and how to calculate the motions.
With a good force field (e.g. Lennard-Jones potential or similar terms for intermolecular interaction), there is no need to calculate the collisions from the shapes of the molecules. In contrast to your inelastic collision model (the disc model used in the 1950ies), collisions between molecules are elastic, and the type of the potential function takes into account that molecules can't come closer than the sum of the atomic radii.
Also think first about the data model to represent the molecules (connect table with atoms, their radii, and the bonds and angles between them, and if you would like to simulate the atomic vibrations of the molecule atoms, also about the forces (bond, angle, torsion) between them), then about the graphics that is associated with the molecules. You can still use SVG for the graphics, but these must have an associated molecule data model.
Molecular dynamics software such as VMD (solvents, small and large molecules) or GULP (solids), both available free, offer a variety of force fields and algorithms to simulate the motions.
this is excellent criticism, and thanks. I have just discovered (like last week) the TCBG at UIUC, and I have sent an email introducing our project.
Our project isn't fundamentally about exact molecular modeling, however, even though we want to be as close as reasonable. It's tempting to open the Pandora's Box of accurate, 3D representations, and for an eventual 2.0 version I will seriously investigate integrating the systems you mention. They're very sexy. But part of our limitation is this software needs to run on sub-commodity, 5yr-old, public school Dell laptops. 3D probably isn't an option at this point, and once I smoosh molecules to 2D, my recent research indicates it more-or-less renders true-to-life dynamic modeling moot. Although it's not the most advanced model in existence, the inelastic, radius-based model of atoms seems adequate for our purposes, and carries the advantage of being instantly grokkable by high-schoolers without chemistry experience. Basically, it seems easier to see chemical reactions in 2D than 3D when you have a solution of 200 atoms, each begging for your attention.
I'm working with a cadre of chemistry PhDs who are pushing hard to make the simulations as close to accurate as possible, so we don't convey more incorrect information than we need to. To me, it seems most important to have a clear, well-designed GUI, and this is my initial priority; we have a linear development cycle, and I'm already behind on delivering usable animations for our first few curriculum lessons. Basically, my goal is to get animations and interactivity that *resembles* correct molecular interactions, in a controlled, abstract 2D world. I'd like to get as close as possible, of course, but I'll have to cut some corners to get this off the ground.
So right now, having believable 2D physics is good enough for me... :)
Leave a comment on niteshade's reply
Change topic type
Link this topic
Provide the permalink of a topic that is related to this topic