Here's what I ended up with. I'm using java.awt.Polygon to find out when I mouse over the interior of the shape, but I haven't rigged it up to update when you drag the vertices yet. Other than that it seems to be peachy!
Code:import controlP5.*;
objectsCollection objects;
int clickTolerance = 5;
void setup() {
size(400,400); smooth();
objects = new objectsCollection();
objects.spawnTriangle();
}
void draw() {
background(255);
objects.display();
}
void mousePressed() {
objects.pressedMouse();
}
void mouseDragged() {
objects.draggedMouse();
}
void mouseReleased() {
objects.releasedMouse();
}
class objectsCollection {
ArrayList theObjects;
int serialIDCounter = 0;
objectsCollection() {
theObjects = new ArrayList();
}
void display() {
if(!theObjects.isEmpty()) {
for(int i=0; i<theObjects.size(); i++) {
geomObject theObject = (geomObject)theObjects.get(i);
theObject.display();
}
}
}
void spawnPoint(float x, float y) {
theObjects.add(new pointObject(serialIDCounter(),x,y));
}
void spawnLine(pointObject p1, pointObject p2) {
theObjects.add(new lineObject(serialIDCounter(),p1,p2));
}
void spawnShape(ArrayList vertices) {
theObjects.add(new shapeObject(vertices));
}
void spawnTriangle() {
spawnPoint(width/2,height/2-50);
pointObject p1 = (pointObject) theObjects.get(latestIndex());
spawnPoint(width/2-50,height/2+50);
pointObject p2 = (pointObject) theObjects.get(latestIndex());
spawnPoint(width/2+50,height/2+50);
pointObject p3 = (pointObject) theObjects.get(latestIndex());
ArrayList vertices = new ArrayList();
vertices.add(p1);
vertices.add(p2);
vertices.add(p3);
spawnShape(vertices);
spawnLine(p1,p2);
spawnLine(p2,p3);
spawnLine(p3,p1);
}
int latestIndex() { return theObjects.size()-1; }
int serialIDCounter() {
serialIDCounter++;
return serialIDCounter;
}
void pressedMouse() {
for(int i=0; i<theObjects.size(); i++) {
geomObject theObject = (geomObject)theObjects.get(i);
theObject.pressedMouse();
}
}
void draggedMouse() {
for(int i=0; i<theObjects.size(); i++) {
geomObject theObject = (geomObject)theObjects.get(i);
theObject.draggedMouse();
}
}
void releasedMouse() {
for(int i=0; i<theObjects.size(); i++) {
geomObject theObject = (geomObject)theObjects.get(i);
theObject.releasedMouse();
}
}
}
class geomObject {
int ID;
String type = "";
void setID(int i) {
ID = i;
}
void display() {}
void pressedMouse() {}
void draggedMouse() {}
void releasedMouse() {}
}
class lineObject extends geomObject {
pointObject p1; pointObject p2;
PVector mouseDatum = new PVector();
boolean locked = false;
lineObject(int IDi, pointObject p1i, pointObject p2i) {
ID = IDi;
p1 = p1i; p2 = p2i;
type = "line";
}
void display() {
noFill(); stroke(200); strokeWeight(1);
if(bounds(mouseX,mouseY)) stroke(#ffcc00);
line(p1.location.x,p1.location.y,p2.location.x,p2.location.y);
p1.display();
p2.display();
if(bounds(mouseX,mouseY)) {
PVector mid = PVector.add(p1.location,p2.location); mid.div(2);
noFill(); stroke(200); strokeWeight(1);
ellipse(mid.x,mid.y,12,12);
}
}
boolean clicked(float x, float y) {
if (p1.bounds(x,y) || p2.bounds(x,y) || bounds(x,y)) return true;
else return false;
}
void pressedMouse() {
if(bounds(mouseX,mouseY)) {
locked = true;
mouseDatum.set(mouseX,mouseY,0);
}
}
void draggedMouse() {
if(locked) {
PVector mouse = new PVector(mouseX,mouseY);
mouseDatum.sub(mouse);
p1.location.sub(mouseDatum);
p2.location.sub(mouseDatum);
mouseDatum = mouse;
}
}
void releasedMouse() {
locked = false;
}
boolean bounds(float x, float y) {
PVector mouse = new PVector(x,y);
if(distFromSeg(p1.location,p2.location,mouse) < clickTolerance &&
lineSegRatio(p1.location,p2.location,mouse) < 1 &&
lineSegRatio(p1.location,p2.location,mouse) > 0 &&
!p1.bounds(mouseX,mouseY) && !p2.bounds(mouseX,mouseY))
return true;
else return false;
}
float distFromSeg(PVector p1, PVector p2, PVector outlier) {
float g = PVector.dist(p1,p2);
float a = PVector.dist(p1,outlier);
float ratio = lineSegRatio(p1,p2,outlier);
return sqrt( sq(a) - sq(ratio * g));
}
float lineSegRatio(PVector p1, PVector p2, PVector outlier) {
float g = PVector.dist(p1,p2);
float a = PVector.dist(p1,outlier);
float b = PVector.dist(p2,outlier);
return (sq(a) + sq(g) - sq(b))/(2*sq(g));
}
}
class pointObject extends geomObject {
PVector location;
boolean locked = false;
PVector mouseDatum = new PVector(0,0);
pointObject(int IDi, float xi, float yi) {
ID = IDi;
location = new PVector(xi,yi);
type = "point";
}
void display() {
fill(0); noStroke();
if(bounds(mouseX,mouseY)) fill(#ffcc00);
ellipse(location.x,location.y,5,5);
if(bounds(mouseX,mouseY)) {
noFill(); stroke(200); strokeWeight(1);
ellipse(location.x,location.y,12,12);
}
}
boolean bounds(float x, float y) {
PVector mouse = new PVector(x,y);
if (PVector.dist(location,mouse) < clickTolerance) return true;
else return false;
}
void pressedMouse() {
if (bounds(mouseX,mouseY)) {
locked = true;
mouseDatum.set(mouseX,mouseY,0);
}
}
void draggedMouse() {
if(locked) {
PVector mouse = new PVector(mouseX,mouseY);
mouseDatum.sub(mouse);
location.sub(mouseDatum);
mouseDatum = mouse;
}
}
void releasedMouse() {
locked = false;
}
}
// TRUNCATED. SEE NEXT POST.