/* 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); }