/*
Code by Lucky Larry: www.luckylarry.co.uk
RGB visualisation to control LED's by dragging shapes to define colour
Copyright (C) 2009 Pete Dainty aka 'Lucky Larry'
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
// import the serial library to allow us to send data via the serial ports (USB in this case)
import processing.serial.*;
// create a new instance of the serial classes and assign it to 'myPort'
Serial myPort;
// create set of variables to store vector infomation (X nd Y co-oordinates)
PVector areaPointA,areaPointB,areaPointC,pointA,pointB,pointC,pointDrag;
// create an arry to store the vectors of each point of our shape in this case a triangle
PVector[] rgbTriangle;
/* the next 3 lines uses a custom class at the bottom of this code.
the class extends java.awt.polygon which means I can use this to create a triangle to test if the
mouse is in side the shape. */
// new instance of our class
DragArea area;
// these lines specify the X value and Y value for each point of our triangle {xpoint1, xpoint2, xpoint3} etc..
int[]xpoints={152,23,284};
int[]ypoints={23,248,248};
// set 3 variables to store the colour values.
int R, G, B;
// setup our font
PFont myFont;
/* setup our background and variables */
void setup () {
// screen size
size(305,271);
// setup my font type and size
myFont = createFont("verdana", 12);
textFont(myFont);
// define our new instance of the custom class. (X points, Y points, Number of points in the shape) more info below by the class
area = new DragArea(xpoints,ypoints,3);
// define the area vectors - we use these to see how far our point is from its original source, needed to calculate the value between 0 and 255
areaPointA = new PVector(152,25);
areaPointB = new PVector(25,246);
areaPointC = new PVector(280,246);
// specifiy the starting co-ordinates for the triangle that we can move
pointA = new PVector(152,40);
pointB = new PVector(40,230);
pointC = new PVector(265,230);
// set the array with the new points.
rgbTriangle = new PVector[]{pointA,pointB,pointC};
// center our shapes
ellipseMode(CENTER);
rectMode(CENTER);
// set smoothing for our shapes edges
smooth();
/* define which port to use mine is COM10 and is 2nd in the array list.
you can print out to the screen which ports are accessible by using this code line below
set the baud rate to the same as in your Arduino code so mine is 9600
*/
// println(Serial.list());
//myPort = new Serial(this, Serial.list()[1], 9600);
} // end setup
/* begin our animation/ interaction */
void draw () {
// set background to black
background(50);
// set the colours and positions of the large colour circles to indentify where red is 100% etc...
// fill(R, G, B);
fill(255,0,0);
// ellipse(X co-ordinate, Y co-ordinate,width, height)
ellipse(areaPointA.x, areaPointA.y, 15,15);
fill(0,255,0);
ellipse(areaPointB.x, areaPointB.y, 15,15);
fill(0,0,255);
ellipse(areaPointC.x, areaPointC.y, 15,15);
// create our background triangle to show the area in which we can move.
fill(100);
beginShape(TRIANGLES);
vertex(areaPointA.x,areaPointA.y);
vertex(areaPointB.x,areaPointB.y);
vertex(areaPointC.x,areaPointC.y);
endShape();
/* set the fill of our coloured triangle we work out the values by
getting the current points co-ordinates and working out the distance
from the original point. These distances are actually calculated on a
circular area so it draws an elliptical area from the origin point from
the 2 adjacent sides of the triangle. First set the values to our variables
R, G, B and round them so that they'll be integers and parse them using the int() method
*/
R = int(round(255-dist(areaPointA.x,areaPointA.y,pointA.x,pointA.y)));
G = int(round(255-dist(areaPointB.x,areaPointB.y,pointB.x,pointB.y)));
B = int(round(255-dist(areaPointC.x,areaPointC.y,pointC.x,pointC.y)));
fill(R,G,B);
/* we need to send this fill value to the Arduino to light up the LED's accordingly
we do this by writing a value to the serial port.
You can write values to the serial port using bytes, integers and chars.
I'm going to send the 3 values separately and store them in an array on the Arduino
*/
//myPort.write(R);
//myPort.write(G);
//myPort.write(B);
// create our RGB triangle from the draggable points
beginShape(TRIANGLES);
vertex(pointA.x,pointA.y);
vertex(pointB.x,pointB.y);
vertex(pointC.x,pointC.y);
endShape();
// create the drag handles for each point in the draggable shape.
for (int i=0; i mouseX &&
rgbTriangle[i].y-5 < mouseY &&
rgbTriangle[i].y+5 > mouseY) {
pointDrag = rgbTriangle[i];
}
}
}
/* If the mouse is pressed and the value of pointDrag is not null - it will be null if the mouse is outside the handle area.
We then do another check to see if our mouse pointer is inside our polygon area. In Processing we can use the .contains() method
that we get from the custom class at the bottom to check if an XY value is inside the polygons area.
*/
void mouseDragged() {
if ( pointDrag != null )
{
if(area.contains(mouseX,mouseY) ) {
// set the XY values of the point we're dragging to the values of the mouse
pointDrag.x = mouseX;
pointDrag.y = mouseY;
}
}
}
/* This doesnt look like much code but what we're doing is extending a class with another class.
By extending our class with java.awt.Polygon we then inherit that classes methods to use as our own.
Since Processing is based upon Java there are many classes that we can import to extend Processing.
The functions of java.awt.Polygon can be found here: http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Polygon.html
This makes it much easier to do collision detection with shapes - Processing can handle rectangles and circles fine
but for triangles this saves alot of effort.
*/
class DragArea extends java.awt.Polygon {
/* our DragArea class is basically an instance of java.awt.Polygons and this class expects and array of X points, Y points and the number of
points in our shape. The variable names also have to be direct references to what this class expects, so xpoints, ypoints and npoints are all
set/defined in the java class.
*/
public DragArea(int[] xpoints,int[] ypoints, int npoints) {
// super invokes the java.awt.Polygon class
super(xpoints,ypoints,npoints);
}
}