Processing append float[] - processing

Im working on a Processing App wich is supposed to grap data from a serial port and put in into various graphs. I've downloaded the giCentre Utilities libary to draw the graphs.
Based of one of the examples i got it to plot a simple graph, but since it will be grabbing data from the serial port in real-time i need to be able to add data. Im trying to use the Append() function, but without any luck.
import org.gicentre.utils.stat.*; // For chart classes.
float[] test = {1900, 1910, 1920, 1930, 1940, 1950, 1960, 1970, 1980, 1990};
float[] test2 ={ 19000, 6489, 6401, 7657, 9649, 9767, 12167, 15154, 18200, 23124};
XYChart lineChart;
/** Initialises the sketch, loads data into the chart and customises its appearance.
*/
void setup()
{
size(500,200);
smooth();
noLoop();
PFont font = createFont("Helvetica",11);
textFont(font,10);
// Both x and y data set here.
lineChart = new XYChart(this);
append(test, 2050);
append(test2, 21000);
lineChart.setData(test, test2);
// Axis formatting and labels.
lineChart.showXAxis(true);
lineChart.showYAxis(true);
lineChart.setMinY(0);
lineChart.setYFormat("###");
lineChart.setXFormat("0000");
// Symbol colours
lineChart.setPointColour(color(180,50,50,100));
lineChart.setPointSize(5);
lineChart.setLineWidth(2);
}
/** Draws the chart and a title.
*/
void draw()
{
background(255);
textSize(9);
lineChart.draw(15,15,width-30,height-30);
}
Isn't the line
append(test, 2050);
append(test2, 21000);
supposed to add a new datapoint at (2050, 21000) ? It would be nice to only have to call these every time serial data comes in and then redraw the plot.
Any help or advice is much appreciated.

The append() function returns the appended array. append(test, 2050) doesn't actually change the test array, it returns an array equivalent to test with 2050 appended to it. So you should be able to do the following:
test = append(test, 2050);
test2 = append(test2, 21000);
EDIT:
Here is the documentation on the Processing Reference page: append(). And here is some code which can be run as a simple test (or learning tool):
void setup()
{
int[] a = {1, 2, 3};
int[] b;
b = append(a, 4);
print(a.length + "\n");
print(b.length);
}
which returns
3
4

Related

How can put image back of paints which i drew?

The thing what I want to make is similar to paint program.
The problem is when I draw some lines(Not just lines. Whole things I drew are included in this case.), those lines only drawn back of a image I put in before I draw that.
At first, I thought it was just problem of code's order. But it wasn't.
I just want draw some lines on the image like paint program.
Like this:enter image description here
You can paint into a separate "layer" using PGraphics.
Once you initialise an instance you can use the typical drawing methods within beginDraw() / endDraw() (as the reference example suggests).
The only thing left is to save the final image which is simple enough using save()
Here's a modified example of Examples > Basics > Image > LoadDisplay which uses a separate PGraphics instance to draw into as the mouse is dragged and saves the final image when the s key is pressed:
/**
* Based on Examples > Basics > Image > Load and Display
*
* Images can be loaded and displayed to the screen at their actual size
* or any other size.
*/
PImage img; // Declare variable "a" of type PImage
// reference to layer to draw into
PGraphics paintLayer;
void setup() {
size(640, 360);
// The image file must be in the data folder of the current sketch
// to load successfully
img = loadImage("moonwalk.jpg"); // Load the image into the program
// create a separate layer to draw into
paintLayer = createGraphics(width,height);
}
void draw() {
// Displays the image at its actual size at point (0,0)
image(img, 0, 0);
// Displays the paint layer
image(paintLayer,0,0);
}
void mouseDragged(){
// use drawing commands between beginDraw() / endDraw() calls
paintLayer.beginDraw();
paintLayer.line(mouseX,mouseY,pmouseX,pmouseY);
paintLayer.endDraw();
}
void keyPressed(){
if(key == 's'){
saveFrame("annotated-image.png");
}
}

Running background in P5

Im trying to make a side-scroller game and I got stuck on the running background part. I've looked for solutions and I've discovered some , but they were using javascript not the p5 library.
I started from the tutorials found on The Coding Train , and looked over all the examples and references on their site.
Although I could avoid this by using something else, just for the sake of it being here in case someone gets stuck on the same issue, could anyone offer a solution to this in p5? Disclaimer: Im a total noob p5.js.
later edit : By running background i mean moving Background image in a loop from left to right
Honestly, from the discussion we had in the comments, it sounds like you're overthinking it.
The general approach to animation (that tutorial is for Processing, but the principles apply to P5.js as well) is as follows:
Step 1: Create a set of variables that represent the state of your scene.
Step 2: Use those variables to draw your scene every frame.
Step 3: Change those variables over time to make your scene move.
You already know what to do: load an image that contains your background, then draw that image, and move it a little bit each frame.
You've said you want to call the background() function instead of the image() function, which doesn't make a ton of sense. The background() function is not any more efficient than the image() function. In fact, the background() function just calls the image() function for you!
From the P5.js source:
p5.prototype.background = function() {
if (arguments[0] instanceof p5.Image) {
this.image(arguments[0], 0, 0, this.width, this.height);
} else {
this._renderer.background.apply(this._renderer, arguments);
}
return this;
};
P5.js simply checks whether the argument is an image, and if so, calls the image() function for you. So it doesn't really make sense to say that using the image() function is "less efficient" than using the background() function.
Taking a step back, you should really avoid thinking about these kinds of micro-optimizations until you A: understand the problem and B: actually have a problem. Don't make assumptions about "efficiency" until you've actually measured your code for performance.
Anyway, back to your question. You also said that you're loading the image twice, which you shouldn't have to do. You can just load the image once (make sure you do that in the setup() function and not the draw() function, and then draw that image twice:
var img;
function preload() {
img = loadImage("image.jpg");
}
function setup() {
image(img, 0, 0);
image(img, 100, 100);
}
And since you can draw two images, you'd then just draw them next to each other. Here's an example using colored rectangles to show the approach more clearly:
var offsetX = 0;
function setup() {
createCanvas(200, 200);
}
function draw() {
background(0);
fill(0, 255, 0);
rect(offsetX, 0, width, height);
fill(0, 0, 255);
rect(offsetX + width, 0, width, height);
offsetX--;
if(offsetX <= -width){
offsetX = 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.14/p5.js"></script>
There are other ways to do it, like creating an image that contains the wrapping itself. But the general approach is pretty much the same.
If you're still stuck, please try to break your problem down into smaller pieces like I've done here. For example, notice that I created a simple sketch that deals with images, and another simple sketch that deals with moving rectangles. Then if you get stuck, please post a MCVE in a new question post and we'll go from there. Good luck.
Maybe it is a late answer.. but you can make the environment 3D and then move the camera.
Docs: https://p5js.org/reference/#/p5/camera
Example:
function setup() {
createCanvas(windowWidth - 200, windowHeight - 200, WEBGL);
background(175);
frameRate(30);
}
function draw() {
background(175);
//move the camera Xaxis when mouse is moved
let camX = map(mouseX, 0, width, 0,width);
camera(camX, 0, (height/2.0) / tan(PI*30.0 / 180.0), camX, 0, 0, 0, 1, 0);
normalMaterial();
noStroke();
ambientLight(251,45,43);
box(100, 100, 50);
ang += 0.3;
rotateY(ang * 0.03);
}
Keep calm and Happy Coding!

setLineWidth works differently on different test machines

I make a game in which I draw bezier curve like this:
final VertexBufferObjectManager vbom = engine.getVertexBufferObjectManager();
final HighPerformanceMeshVertexBufferObject pMeshVBOM = new HighPerformanceMeshVertexBufferObject(vbom, pBufferData, pBufferData.length, DrawType.DYNAMIC, true, Mesh.VERTEXBUFFEROBJECTATTRIBUTES_DEFAULT);
final HighPerformanceLineChainVertexBufferObject pLeftCurbLineChainVBOM = new HighPerformanceLineChainVertexBufferObject(vbom, triangleCount * 3, DrawType.DYNAMIC, true, leftCurb.VERTEXBUFFEROBJECTATTRIBUTES_DEFAULT);
final HighPerformanceLineChainVertexBufferObject pRightCurbLineChainVBOM = new HighPerformanceLineChainVertexBufferObject(vbom, triangleCount * 3, DrawType.DYNAMIC, true, rightCurb.VERTEXBUFFEROBJECTATTRIBUTES_DEFAULT);
leftCurb = new LineStrip(0, 0, 10f, triangleCount, pLeftCurbLineChainVBOM){
#Override
protected void onManagedUpdate(final float pSecondsElapsed) {
super.onManagedUpdate(pSecondsElapsed);
drawByBezier(curveOffset);
};
void drawByBezier(float curveOffset){
for (int triangleIndex = 0; triangleIndex < triangleCount; triangleIndex++) {
this.setX(triangleIndex, getBezierX(triangleIndex, -curveBottom, -curveControlPoint, -curveTop + curveOffset));
this.setY(triangleIndex, triangleIndex * heightIncrement);
}
}
By changing a value of curveOffset I change the look of the curve.
The first parameter (10f) is a line width. When I test it on Galaxy S5 (android 5) the line width is drawn as about 2 pixels wide and if I put lower value there, like 1.5f the drawn line is very thin. On the other hand putting large numbers like 100f doesn't do anything - line stays at same (small) width.
I tested this on Galaxy S3 mini (android 4.1.2) and the line width works there (performance is other thing though...). Line is drawn as I wanted to. How can I do that in GalaxyS5 (android 5). For me it looks like device or OS specific problem (openGL version?), but is there any way to overcome this?
OpenGL ES implementations do not have to support drawing of wide lines. You can query the range of available line widths with:
float[] range = new float[2];
GLES20.glGetFloatv(GLES20.GL_ALIASED_LINE_WIDTH_RANGE, range, 0);
// range[0] is the minimum supported line width.
// range[1] is the maximum supported line width.
This gives you the range supported by the specific device you're running on. Compliant implementations can have a maximum as low as 1.0. This means that you cannot use wide lines if you want your code to run on all devices.
If you want something that has the appearance of wide lines, and will work on any device, you have to draw polygons. You can draw something that looks like a line as a thin quad that is oriented towards the viewer.

ILNumeric continuous rendering plots

Is there a way to continously plot changing array data? I've got a ILLinePlot to graph the line to changing data on a button event, but I would like to make it continuous.
while (true)
{
float[] RefArray = A.GetArrayForWrite();
//RefArray[0] = 100;
Shuffle<float>(ref RefArray);
Console.Write(A.ToString());
scene = new ILScene();
pc = scene.Add(new ILPlotCube());
linePlot = pc.Add(new ILLinePlot(A.T, lineColor: Color.Green));
ilPanel1.Scene = scene;
ilPanel1.Invalidate();
}
The problem I'm running into is that the loop runs, and i can see updates of the array, but the ILPanel does not update. I'm thinking maybe it's because the main loop can't be accessed due to this infinite loop, so I put it in its own thread as well, but it's still not rendering as I hoped...
As Paul pointed out, there is a more efficient attempt to do this:
private void ilPanel1_Load(object sender, EventArgs e) {
using (ILScope.Enter()) {
// create some test data
ILArray<float> A = ILMath.tosingle(ILMath.rand(1, 50));
// add a plot cube and a line plot (with markers)
ilPanel1.Scene.Add(new ILPlotCube(){
new ILLinePlot(A, markerStyle: MarkerStyle.Rectangle)
});
// register update event
ilPanel1.BeginRenderFrame += (o, args) =>
{
// use a scope for automatic memory cleanup
using (ILScope.Enter()) {
// fetch the existint line plot object
var linePlot = ilPanel1.Scene.First<ILLinePlot>();
// fetch the current positions
var posBuffer = linePlot.Line.Positions;
ILArray<float> data = posBuffer.Storage;
// add a random offset
data = data + ILMath.tosingle(ILMath.randn(1, posBuffer.DataCount) * 0.005f);
// update the positions of the line plot
linePlot.Line.Positions.Update(data);
// fit the line plot inside the plot cube limits
ilPanel1.Scene.First<ILPlotCube>().Reset();
// inform the scene to take the update
linePlot.Configure();
}
};
// start the infinite rendering loop
ilPanel1.Clock.Running = true;
}
}
Here, the full update runs inside an anonymous function, registered to BeginRenderFrame.
The scene objects are reused instead of getting recreated in every rendering frame. At the end of the update, the scene needs to know, you are done by calling Configure on the affected node or some node among its parent nodes. This prevents the scene from rendering partial updates.
Use an ILNumerics arteficial scope in order to clean up after every update. This is especially profitable once larger arrays are involved. I added a call to ilPanel1.Scene.First<ILPlotCube>().Reset() in order to rescale the limits of the plot cube to the new data content.
At the end, start the rendering loop by starting the Clock of ILPanel.
The result is a dynamic line plot, updating itself at every rendering frame.
I think you need to call Configure() after any modification of a shape or its buffers. Use the BeginRenderFrame event to do your modifications and you should not add infinitely many shapes / new scenes. It is better to reuse them!
Let me know, if you need an example...

How to animate data visualization in Processing?

I'm trying to create an animated data visualization and currently only know how to do the following "static" code, which puts a string of dots in a straight line. How do I make them jump up and down? Also, if there is anyone in Dublin, Ireland, who wouldn't mind giving a few tutorial sessions to a couple of college students working on a data visualization project in Processing, we have a small budget to compensate you for your time. Thanks very much!
For now, here's the code I was talking about...
SimpleSpreadsheetManager sm;
String sUrl = "t6mq_WLV5c5uj6mUNSryBIA";
String googleUser = "USERNAME";
String googlePass = "PASSWORD";
void setup() {
//This code happens once, right when our sketch is launched
size(800,800);
background(0);
smooth();
//Ask for the list of numbers
int[] numbers = getNumbers();
fill(255,40);
noStroke();
for (int i = 0; i < numbers.length; i++) {
ellipse(numbers[i] * 8, width/2, 8,8);
};
};
void draw() {
//This code happens once every frame.
};
Essentially the x position you use for drawing the ellipse is a number value you get from external data. You need a variable that changes value. Redrawing the ellipse at the updated value should get things animated.
Take this basic example:
float x,y;//position variables for the ellipse
void setup(){
size(800,800);
smooth();
fill(255,40);
noStroke();
y = 400;
}
void draw(){
//update values
x = mouseX + (sin(frameCount * .05) * 30);//update x to an arbitrary value
//draw
background(0);//clear the screen for the new frame
ellipse(x,y,8,8);//draw the ellipse at the new position
}
the x variable is a bit like numbers[i] - just a value that chances.
Nothing special happens in draw() other than clearing the screen(by calling background()) and drawing. The example above uses an arbitrary value, but with your setup that might be something else, maybe a certain value in a data set that changes in time (like the population of a country, etc.)
Another handy thing to keep in mind is the separation between the data and visuals code wise. If values in the data set are higher than what can be displayed on screen as raw values, you can map() values so they can be viewer, add some sort of navigation controls, etc. The values analysed will not be affected by what's being displayed. In programming terms this separation between the data/model, the visuals/view (how the data is rendered) and the controls/controller is known as the Model-View-Controller pattern.
This might be a bit much for people just starting with code, but just being aware of the separation without worrying to much on the specific implementation can be helpful.
Here's a very basic example having the width of the sketch mapped to the size of the data (numbers)
SimpleSpreadsheetManager sm;
String sUrl = "t6mq_WLV5c5uj6mUNSryBIA";
String googleUser = "USERNAME";
String googlePass = "PASSWORD";
int[] numbers;//data used for visualisation
void setup() {
//sketch setup
size(800,800);
smooth();
fill(255,40);
noStroke();
//retrieve data
numbers = getNumbers();
}
void draw() {
background(0);
int numId = int(map(mouseX,0,width,0,numbers.length));//map mouse x position based on sketch width and data size
ellipse(numbers[numId] * 8, height/2, 8,8);
}
For an animation you need one or more parameters that their values changed in time, currently there is a library for processing which do such things: Ani
For more information see the site and provided examples.

Resources