Hi there!
Does anybody know how many calculation is done in processing per second? I would like to create a simple aeroplane simulator and I am wondering if processing would manage with real-time calculations including: wind (Navier-Stokes equations), steering input, forces applied to the aeroplane and position as a final result on the end of each loop. So far I’ve managed to do it in a very simplified version without any phisics involved, however I would like to make sure if it would be possible before I even start it.
Thank You for Response
There is no real answer to that because it depends on the complexity of the calculation.
If you are using Java mode then Processing will have no problem doing what you describe. I cannot be certain of other modes e.g. Javascript and Python.
You can start by exploring current physics libraries to have a feeling of what to expect for physics engines. Some posts to explore:
- https://www.youtube.com/watch?v=wB1pcXtEwIs&vl=en
- Libraries / Processing.org
- 2D Physics engine made with Processing - Processing 2.x and 3.x Forum
Physics equations in this case will be based on time parameters. You can obtain the current time elapsed since the beginning of the sketch by using the millis()
function, which keeps track in milliseconds. You calculate the value of those equations at the current time state return by this function.
You can find Physics + time + Processing in this post thinking along the time of game engines: Processing Tutorial: Building a Simple Game | Toptal®
I would like to attach a sample code below where I show a blocking and non blocking plane roll indicator. The one of top is always displayed. The one at the bottom only update if not being blocked. This is to show that physics calculations depends strictly on the current time and it is independent of the draw cycle. Note the effect is to be explored from the perspective of the effect seeing in the sketch when it is running. The code does not represent actual physics “time” calculations but it is more of cheat by introducing random blocking times for one of the indicators. This would be the effect if your calculations were heavy. If this were to happen, you will need to investigate ways to optimize your code or your actual calculations.
Kf
//REFERENCES:
//===========================================================================
// GLOBAL VARIABLES:
boolean blockDrawing=false;
int drawAgain=0;
Plane mainPlane;
Plane skippyPlane;
//===========================================================================
// PROCESSING DEFAULT FUNCTIONS:
void settings() {
size(400, 600);
}
void setup() {
textAlign(CENTER, CENTER);
rectMode(RADIUS);
noStroke();
mainPlane=new Plane("Main Plane", width*0.5, height*0.25, 0);
skippyPlane=new Plane("Skippy Plane", width*0.5, height*0.75, 0);
}
void draw() {
background(20);
float rotationAngle=map(millis()%5000, 0, 5000, 0, 2*PI);
//Only update if in not-blocking state
if (!blockDrawing) {
skippyPlane.ang=rotationAngle;
}
skippyPlane.draw();
mainPlane.ang=rotationAngle;
mainPlane.draw();
//About every two seconds, block and set the next time to unblock
if (frameCount%180==0 && !blockDrawing) {
//delay(int(random(0.5,1)*1500));
int blockDuration = int(random(0.5, 1)*1500);
blockDrawing=true;
drawAgain=millis()+blockDuration;
}
//Unblock directive
if (millis()>drawAgain) {
blockDrawing=false;
}
}
//===========================================================================
// OTHER FUNCTIONS:
class Plane {
final int RULER_HALF_LEN=75;
final float PLANE_BODY=PI*1.25;
final float PLANE_WIDTH=80;
final float PLANE_HEIGHT=50;
final float START_ANGLE=-PI*1.25;
final float STOP_ANGLE=PI/4;
float px, py, ang;
String theLabel;
Plane(String label, float posX, float posY, float angle) {
theLabel=label;
px=posX;
py=posY;
ang=angle;
}
void draw() {
pushMatrix();
translate(px, py);
fill(188);
text(theLabel, width/3, 0);
rotate(ang);
drawPlaneBody();
popMatrix();
}
void drawPlaneBody() {
//Plane axis: white
fill(220);
rect(0, 0, RULER_HALF_LEN, 2);
//Plane body: Red
fill(240, 0, 0);
arc(0, 0, PLANE_WIDTH, PLANE_HEIGHT, START_ANGLE, STOP_ANGLE, PIE);
//Plane wing's marker
fill(250, 150, 0);
ellipse(-RULER_HALF_LEN, 0, 5, 15);
fill(0, 150, 0);
ellipse(RULER_HALF_LEN, 0, 5, 15);
}
}
What does “real-time” mean for you? 30fps, 60fps?
If you have target hardware, and a target fps, then there are a few simple tests you can do to ballpark calculations/speed – create a test operation, such as drawing random circles (or analyzing images, or whatever kind of activity you are doing), then put it in a variable length for-loop and watch the program FPS grind to a halt at some order of magnitude. You can even set your program to exit when it detects that you are failing to meet a minimum acceptable frameRate – although keep in mind that frameRate can fluctuate.
/**
* FrameRateLoadTest
* 2020-03-05 Jeremy Douglass
* Processing 3.4
* https://discourse.processing.org/t/speed-of-calculations/17862/
*
* Define a loadTest that increases, then run sketch until
* it fails to meet a defined minimum frameRate.
* Use this to make quick ballpark estimates of performance
* of specific tasks on specific hardware.
*/
float minFrameRate = 30.0;
void setup() {
size(400, 400);
}
void draw() {
background(128);
// exits if average framerate drops below minimum
if (frameRate<minFrameRate && frameCount>10) { // ignore initial long frames
println("frameRate " + frameRate + "<" + minFrameRate + " on frame " + frameCount);
exit();
}
// perform an operation that scales up
// the longer the sketch runs
loadTest(frameCount);
}
void loadTest(int load) {
for (int i=0; i<load; i++) {
fill(random(255),random(255),random(255), 128);
ellipse(random(width), random(20, height), 20, 20);
}
text(load + " " + frameRate, 10, 10);
}
…but it will still depend a lot on the kinds of calculations / operations. Addition is faster than division or logarithms. Accessing / updating graphics and pixel buffers might be very fast or very slow depending on the specifics of how you do it. Some graphics operations have a completely different performance profile while done through shaders / on GPU vs CPU… et cetera. Given all that, quick tests can help a lot with planning.
Interesting test I’ve set up a timer and with an average of 10 tries it takes very close to 9 seconds to exit the sketch on my modest computer.
Adding a timer might be helpful – and averaging over multiple runs is definitely helpful!
Note however that the final printed load is the key number, not elapsed time – so if you are averaging ~500 load (frameCount) on exit, then at around 500 random ellipses per frame is when your computer can’t maintain 30fps anymore, and you could plan accordingly.