/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.iol3AoQzf9Y/rev.5
*
* authors:
* GoToLoop
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
/**
Line vs Circle Intersection
by KarlHungus (2013/Apr)
http://forum.processing.org/topic/if-touched-send-once
*/
int circleX, circleY, circleR;
int lineX, lineY;
boolean isIntersecting;
final static String GFX = P2D; // Use JAVA2D for Processing 2+
void setup() {
size(600, 400, GFX);
noLoop(); // turn off draw()!;
smooth();
ellipseMode(RADIUS);
strokeWeight(2);
circleX = width >> 1;
circleY = height >> 1;
circleR = height >> 2;
lineX = width - width/8;
lineY = height - height/8;
mouseX = mouseY = lineX;
}
void mouseMoved() {
redraw(); // 1 round of draw()!
}
void draw() {
background(0300);
if ( checkIntersection(lineX, lineY, mouseX, mouseY,
circleX, circleY, circleR) ) {
if (!isIntersecting) println("Sending OSC...");
isIntersecting = true;
}
else {
if (isIntersecting) println("Stopped intersecting!");
isIntersecting = false;
}
noStroke();
fill(isIntersecting? 0 : -1);
ellipse(circleX, circleY, circleR, circleR);
stroke(#00FF00);
line(lineX, lineY, mouseX, mouseY);
}
// Code adapted from Paul Bourke:
// http://local.wasp.uwa.edu.au/~pbourke/geometry/sphereline/raysphere.c
boolean checkIntersection(float x1, float y1, float x2, float y2,
float cx, float cy, float cr ) {
float dx = x2 - x1;
float dy = y2 - y1;
float a = dx*dx + dy*dy;
float b = (dx*(x1 - cx) + (y1 - cy)*dy) * 2;
float c = cx*cx + cy*cy;
c += x1*x1 + y1*y1;
c -= (cx*x1 + cy*y1) * 2;
c -= cr*cr;
float delta = b*b - 4*a*c;
if (delta < 0) return false; // Not intersecting
delta = sqrt(delta);
float mu = (-b + delta) / (2*a);
float ix1 = x1 + mu*dx;
float iy1 = y1 + mu*dy;
mu = (b + delta) / (-2*a);
float ix2 = x1 + mu*dx;
float iy2 = y1 + mu*dy;
// Intersection points
fill(#FF0000);
ellipse(ix1, iy1, 5, 5);
ellipse(ix2, iy2, 5, 5);
// Figure out which point is closer to the circle
boolean test = dist(x1, y1, cx, cy) < dist(x2, y2, cx, cy);
float closerX = test? x2:x1;
float closerY = test? y2:y1;
return dist(closerX, closerY, ix1, iy1) < dist(x1, y1, x2, y2) ||
dist(closerX, closerY, ix2, iy2) < dist(x1, y1, x2, y2);
}