there is no z variable in the first code.
and in the second giraffe and count never match so no points will be drawn.
xx and yy vars are never used
i’m not sure what the giraffe == count test is for truthfully nor why are you exporting to a text file then importing it. wouldn’t it be easier to process it all in one sketch?
if you add a z var to the first sketch and use the below code in place of the second you will get an output but… well have a look for yourself as i’m not sure if it is the output you are seeking.
float r = 0;
float theta = 0;
int count = 0;
ArrayList<float[]> points;
void setup() {
size(300, 300);
surface.setSize(300,300);
background(255);
fill(255, 0, 0);
points = new ArrayList<float[]>();
parseFile();
}
void draw() {
translate(width / 2, height / 2);
for(int i = 0; i < points.size(); i++) {
float[] p = points.get(i);
point(p[0], p[1]);
}
}
void parseFile() {
// Open the file from the createWriter() example
BufferedReader reader = createReader("positions.txt");
String line = null;
try {
while ((line = reader.readLine()) != null) {
float x = r * cos(theta);
float y = r * sin(theta);
// Adjust for center of window
//you never use the xx and yy variables
//float xx = (x+width/2);
//float yy = (y+height/2);
int giraffe = int(line);
//you can see in the console they never match
println("giraffe: " + giraffe + " count: " + count);
points.add(new float[] {x,y});
// Increment the angle
theta += 0.01;
// Increment the radius
r += 0.003;
count = count +1;
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
your while loop goes for unlimited z ( now called count )
and reads lines,
instead it should read one line, count z until is equal line,
draw pix ( not at x,y better xx,yy )
and read next line.
void parseFile() { // Open the file from the createWriter() example
BufferedReader reader = createReader("positions.txt");
String line = null;
try {
line = reader.readLine(); // read first line
while ( line != null && z < 49950) {
if (int(line) == z) {
float x = r * cos(theta);
float y = r * sin(theta);
// Adjust for center of window
float xx = (x+width/2);
float yy = (y+height/2);
point(xx, yy);
line = reader.readLine(); // next line
}
// Increment the angle
theta += 0.01;
// Increment the radius
r += 0.003;
z++;
println(z);
}
reader.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
Thank you!! That’s 95% correct. The final drawing looks correct but the text file is formatted in a way that doesn’t look as it needs to be. The text file should just be points along the spiral path that were black in the source image, not x-y coordinates. The drawing file needs to increment along the same spiral path and read line by line the text file. If the step along the spiral equals the current count in the text file, then it can draw at that position.
Awesome!Can you provide the whole script?It doesn’t doanything when I run it as you pasted.
i use one file and /* */ to run
step get
step set
// https://discourse.processing.org/t/draw-from-text-file-not-working-as-expected/8498
float r = 0;
float theta = 0;
int z = 0;
void setup() {
size(300, 300);
background(255);
parseFile();
}
void parseFile() { // Open the file from the createWriter() example
BufferedReader reader = createReader("positions.txt");
String line = null;
try {
line = reader.readLine(); // read first line
while ( line != null && z < 49950) {
if (int(line) == z) {
float x = r * cos(theta);
float y = r * sin(theta);
// Adjust for center of window
float xx = (x+width/2);
float yy = (y+height/2);
point(xx, yy);
line = reader.readLine(); // next line
}
// Increment the angle
theta += 0.01;
// Increment the radius
r += 0.003;
z++;
println(z);
}
reader.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
// slo mo version with show
/*
float r = 0;
float theta = 0;
PImage input; // from file explorer
boolean gotit = false;
String[] output;
String infile= "data/moonwalker.jpg", outfile = "data/positions.txt";
int z=0;
color cr = color(200, 0, 0);
color cg = color(0, 200, 0);
color cu;
void setup() {
size(600, 300);
background(255);
output = new String[1];
output[0] = "";
selectInput("select an image to process", "select");
}
void select(File selection) {
if (selection == null) {
exit();
} else {
infile = selection.getAbsolutePath();
println("load: "+infile);
input = loadImage(infile);
input.resize(width, height);
input.filter(THRESHOLD, 0.5);
gotit = true;
}
}
void read_black() {
input.loadPixels();
//println("z "+z);
if (z < 49950) {
// Polar to Cartesian conversion
float x = r * cos(theta);
float y = r * sin(theta);
int xx = int((x+width/2));
int yy = int((y+height/2));
int ppos = yy * width + xx;
if (z > 2000) {
if (input.pixels[ppos] == color(0)) { output[0] += z + "\n"; println("black "+z); cu = cr; }
else cu = cg;
input.pixels[ppos] = cu;
input.updatePixels();
}
// Increment the angle
theta += 0.01;
// Increment the radius
r += 0.003; //0.001 covers all pixels
z = z + 1;
} else {
saveStrings(outfile, output);
println("write "+outfile);
exit();
}
}
void draw() {
if (gotit) {
image(input, 0, 0);
read_black();
}
}
*/
i think your math is still wrong!
your last code goes by a const angle, that means a increasing speed / way as the R grows also,
while you need constant way.
you should keep the spiral
but find a const distance between 2 points on it.
Do you mean like equidistant points along a spiral? Looking for a processing compatible formula for that now. I found this clarkston scroll formula: t = 2 * Pi * Sqrt(2 * s / a) but I don’t understand how to implement it.
This is what I have so far but I do not understand how to integrate the S variable from the clarkston scroll formula:
float r = 0;
float t = 0;
int z = 0;
int s = 0;
PImage input;
String[] output;
void setup() {
size(300, 300);
background(255);
output = new String[1];
output[0] = "";
selectInput("select an image to process", "select");
}
void select(File selection){
if (selection == null){
exit();
}
else {
input = loadImage(selection.getAbsolutePath());
input.resize(width, height);
input.filter(THRESHOLD, 0.5);
input.loadPixels();
//while (z < 49950) {
// Polar to Cartesian conversion
float x = r * cos(t);
float y = r * sin(t);
t = 2 * PI * sqrt(2 * s / r);
int xx = int((x+width/2));
int yy = int((y+height/2));
//if (z > 2000) {
if(input.pixels[yy * width + xx] == color(0)) {
output[0] += z + "\n";
println(s);
}
//}
// Increment the angle
t += 0.01;
// Increment the radius
r += 0.003; //0.001 covers all pixels
z = z + 1;
}
saveStrings("positions.txt", output);
println("done!");
}
//}
i found something what looks good,
imagine that as measuring points on the picture
and later as rounds of the tractor wheel
( what’s circumference is the distance of the points )
// equidistant spiral points
// https://stackoverflow.com/questions/13894715/draw-equidistant-points-on-a-spiral
void spiral() {
float coils = 10, radius =200, rotation = 0.1;
float thetaMax = coils * 2 * PI; // value of theta corresponding to end of last coil
float awayStep = radius / thetaMax; // How far to step away from center for each side.
float chord = 10; // distance between points to plot
// For every side, step around and away from center. // start at the angle corresponding to a distance of chord // away from centre.
for ( float theta = chord / awayStep; theta <= thetaMax; ) {
float away = awayStep * theta; // How far away from center
float around = theta + rotation; // How far around the center.
float x = width/2 + cos ( around ) * away; // Convert 'around' and 'away' to X and Y.
float y = height/2 + sin ( around ) * away;
circle( x, y, 5 ); // show something
theta += chord / away; // to a first approximation, the points are on a circle so the angle between them is chord/radius
}
}
void setup() {
size( 500, 500);
background(200, 200, 0);
stroke(200, 0, 0);
spiral();
}
void draw() {
}
I integrated your math into the picture-to-coordinates-file-generator sketch but it throws an error message and doesn’t save the text file.
PImage input;
String[] output;
int z = 0;
void setup() {
size(300, 300);
background(255);
output = new String[1];
output[0] = "";
selectInput("select an image to process", "select");
}
void select(File selection){
if (selection == null){
exit();
}
else {
input = loadImage(selection.getAbsolutePath());
input.resize(width, height);
input.filter(THRESHOLD, 0.5);
input.loadPixels();
//void spiral() {
float coils = 10, radius =200, rotation = 0.1;
float thetaMax = coils * 2 * PI; // value of theta corresponding to end of last coil
float awayStep = radius / thetaMax; // How far to step away from center for each side.
float chord = 10; // distance between points to plot
// For every side, step around and away from center. // start at the angle corresponding to a distance of chord // away from centre.
for ( float theta = chord / awayStep; theta <= thetaMax; ) {
float away = awayStep * theta; // How far away from center
float around = theta + rotation; // How far around the center.
float x = width/2 + cos ( around ) * away; // Convert 'around' and 'away' to X and Y.
float y = height/2 + sin ( around ) * away;
int xx = int(x);
int yy = int(y);
int loc = input.get(xx,yy);
//
if (loc == color(0)) {
//if(input.pixels[yy * width + xx] == color(0)) {
//if (input.pixels[yy + yy * width] == color(0)) {
output[0] += away + "\n";
println(away);
}
///point( x, y); // show something
theta += chord / away; // to a first approximation, the points are on a circle so the angle between them is chord/radius
}
}
saveStrings("positions.txt", output);
println("done!");
}
recreator sketch:
float coils = 10, radius =200, rotation = 0.1;
float thetaMax = coils * 2 * PI; // value of theta corresponding to end of last coil
float awayStep = radius / thetaMax; // How far to step away from center for each side.
float chord = 10; // distance between points to plot
int z = 0;
void setup() {
size(300, 300);
background(255);
parseFile();
}
void parseFile() { // Open the file from the createWriter() example
BufferedReader reader = createReader("positions.txt");
String line = null;
try {
line = reader.readLine(); // read first line
while ( line != null) {
for ( float theta = chord / awayStep; theta <= thetaMax; ) {
float away = awayStep * theta; // How far away from center
float around = theta + rotation; // How far around the center.
float x = width/2 + cos ( around ) * away; // Convert 'around' and 'away' to X and Y.
float y = height/2 + sin ( around ) * away;
int xx = int(x);
int yy = int(y);
if (int(line) == away) {
//float x = r * cos(theta);
//float y = r * sin(theta);
// Adjust for center of window
//float xx = (x+width/2);
//float yy = (y+height/2);
point(xx, yy);
line = reader.readLine(); // next line
}
// Increment the angle
//theta += 0.01;
// Increment the radius
// r += 0.003;
//z++;
//println(z);
theta += chord / away; // to a first approximation, the points are on a circle so the angle between them is chord/radius
}
}
reader.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
It’s kinda working now. I am just wondering which values to change if I want to adjust the away step and the distance between wheel steps so that it may reproduce the image better.
// https://stackoverflow.com/questions/13894715/draw-equidistant-points-on-a-spiral
// https://discourse.processing.org/t/draw-from-text-file-not-working-as-expected/8498
float coils = 10, radius =200, rotation = 0.1;
float thetaMax = coils * 2 * PI; // value of theta corresponding to end of last coil
float awayStep = radius / thetaMax; // How far to step away from center for each side.
float chord = 10; // distance between points to plot
int z = 0;
void setup() {
size(300, 300);
background(255);
parseFile();
}
void parseFile() { // Open the file from the createWriter() example
BufferedReader reader = createReader("positions.txt");
String line = null;
try {
line = reader.readLine(); // read first line
while ( line != null) {
for ( float theta = chord / awayStep; theta <= thetaMax; ) {
float away = awayStep * theta; // How far away from center
float around = theta + rotation; // How far around the center.
float x = width/2 + cos ( around ) * away; // Convert 'around' and 'away' to X and Y.
float y = height/2 + sin ( around ) * away;
int xx = int(x);
int yy = int(y);
if (int(line) == z) {
point(xx, yy);
line = reader.readLine(); // next line
}
z++;
println(z);
theta += chord / away; // to a first approximation, the points are on a circle so the angle between them is chord/radius
}
}
reader.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
type or paste code here
// equidistant spiral points
// https://stackoverflow.com/questions/13894715/draw-equidistant-points-on-a-spiral
// https://discourse.processing.org/t/draw-from-text-file-not-working-as-expected/8498
PImage input;
String[] output;
int z = 0;
void setup() {
size(300, 300);
background(255);
output = new String[1];
output[0] = "";
selectInput("select an image to process", "select");
}
void select(File selection){
if (selection == null){
exit();
}
else {
input = loadImage(selection.getAbsolutePath());
input.resize(width, height);
input.filter(THRESHOLD, 0.5);
input.loadPixels();
//void spiral() {
float coils = 10, radius =200, rotation = 0.1;
float thetaMax = coils * 2 * PI; // value of theta corresponding to end of last coil
float awayStep = radius / thetaMax; // How far to step away from center for each side.
float chord = 10; // distance between points to plot
// For every side, step around and away from center. // start at the angle corresponding to a distance of chord // away from centre.
for ( float theta = chord / awayStep; theta <= thetaMax; ) {
float away = awayStep * theta; // How far away from center
float around = theta + rotation; // How far around the center.
float x = width/2 + cos ( around ) * away; // Convert 'around' and 'away' to X and Y.
float y = height/2 + sin ( around ) * away;
int xx = int(x);
int yy = int(y);
int loc = input.get(xx,yy);
//
if (loc == color(0)) {
output[0] += z + "\n";
//output[0] += away + "\n";
println(away);
}
///point( x, y); // show something
theta += chord / away; // to a first approximation, the points are on a circle so the angle between them is chord/radius
z++;
}
}
saveStrings("positions.txt", output);
println("done!");
}
Also, the recreator sketch doesn’t stop running on the end of the text file for some reason.
i try to make a better setup,
combine both tools,
allow both spiral types …
import processing.pdf.*; // make pdf print
boolean record;
// selectable old new spiral,
// combine create and recreate
// save create picture to PDF
//variables for file handling
PImage input; // from file explorer
boolean usefileexplorer=false; // if false expect path / file
String[] output;
String pdffile= "data/getblack.pdf", infile= "data/moonwalk.jpg", outfile = "data/positions.txt";
// colors for progress show, see also pdf
color cr = color(200, 0, 0);
color cg = color(0, 200, 0);
color cu;
// main program flow
int mode = 0; // can use = 2 for recreate only
boolean diagp = false; //true; //false;
int z=0, zstart= 0, zstop = 5000; //49950;
void setup() {
size(600, 600);
//noSmooth();
background(255);
output = new String[1];
output[0] = "";
if ( mode == 0 ) {
if ( usefileexplorer ) selectInput("select an image to process", "select");
else select(null);
}
}
void select(File selection) {
if (selection == null) ; // use preconfig path/file
else infile = selection.getAbsolutePath();
println("load: "+infile);
input = loadImage(infile);
input.resize(width, height);
input.filter(THRESHOLD, 0.5);
input.loadPixels();
mode = 1;
beginRecord(PDF, pdffile);
image(input, 0, 0);
}
//_____________________________________________________ variables and calc for old spiral
float r = 0, rpp = 0.005;//0.003;
float theta = 0, thetapp = 0.01;
float x, y;
int pixpos;
int const_theta_spiral() {
x = r * cos(theta) + width/2; // Polar to Cartesian conversion
y = r * sin(theta) + height/2;
theta += thetapp; // Increment the angle // for next loop
r += rpp; // Increment the radius //0.001 covers all pixels
return (int)y * width + (int)x; // just return the pix position in the image to check on
}
//______________________________________________________ variables for new spiral
boolean use_const_dist = true;
float coils = 50, radius = 200, rotation = 0.1;
float thetaMax = coils * 2 * PI; // value of theta corresponding to end of last coil
float away, around, awayStep = radius / thetaMax; // How far to step away from center for each side.
float chord = 5; // distance between points to plot
float theta2 = chord / awayStep; // start value
int const_dist_spiral() { // For every side, step around and away from center. // start at the angle corresponding to a distance of chord // away from centre.
// for ( float theta = chord / awayStep; theta <= thetaMax; ) { // WARNING limit disabled ONLY ZSTOP used
away = awayStep * theta2; // How far away from center
around = theta2 + rotation; // How far around the center.
x = width/2 + cos ( around ) * away; // Convert 'around' and 'away' to X and Y.
y = height/2 + sin ( around ) * away;
theta2 += chord / away; // to a first approximation, the points are on a circle so the angle between them is chord/radius
// }
return (int)y * width + (int)x; // just return the pix position in the image to check on
}
void read_black() {
if (z < zstop) {
if ( use_const_dist ) pixpos = const_dist_spiral();
else pixpos = const_theta_spiral();
if ( x < 0 || x > width ) zstop = z; // the zstop thing can be a bad idea, actually we must stop when x and y out of canvas ( or picture )
if ( y < 0 || y > height ) zstop = z;
if (z > zstart && z < zstop ) {
if (input.pixels[pixpos] == color(0)) {
output[0] += z + "\n";
if ( diagp ) println("black "+z+" pixpos "+pixpos+" x "+x+" y "+y);
cu = cr;
} else cu = cg;
stroke(cu); fill(cu);
circle(x,y,2);
}
z = z + 1;
} else {
saveStrings(outfile, output);
println("write "+outfile);
mode = 2; // exit();
}
}
void draw() {
if ( mode == 1 ) {
read_black();
}
if ( mode == 2 ) { // do some resets
endRecord(); // write PDF file
println("saved to "+pdffile);
background(200, 200, 0);
r = 0.0;
theta = 0.0;
theta2 = chord / awayStep;
z = 0;
stroke(200, 0, 0);
println("read "+outfile);
mode = 3;
}
if ( mode == 3 ) {
parseFile();
}
}
void parseFile() { // Open the file from the createWriter() example
BufferedReader reader = createReader("positions.txt");
String line = null;
try {
line = reader.readLine(); // read first line
if ( use_const_dist ) pixpos = const_dist_spiral();
else pixpos = const_theta_spiral();
while ( line != null && z < zstop) {
if ( use_const_dist ) pixpos = const_dist_spiral();
else pixpos = const_theta_spiral();
if (int(line) == z) {
circle(x,y,2); //point(x, y);
line = reader.readLine(); // next line
if ( diagp ) println("z "+z+" x "+x+" y "+y);
}
z++; //println(z);
}
reader.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
It works except for the PDF which won’t open. Here’s the error message:
load: C:\Users\g9duf\Desktop\New folder\sim-input.jpg
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at processing.core.PApplet.selectCallback(PApplet.java:6712)
at processing.core.PApplet.access$1(PApplet.java:6705)
at processing.core.PApplet$4.run(PApplet.java:6616)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.lang.RuntimeException: Problem saving the PDF file.
at processing.pdf.PGraphicsPDF.beginDraw(Unknown Source)
at processing.core.PApplet.beginRecord(PApplet.java:11141)
at processing.core.PApplet.beginRecord(PApplet.java:11130)
at printgencheck22219.select(printgencheck22219.java:65)
… 21 more
Caused by: com.lowagie.text.exceptions.IllegalPdfSyntaxException: Unbalanced begin/end text operators.
at com.lowagie.text.pdf.PdfContentByte.beginText(Unknown Source)
at com.lowagie.text.pdf.PdfDocument.initPage(Unknown Source)
at com.lowagie.text.pdf.PdfDocument.open(Unknown Source)
at com.lowagie.text.Document.open(Unknown Source)
… 25 more
write data/positions.txt
ExceptionConverter
ExceptionConverter
ExceptionConverter
ExceptionConverter
ExceptionConverter
Copied to the clipboard. Use shift-click to search the web instead.
you still talk about PDF file?
or you mean for the picture to analyze?
-a- well i tested it with a .png and it works too
-b- the code i show you use the default picture from many processing examples
“moonwalk.jpg”
( so i sure not need to provide that picture )
-c- if you want try a code you best start to run it “as is”
in the default environment ( processing IDE ( now 3.5.3 ))
without any changes.
later you can delete it or use one or many lines in you own project.
but testing it with a ?bad? picture what you never used in your own project not makes sense.
Yes it seems it doesn’t like certain image files or their location as it won’t open some. That’s acceptable. Is there a way to put each of those “print” messages into the bottom corner of the window as it progresses? I’d like to display those without the console eventually.