/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.zLU$IJZshw$/rev.4461
*
* authors:
* Joshua Lansford
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
// Pressing Control-R will render this sketch.
PFont font;
double fieldPercentage = 0;
double percentageIncrement = .025;
double lagMax = .9;
int width = 500;
int height = 268;
ArrayList shapes = new ArrayList();
double minShapeX = 120;
double maxShapeX = 365;
class Shape{
double x; double y;
abstract void draw();
abstract double hitLine( double yPos );
abstract double mouseHit( double x, double y );
//Dragging
boolean locked = false;
double lockX, lockY;
void mousePressed(){
if( mouseHit() ){
locked = true;
lockX = mouseX-x;
lockY = mouseY-y;
}
}
void mouseDragged(){
if( locked ){
x = mouseX-lockX;
y = mouseY-lockY;
}
if( x < minShapeX ) x = minShapeX;
if( x > maxShapeX ) x = maxShapeX;
}
void mouseReleased(){
locked = false;
}
void draw(){
if( mouseHit() ){
stroke( #dddddd );
}else{
stroke( 0 );
}
if( locked ){
fill( #777777 );
}else{
fill( 0 );
}
}
}
void mousePressed(){
for( Shape shape : shapes )shape.mousePressed();
}
void mouseDragged(){
for( Shape shape : shapes )shape.mouseDragged();
}
void mouseReleased(){
for( Shape shape : shapes) shape.mouseReleased();
}
class Rect extends Shape{
double size = 30;
public Rect( double newX, double newY, double newSize ){
x = newX; y = newY; size = newSize;
}
void draw(){
super.draw();
rect( x, y, size, size );
}
double hitLine( double yPos ){
double result = -1;
if( yPos > y && yPos < y+size ){
result = x;
}
return result;
}
double mouseHit(){
if( mouseX < x ) return false;
if( mouseX > x+size ) return false;
if( mouseY < y ) return false;
if( mouseY > y+size) return false;
return true;
}
}
class Circle extends Shape{
double size = 30;
public Circle( double newX, double newY, double newSize ){
x = newX; y = newY; size = newSize;
}
void draw(){
super.draw();
ellipse( x, y, size, size );
}
double hitLine( double yPos ){
double result = -1;
if( yPos > y-size/2 && yPos < y+size/2 ){
result = -sqrt( pow(size/2,2)-pow(yPos-y,2) ) + x;
}
return result;
}
double mouseHit(){
return sqrt( pow(mouseX-x,2) + pow( mouseY-y,2 ) ) < size/2;
}
}
void setup() { // this is run once.
// set the background color
background(255);
// canvas size (Integers only, please.)
//size(width, height);
size( 500, 268 );
// smooth edges
smooth();
// limit the number of frames per second
frameRate(30);
// set the width of the line.
strokeWeight(1);
// load font
font = loadFont("FFScala.ttf");
textFont(font);
shapes.add( new Rect( 72+50+50+20+50, 10+50+80+20, 30 ) );
shapes.add( new Rect( 80+75+50, 10+50+80, 20 ) );
shapes.add( new Circle( 300, 70, 25 ) );
shapes.add( new Circle( 170, 170, 50 ) );
}
double findHitX( double strokeHeight ){
//see if this line hits
double hitX = -1;
for( Shape shape : shapes ){
double testHitX = shape.hitLine( strokeHeight );
if( testHitX > 0 ){
if( hitX > 0 ){
hitX = min( hitX, testHitX );
}else{
hitX = testHitX;
}
}
}
return hitX;
}
double scopeMaxX = 451;
double scopeMinX = 415;
double scopeMaxY = 195;
double scopeMinY = 221;
void draw() { // this is run repeatedly.
//background
fill( #ffffff ); stroke( #ffffff );
rect( 0, 0, width, height );
// set the width of the line.
strokeWeight(1);
// lenses
fill( #008D90 );
stroke( #008D90 );
ellipse( 120, 82, (136-106), (144-24) );
ellipse( 368, 82, (136-106), (144-24) );
fill( #000000 );
text( "Collimator Lens", 120-20-10-10, 82-40-10-20+5 );
text( "Focal Lens", 368-20-10, 82-40-10-20+5 );
// laser box
fill( #0000FF );
stroke( #0000FF );
rect( 109, 207, (133-108), (228-207) );
fill( #000000 );
text( "Laser", 122-20+5, 241 );
//Receiver
fill( #0000FF );
rect( 467, 64, (482-466), (105-64) );
fill( #000000 ); stroke( 0 );
text( "Receiver", 467-30+10, 64-5 );
//PC
//card
fill( #006500 ); stroke( #006500 );
rect( 409, 183, (457-409), (227-183) );
//computer base
fill( #404040 ); stroke( #404040 );
rect( 359, 205, (409-359), (227-205) );
//screen
fill( #00ffff ); stroke( #00ffff );
rect( 359, 166, (409-359), (212-166), 10 );
fill( #000000 ); stroke( 0 );
text( "PC", 359+10+10-5, 166+50+20+5 );
//Line to PC
fill( #0000ff ); stroke( #0000ff );
line( 474, 105, 474, 117 );
line( 474, 117, 450, 117 );
line( 450, 117, 450, 142 );
line( 450, 142, 487, 142 );
line( 487, 142, 487, 208 );
line( 487, 208, 458, 208 );
triangle(466, 134, 481, 142, 466, 149);
//Laser
stroke( #ff0000 );
line( 120, 207, 23, 83 );
double lagPercentage = 0;
double scopeLastX = 0;
double scopeLastY = 0;
for( double lagPercentage = 0;
lagPercentage < lagMax;
lagPercentage += percentageIncrement ){
int scanPercentage = fieldPercentage-lagPercentage;
while( scanPercentage < 0 ) scanPercentage += 1;
double strokeHeight =
(fieldBottom-fieldTop)*scanPercentage+fieldTop;
double alpha = lagPercentage*(0-255)/lagMax+255;
stroke( 255, 0, 0, alpha );
line( 23, 83, 120, strokeHeight );
double hitX = findHitX(strokeHeight);
//Draw laser
if( hitX > 0 ){
line( 120, strokeHeight, hitX, strokeHeight );
}else{
line( 120, strokeHeight, 367, strokeHeight );
line( 367, strokeHeight, 466, 85 );
}
//draw o-scope
double scopeX = scanPercentage*(scopeMaxX-scopeMinX)+scopeMinX;
double scopeY = (hitX > 0)?scopeMaxY:scopeMinY;
stroke( 181, 230, 29, alpha );
if( scopeLastX > 0 && scopeX < scopeLastX ){
line( scopeLastX, scopeLastY, scopeX, scopeY );
}
scopeLastX = scopeX;
scopeLastY = scopeY;
}
//text( TWO_PI, 20, 20 );
//Prism
double middleX = 13+2;
double middleY = 77+2;
double halfWidth = 13-2;
double cornerWidth = 13-65;
beginShape();
for( int virtex = 0; virtex < 8; ++virtex ){
double angle1 = virtex*TWO_PI/8 + fieldPercentage*(TWO_PI/8)-.3;
double x = halfWidth*cos( angle1 );
double y = halfWidth*sin( angle1 );
vertex( middleX+x, middleY+y );
}
endShape();
fill( #000000 ); stroke( 0 );
text( "Rotating", 14-10+3, 57-5+2 );
text( "Mirror", 14-10+3, 67-5+2 );
//Shapes
for( Shape shape : shapes ){
shape.draw();
}
//draw PC measurements
double measurementX = 362;
double measurementY = 178;
boolean lastLightBlocked = false;
double lastSwitchPercent = -1;
for( double testPercent = 0; testPercent < 1; testPercent += .01 ){
double strokeHeight =
(fieldBottom-fieldTop)*testPercent+fieldTop;
boolean lightBlocked = findHitX(strokeHeight) > 0;
if( lightBlocked != lastLightBlocked ){
if( lastSwitchPercent > 0 ){
if( !lightBlocked ){
fill( 0 );
}else{
fill( #0000ff );
}
double value =
round((testPercent-lastSwitchPercent)*30*100)/100;
text( value + "mm", measurementX, measurementY );
measurementY += 11;
}
lastLightBlocked = lightBlocked;
lastSwitchPercent = testPercent;
}
}
//stroke( 0 );
//text( "123mm", measurementX, measurementY );
//animation progression
fieldPercentage += percentageIncrement;
if( fieldPercentage > 1 ) fieldPercentage = 0;
//text( fieldPercentage, 20, 20 );
//fieldPercentage = 0;
}
double fieldTop = 43;
double fieldBottom = 126;