I'm reading up on image/pixel manipulation and was running through some of the examples in
Processing: A Programming Handbook and I keep getting
ArrayIndexOutOfBoundsException: 10000 exceptions.
My
eames101.jpg image is 101x101 pixels.
PImage eames101 = loadImage("eames101.jpg"); int count = eames101.width * eames101.height; eames101.loadPixels(); loadPixels(); for (int i = 0; i < count; i += 2) { pixels[i] = eames101.pixels[i]; } updatePixels();
I know you're probably thinking I should just draw a triangle and fill it, but I'd like to draw many lines, and have the blank spaces filled at random after they intersect.
Should I just use triangles and try to make them aware of where they are relative to each other? Or is there a more obvious solution I'm overlooking?
// Variables String[] lines; int index = 0; int size_index = 0; int i = 0; int liner = 20; int maxline = 0; int x1 = 0; int y1 = 0; int x2 = 0; int y2 = 0; int maxValue; // ADDED: The highest value int incrementor = 11;
PFont f;
// Setup runs once void setup() { //frame.setResizable(true); background(46, 38, 33); stroke(190, 232, 224); lines = loadStrings("rar2.csv"); // Load the csv file which contains the counts f = loadFont("SansSerif.plain-8.vlw"); // Load a font to display the names next to the graph
for (i = 0; i < lines.length; i++) { String[] pieces = split(lines[size_index], ','); int x = int(pieces[1]); // MODIFIED: You have the x and the y flipped! int y = int(pieces[0]); if (y > maxline) { maxline = y; } else { maxline = maxline; } size_index = size_index + 1;
maxValue = max(maxValue, x); // ADDED: Find the maximum value } // Multiplying lines.length by incrementor because of the iteration on the index spacer later in draw() size(800,(liner+(lines.length * incrementor)+liner)); // MODIFIED: Changed width to allow for scaling } // Draw runs continuously void draw() { if (index < lines.length) { // Split the input file by comma String[] pieces = split(lines[index], ',');
// Variables to set line length and spacing // Starting at 120 pixels to the right to give room for the text x1 = 120; y1 = liner; x2 = int(pieces[1]); y2 = liner;
// Increase line thickness to 4 strokeWeight(8); // Set the cap to the end of lines be square strokeCap(SQUARE); // Set the font and size textFont(f,8); // Try to align the text properly textAlign(CENTER + 10);
float scaledX = map(x2,0,maxValue,0,width - x1 * 2); // ADDED: Scale the width of the bar text(pieces[0], 8,y1); line(x1,y1,(x1+scaledX),y2); // MODIFIED: Use scaled value
// Iterate the line count index = index + 1;
// Increment the liner value by the incrementor, this is the spacing between lines liner = liner + incrementor; } //saveFrame("output-###.png"); }
The names appear to be just a few pixels higher than the lines being drawn and I'm not entirely certain how to get them to match up nice and clean, any advice?
I've got what I think is a scaling issue at hand. I've got some code written for a simple line-graph generator, (code below).
The length of the line is determine by the second value in each line of my input .csv file, (also below).
Seeing as how the line drawn is x pixels long, I'm going to run into a problem once I try to draw lines where the input number is in the thousands or millions.
How would I scale my lines and the size of the sketch window to accommodate for such large values?
Any tips?
// Drawing line graphs of some counts // Current Goal: scale lines that have values in the millions
// Variables String[] lines; int index = 0; int size_index = 0; int i = 0; int liner = 30; int maxline = 0; int x1 = 0; int y1 = 0; int x2 = 0; int y2 = 0;
// Setup runs once void setup() { frame.setResizable(true); // Set background color to dark blue background(43, 58, 66); // Set line color to orange stroke(235, 85, 13); // Load the csv file which contains the counts lines = loadStrings("rar.csv");
for (i = 0; i < lines.length; i++) { String[] pieces = split(lines[size_index], ','); int x = int(pieces[0]); int y = int(pieces[1]); if (y > maxline) { maxline = y; } else { maxline = maxline; } size_index = size_index + 1; } // Multiplying lines.length by 10 because of the iteration on the index spacer later in draw() size(liner+(maxline + liner),(liner+(lines.length * 10)+liner)); }
// Draw runs continuously void draw() { if (index < lines.length) { // Split the input file by comma String[] pieces = split(lines[index], ',');
// Variables to set line length and spacing x1 = 30; y1 = liner; x2 = int(pieces[1]); y2 = liner;
// Increase line thickness to 2 strokeWeight(2); // Set the cap to the end of lines be square strokeCap(SQUARE);
// 10 = Starting point of line, line will extend to the right line(x1,y1,(x2+x1),y2);
// Iterate the line count index = index + 1;
// Increment the liner value by 10, this is the spacing between lines liner = liner + 10; } }
In my program, I've used the translate() function to change the origin point from the upper left corner of the image, to the lower left.
My intention is to draw some varying shapes, (lines, points, rectangles) using some data that I have.
The problem is that some of this data has negative point values, think (-5, -6), so based on where my origin point is, I can't see some of my data.
Is there a way to view my image, such that my origin point is in the middle of the image, AND the X and Y values increase as they go up and right, as opposed the default of down and right?
The only option I can think of now is to set the origin point at the middle of my image, and then just convert all of my values so they appear where I think they should, but that's not really the way I'd like to approach this problem.
I'm reading through Ben Fry's 'Visualizing Data' and I'm writing the scatter plot map program in Chapter 6 (If you haven't read it, it's essentially about drawing GPS coordinates). I've gotten the base program working, but now I'm trying to edit it to display more information.
My basic question is how do I read my input file, and only bring a single row into memory at once, as opposed to the whole file. The entire file I've got is too big to bring into memory all at once. I've got a large dataset I want to try to draw, but the way the program is currently written, it brings the entire input into memory at once, and then draws it. I'd like to loop through each row in my input, draw that, dump it from memory, draw the next row, and so on.
Does anyone have any tips?
// The first line in the input file, in this case, zips2.csv contains the bounding box for the drawing area // The first number is the count of the total number of rows, then it's MinX, MaxX, MinY, MaxY
// Column numbers in the data file static final int X = 0; static final int Y = 1;
int totalCount; // Total number of places Place[] places; int placeCount; // Numbers of places loaded
// MIN/MAX boundary of all points float minX, maxX; float minY, maxY;
// Border of where the map should be drawn on screen float mapX1, mapY1; float mapX2, mapY2;
My question has a couple of parts, I know how to read this file/data into processing, but how do I split each line and only read the latitude and longitude values?
Once I've got those values declared as their own variables, would using the map() function be the best method to display them? I've read the reference on it and it's a little fuzzy to me.
Any examples or tips anyone could post would be awesome.