Yet another long post
So I did that set starting point feature. Code is below. Bugs and weird comments expected because I’m feeling really tired. Click mouse button to set starting point and click it again to set direction.
I used mouseMoved
and mouseClicked
events to get starting point and direction. Variable state
is used to keep track of what’s going on. Serial port initialization is moved from setup()
to mouseClicked()
so it only starts reading the port when starting point and direction are set.
import processing.serial.*;
// States
final int STATE_GETTING_START_POINT = 0;
final int STATE_GETTING_DIRECTION = 1;
final int STATE_TRACKING = 2;
int state = STATE_GETTING_START_POINT;
PGraphics buffer;
PImage img;
Serial PicPort;
String myString = null;
int cr = 13; // strings are terminated by ascii 13: carriage return aka newline
float oldangle = 0;
float x0 = 0;
float y0 = 0;
float x1 = 0;
float y1 = 0;
float angle = 0;
float travel = 0;
void setup() {
size(600,400);
// Create an off-screen buffer and initial image.
buffer = createGraphics(600, 400, JAVA2D);
buffer.beginDraw();
buffer.background(32);
buffer.endDraw();
img = buffer.get(0, 0, buffer.width, buffer.height);
}
void draw() {
background(255);
image(img,0,0);
}
// This gets called whenever there’s data available
void serialEvent(Serial p) {
myString = p.readStringUntil(cr);
if (myString != null) {
// println(myString);
// examples of myString: “r:259”, “t:18”, “t:0”
String telemetry [] = split(myString, “:”);
if (telemetry.length == 2) {
String qualifier = telemetry[0];
float value = float(telemetry[1]); // WHY won’t this convert to int ?!?!
int valint = int(value);
// println (qualifier +"="+ valint);
if (qualifier.equals(“r”)) {
// rotation
angle = oldangle + value / 360 * TWO_PI; // input ranges 0-359, result is in radians
// println (“rotated: " + value + " degrees” +" “+ angle +” radians");
}
if (qualifier.equals(“t”)) {
// travel
travel = value / 50 * width * .01; // input ranges 0-50, result is in 1% increments of screen width
// println (“traveled: " + value + " mickeys” +" “+ travel +” pixels");
// background(192);
x1 = x0 + travel * cos(angle);
y1 = y0 + travel * sin(angle);
buffer.beginDraw();
buffer.stroke(192);
buffer.rectMode(CENTER);
buffer.translate(width / 2, height / 2);
buffer.strokeWeight(2);
buffer.line(x0,y0 , x1, y1);
buffer.endDraw();
oldangle = angle;
x0 = x1;
y0 = y1;
}
}
}
img = buffer.get(0, 0, buffer.width, buffer.height);
}
void storeStartingPoint() {
// Mouse coordinates are originated from upper left corner.
// Translate starting point by width / 2 and height / 2
x0 = mouseX - width / 2;
y0 = mouseY - height / 2;
//println (“x0=” + x0 + “, y0=” + y0);
}
void storeDirectionPoint() {
// Mouse coordinates are originated from upper left corner.
// Translate starting point by width / 2 and height / 2
x1 = mouseX - width / 2;
y1 = mouseY - height / 2;
//println (“x0=” + x0 + “, y0=” + y0);
}
void drawStartingPointAndDirectionToBuffer() {
// Draw starting point and direction to buffer
buffer.beginDraw();
buffer.background(32); // Clear
buffer.stroke(192);
buffer.rectMode(CENTER);
buffer.translate(width / 2, height / 2);
buffer.ellipse(x0,y0 , 10,10);
// We want to draw direction only if state is STATE_GETTING_DIRECTION
if( state == STATE_GETTING_DIRECTION ) {
buffer.line (x0, y0, x1, y1);
}
buffer.endDraw();
img = buffer.get(0, 0, buffer.width, buffer.height);
}
// mouseMoved event is used to draw nice animation while
// setting starting point and direction
void mouseMoved() {
switch(state) {
case STATE_GETTING_START_POINT:
storeStartingPoint();
// Draw starting point to buffer
drawStartingPointAndDirectionToBuffer();
break;
case STATE_GETTING_DIRECTION:
storeDirectionPoint();
// Draw starting point and direction to buffer
drawStartingPointAndDirectionToBuffer();
break;
case STATE_TRACKING:
// Nothing to do here.
break;
default:
// Should not happen!
break;
}
}
// mouseClicked event is used to set starting point and direction.
// We also change the state here
void mouseClicked() {
println (“mouseX=” + mouseX + “, mouseY=” + mouseY);
switch(state) {
case STATE_GETTING_START_POINT:
storeStartingPoint();
state = STATE_GETTING_DIRECTION;
break;
case STATE_GETTING_DIRECTION:
storeDirectionPoint();
// Calculate x and y differences and angle
float dx = x1 - x0;
float dy = y1 - y0;
angle = atan2(dy, dx);
println (“angle=” + degrees(angle));
// Change state before calling drawStartingPointAndDirectionToBuffer
// so direction line is not drawn anymore
state = STATE_TRACKING;
// Draw starting point to buffer
drawStartingPointAndDirectionToBuffer();
// Start reading serial port
// parent comport baud parity databits stopbit
PicPort = new Serial(this, Serial.list()[0], 4800, ‘N’, 8, 1.0);
PicPort.bufferUntil(cr); // Buffer until CR is found (before calling serialEvent)
break;
case STATE_TRACKING:
// Nothing to do here
break;
default:
// Should not happen!
break;
}
}