453 lines
9.6 KiB
Java
453 lines
9.6 KiB
Java
import processing.core.*;
|
|
import processing.xml.*;
|
|
|
|
import java.applet.*;
|
|
import java.awt.*;
|
|
import java.awt.image.*;
|
|
import java.awt.event.*;
|
|
import java.io.*;
|
|
import java.net.*;
|
|
import java.text.*;
|
|
import java.util.*;
|
|
import java.util.zip.*;
|
|
import java.util.regex.*;
|
|
|
|
public class viewer extends PApplet {
|
|
|
|
/**
|
|
* viewer
|
|
*
|
|
* Copyright 2013 by John Johnson Software, LLC
|
|
* All Rights Reserved
|
|
*
|
|
* Load line coordinates from a file and draw them.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* Representation of a line.
|
|
*
|
|
*/
|
|
class Line {
|
|
float sx;
|
|
float sy;
|
|
float ex;
|
|
float ey;
|
|
int pass; // What pass this line was created on.
|
|
|
|
Line(float x1, float y1, float x2, float y2, int pass_num) {
|
|
sx = x1;
|
|
sy = y1;
|
|
ex = x2;
|
|
ey = y2;
|
|
pass = pass_num;
|
|
}
|
|
}
|
|
|
|
Line[] plines = new Line[1];
|
|
|
|
/*
|
|
* When lines are drawn in color, the colors used follow the
|
|
* standard resistor color codes. After 9, the sequence repeats.
|
|
* 0 is cyan, rather than black, as that would be a little hard
|
|
* to see on the black background.
|
|
* Colors are also slightly (204/255) transparent so you can see where
|
|
* they overlap.
|
|
*
|
|
*/
|
|
int[] color_table = {
|
|
0xCC3399FF, /* pass 0, cyan */
|
|
0xCC993300, /* 1 = brown */
|
|
0xCCFF0000,
|
|
0xCCFF9900,
|
|
0xCCFFFF00, /* yellow */
|
|
0xCC33FF00,
|
|
0xCC0000FF,
|
|
0xCC660099, /* violet */
|
|
0xCCCCCCCC, /* gray */
|
|
0xCCFFFFFF /* white */
|
|
};
|
|
|
|
int bg_color = 0xff000000;
|
|
|
|
float x_scale = -200;
|
|
float y_scale = -200;
|
|
float x_offset = 0;
|
|
float y_offset = 300;
|
|
|
|
//float minx = 999;
|
|
//float miny = 999;
|
|
//float maxx = -999;
|
|
//float maxy = -999;
|
|
float minx = 0;
|
|
float miny = 0;
|
|
float maxx = 0;
|
|
float maxy = 0;
|
|
|
|
PFont metaBold;
|
|
|
|
String filename = "optimize_me.txt";
|
|
|
|
String comment = "";
|
|
float tool_size = 0.001f;
|
|
|
|
int m_pass;
|
|
boolean m_monochrome = false;
|
|
|
|
/*
|
|
* Parse Strings and produce Lines.
|
|
*
|
|
*/
|
|
public void prepare_lines(String[] lines) {
|
|
int i;
|
|
|
|
for (i=0; i < lines.length; i++) {
|
|
if (lines[i] != null) {
|
|
// println(lines[i]);
|
|
String[] pieces = split(lines[i], ',');
|
|
if (pieces.length == 5) {
|
|
float x1 = PApplet.parseFloat(pieces[0]);
|
|
float y1 = PApplet.parseFloat(pieces[1]);
|
|
float x2 = PApplet.parseFloat(pieces[2]);
|
|
float y2 = PApplet.parseFloat(pieces[3]);
|
|
int m_pass = PApplet.parseInt(pieces[4]);
|
|
plines[i] = new Line(x1, y1, x2, y2, m_pass);
|
|
// println(nfs(plines[i].sx, 1, 5) +", " + nfs(plines[i].sy, 1, 5) + " " + nfs(plines[i].pass, 2));
|
|
minx = min(minx, x1);
|
|
miny = min(miny, y1);
|
|
maxx = max(maxx, x1);
|
|
maxy = max(maxy, y1);
|
|
minx = min(minx, x2);
|
|
miny = min(miny, y2);
|
|
maxx = max(maxx, x2);
|
|
maxy = max(maxy, y2);
|
|
}
|
|
}
|
|
}
|
|
/* println("prepare_lines exit");
|
|
println("minx = " + nfs(minx, 1, 3));
|
|
println("miny = " + nfs(miny, 1, 3));
|
|
println("maxx = " + nfs(maxx, 1, 3));
|
|
println("maxy = " + nfs(maxy, 1, 3));
|
|
*/
|
|
}
|
|
|
|
/*
|
|
* Calculate scaling based on the extents of the trace coordinates.
|
|
*
|
|
*/
|
|
public void set_scaling() {
|
|
x_scale = (width - 70) / (maxx - minx);
|
|
y_scale = (height - 70) / (maxy - miny);
|
|
// println("x_scale = " + nfs(x_scale, 1, 3));
|
|
// println("y_scale = " + nfs(y_scale, 1, 3));
|
|
|
|
y_scale = x_scale = min(x_scale, y_scale);
|
|
y_scale = -abs(y_scale);
|
|
|
|
if (minx < 0) {
|
|
x_offset += abs(minx) * x_scale;
|
|
}
|
|
x_offset += 20;
|
|
y_offset = height - 40;
|
|
|
|
/*
|
|
println("x_scale = " + nfs(x_scale, 1, 3));
|
|
println("y_scale = " + nfs(y_scale, 1, 3));
|
|
println("x_offset = " + nfs(x_offset, 1, 3));
|
|
println("y_offset = " + nfs(y_offset, 1, 3));
|
|
*/
|
|
}
|
|
|
|
/*
|
|
* Right-justified text.
|
|
*
|
|
*/
|
|
public void rtext(String s, float x, float y) {
|
|
text(s, x - textWidth(s), y);
|
|
}
|
|
|
|
/*
|
|
* Setup the window.
|
|
* Read and parse the file.
|
|
*
|
|
*/
|
|
public void setup() {
|
|
String matches[];
|
|
size(800, 600);
|
|
|
|
String line = null;
|
|
String[] lines = new String[1];
|
|
BufferedReader reader = createReader(filename);
|
|
do {
|
|
try {
|
|
line = reader.readLine();
|
|
}
|
|
catch (IOException e) {
|
|
println("Mama I'm sick");
|
|
}
|
|
if (line != null) {
|
|
matches = match(line, "^# board=(.+)");
|
|
if (matches != null) {
|
|
comment = matches[1];
|
|
}
|
|
matches = match(line, "^# tool size=(.+)");
|
|
if (matches != null) {
|
|
tool_size = PApplet.parseFloat(matches[1]);
|
|
}
|
|
matches = match(line, "^# pass=(.+)");
|
|
if (matches != null) {
|
|
m_pass = PApplet.parseInt(matches[1]);
|
|
}
|
|
matches = match(line, "^#");
|
|
if (matches == null) {
|
|
lines = (String[])append(lines, (line + "," + nf(m_pass,2)));
|
|
}
|
|
}
|
|
} while (line != null);
|
|
plines = (Line[])expand(plines, lines.length);
|
|
prepare_lines(lines);
|
|
set_scaling();
|
|
noLoop();
|
|
}
|
|
|
|
/*
|
|
* Draw a Line.
|
|
*
|
|
*/
|
|
public void line(Line l) {
|
|
if (l != null) {
|
|
if (! m_monochrome) {
|
|
stroke(color_table[l.pass % 9]);
|
|
}
|
|
line(l.sx * x_scale + x_offset, l.sy * y_scale + y_offset,
|
|
l.ex * x_scale + x_offset, l.ey * y_scale + y_offset);
|
|
// println(nfs(l.sx, 1, 5) +", " + nfs(l.sy, 1, 5));
|
|
// print(nfs(l.sx * x_scale + x_offset, 1, 5) +", " + nfs(l.sy * y_scale + y_offset, 1, 5) + ", ");
|
|
// println(nfs(l.ex * x_scale + x_offset, 1, 5) +", " + nfs(l.ey * y_scale + y_offset, 1, 5));
|
|
}
|
|
else {
|
|
println("null line");
|
|
}
|
|
}
|
|
|
|
/*
|
|
* X scale and offset.
|
|
*
|
|
*/
|
|
public float xso(float x) {
|
|
return x * x_scale + x_offset;
|
|
}
|
|
|
|
/*
|
|
* Y scale and offset.
|
|
*
|
|
*/
|
|
public float yso(float y) {
|
|
return y * y_scale + y_offset;
|
|
}
|
|
|
|
/*
|
|
* Text notes around the periphery of the window.
|
|
*
|
|
*/
|
|
public void ornaments() {
|
|
stroke(255, 0, 0);
|
|
fill(255, 0, 0);
|
|
strokeWeight(1);
|
|
|
|
// lower-left corner
|
|
line(xso(minx), yso(miny) - 10, xso(minx), yso(miny));
|
|
line(xso(minx), yso(miny), xso(minx) + 10, yso(miny));
|
|
|
|
text(nfs(minx, 1, 3) + ", " + nfs(miny, 1, 3), xso(minx) + 5, yso(miny) + 12);
|
|
|
|
// lower-right
|
|
line(xso(maxx), yso(miny) - 10, xso(maxx), yso(miny));
|
|
line(xso(maxx), yso(miny), xso(maxx) - 10, yso(miny));
|
|
|
|
// upper-right
|
|
line(xso(maxx) - 10, yso(maxy), xso(maxx), yso(maxy));
|
|
line(xso(maxx), yso(maxy), xso(maxx), yso(maxy) + 10);
|
|
rtext(nfs(maxx, 1, 3) + ", " + nfs(maxy, 1, 3), xso(maxx), yso(maxy) - 5);
|
|
|
|
// upper-left corner
|
|
line(xso(minx) + 10, yso(maxy), xso(minx), yso(maxy));
|
|
line(xso(minx), yso(maxy), xso(minx), yso(maxy) + 10);
|
|
|
|
// cross-hoirs at the origin
|
|
line(xso(0)-10, yso(0), xso(0)+10, yso(0));
|
|
line(xso(0), yso(0)-10, xso(0), yso(0)+10);
|
|
noFill();
|
|
ellipse(xso(0), yso(0), 10, 10);
|
|
|
|
// comment from the file
|
|
stroke(255);
|
|
text(comment, 10, 20);
|
|
|
|
// tool size and number of passes
|
|
rtext("tool size " + nfs(tool_size, 1, 3), width - 120, 20);
|
|
rtext(nfs(m_pass, 1) + " passes", width - 40, 40);
|
|
|
|
// brief help
|
|
text("Keys: +/- zoom, 1 no zoom, 2 zoom 2x, arrows move, a left, de right, w, up, so down", 10, 40);
|
|
text("c toggle color, qx quit", 60, 60);
|
|
}
|
|
|
|
float m_scale = 1.0f;
|
|
float m_trans_x = 0;
|
|
float m_trans_y = 0;
|
|
int draw_cnt = 0;
|
|
boolean m_drawing;
|
|
public void draw() {
|
|
m_drawing = true;
|
|
background(bg_color);
|
|
stroke(127);
|
|
fill(bg_color);
|
|
strokeWeight(4);
|
|
quad(0, 0, width-1, 0, width-1, height-1, 0, height-1);
|
|
strokeWeight(1);
|
|
|
|
fill(255, 0, 0);
|
|
metaBold = loadFont("BankGothic-Light-14.vlw");
|
|
textFont(metaBold);
|
|
rtext("Viewer 1.5", width - 20, 20);
|
|
|
|
stroke(200);
|
|
scale(m_scale);
|
|
translate(m_trans_x, m_trans_y);
|
|
if (plines != null) {
|
|
println("plines.length = " + nf(plines.length, 3));
|
|
strokeWeight(tool_size * x_scale);
|
|
for (int i = 0; i < plines.length; i++) {
|
|
line(plines[i]);
|
|
}
|
|
}
|
|
else {
|
|
text("Didn't open the file", 100, height / 2);
|
|
}
|
|
|
|
ornaments();
|
|
m_drawing = false;
|
|
}
|
|
|
|
public void keyPressed() {
|
|
if (m_drawing) {
|
|
return;
|
|
}
|
|
switch (key) {
|
|
|
|
/*
|
|
* Toggle colored lines.
|
|
*
|
|
*/
|
|
case 'c':
|
|
case 'C':
|
|
m_monochrome = ! m_monochrome;
|
|
break;
|
|
|
|
/*
|
|
* Zoom in or out.
|
|
*
|
|
*/
|
|
case '+':
|
|
case '=':
|
|
if (m_scale < 10) {
|
|
m_scale += 0.2f;
|
|
m_trans_x -= width / m_scale / 20;
|
|
m_trans_y -= height / m_scale / 20;
|
|
}
|
|
break;
|
|
case '_':
|
|
case '-':
|
|
if (m_scale > 0.5f) {
|
|
m_scale -= 0.2f;
|
|
m_trans_x += width / m_scale / 20;
|
|
m_trans_y += height / m_scale / 20;
|
|
}
|
|
break;
|
|
|
|
/*
|
|
* Fixed zoom amounts.
|
|
*
|
|
*/
|
|
case '1':
|
|
m_scale = 1;
|
|
m_trans_x = 0;
|
|
m_trans_y = 0;
|
|
break;
|
|
case '2':
|
|
m_scale = 2;
|
|
m_trans_x = -width / 4;
|
|
m_trans_y = -height / 4;
|
|
break;
|
|
|
|
/*
|
|
* Exit the program.
|
|
*
|
|
*/
|
|
case 'x':
|
|
case 'X':
|
|
case 'q':
|
|
case 'Q':
|
|
exit();
|
|
break;
|
|
|
|
/*
|
|
* Small movement left, right, up, down.
|
|
*
|
|
* Use these keys:
|
|
*
|
|
* QWERTY Dvorak
|
|
* w ,
|
|
* a d a e
|
|
* s o
|
|
*
|
|
*/
|
|
case 'a':
|
|
m_trans_x += width / 80;
|
|
break;
|
|
case 'e':
|
|
case 'd':
|
|
m_trans_x -= width / 80;
|
|
break;
|
|
case ',':
|
|
case 'w':
|
|
m_trans_y += width / 80;
|
|
break;
|
|
case 'o':
|
|
case 's':
|
|
m_trans_y -= width / 80;
|
|
break;
|
|
|
|
/*
|
|
* Move using the arrow keys.
|
|
*
|
|
*/
|
|
case CODED:
|
|
switch (keyCode) {
|
|
case LEFT:
|
|
m_trans_x += width / 20;
|
|
break;
|
|
case RIGHT:
|
|
m_trans_x -= width / 20;
|
|
break;
|
|
case UP:
|
|
m_trans_y += height / 20;
|
|
break;
|
|
case DOWN:
|
|
m_trans_y -= height / 20;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
background(bg_color);
|
|
redraw();
|
|
}
|
|
|
|
|
|
static public void main(String args[]) {
|
|
PApplet.main(new String[] { "--bgcolor=#ffffff", "viewer" });
|
|
}
|
|
}
|