// Drawbot Mandala // Default code for drawbot kit // (cc) 2008 AS220 Labs #include #define motorStepsA 400 #define motorStepsB 400 #define motorPinA1 15 #define motorPinA2 16 #define motorPinB1 17 #define motorPinB2 18 // Approximate number of steps per inch, calculated from radius of spool // and the number of steps per radius int StepUnit = 102; // Approximate dimensions of the total drawing area int w= 72*StepUnit; int h= 48*StepUnit; // Coordinates of current (starting) point int x1= w/2; int y1= h; // Approximate length of strings from marker to staple int a1= sqrt(pow(x1,2)+pow(y1,2)); int b1= sqrt(pow((w-x1),2)+pow(y1,2)); // Size of image array int rows = 31; int columns = 23 ; float prevR=0; float littleR=50; float bigR=200; float outer_radius = 2000; // Radius of pixel circles, in StepUnits int radius = 26; // equals about .4 inches // Size of page int pageW = columns*radius*2; int pageH = rows*radius*2; // Size of one "pixel" int cellW =2*radius; int cellH = 2*radius; // Coordinate of upper left corner of page int page0X = x1-(pageW/2); int page0Y = y1-pageH-500; int centerx = x1; int centery = y1-outer_radius; // Stepper motor objects: A is left, B is right Stepper StepperA(motorStepsA, motorPinA1,motorPinA2); Stepper StepperB(motorStepsB, motorPinB1,motorPinB2); void setup() { // Set up stepper motors and random # seed, if needed delay(2000); StepperA.setSpeed(15); StepperB.setSpeed(15); delay(2000); randomSeed(analogRead(0)); } float rads(int n) { // Return an angle in radians return (n/180.0 * PI); } void moveTo(int x2, int y2) { // Turn the stepper motors to move the marker from the current point (x1, y1) to (x2, y2) // Note: This only moves in a perfectly straight line if // the distance is the same in both dimensions; this should be fixed, but it works well // a2 and b2 are the final lengths of the left and right strings int a2 = sqrt(pow(x2,2)+pow(y2,2)); int b2 = sqrt(pow((w-x2),2)+pow(y2,2)); int stepA; int stepB; if (a2>a1) { stepA=1; } if (a1>a2) { stepA=-1; } if (a2==a1) { stepA=0; } if (b2>b1) { stepB=1; } if (b1>b2) { stepB=-1; } if (b2==b1) { stepB=0; } // Change the length of a1 and b1 until they are equal to the desired length while ((a1!=a2) || (b1!=b2)) { if (a1!=a2) { a1 += stepA; StepperA.step(-stepA); } if (b1!=b2) { b1 += stepB; StepperB.step(stepB); } } x1 = x2; y1=y2; } void drawCurve(float x, float y, float fx, float fy, float cx, float cy) { // Draw a Quadratic Bezier curve from (x, y) to (fx, fy) using control pt (cx, cy) float xt=0; float yt=0; for (float t=0; t<=1; t+=.0025) { xt = pow((1-t),2) *x + 2*t*(1-t)*cx+ pow(t,2)*fx; yt = pow((1-t),2) *y + 2*t*(1-t)*cy+ pow(t,2)*fy; moveTo(xt, yt); } } void drawCircle(int centerx, int centery, int radius) { // Estimate a circle using 20 arc Bezier curve segments int segments =20; int angle1 = 0; int midpoint=0; moveTo(centerx+radius, centery); for (float angle2=360/segments; angle2<=360; angle2+=360/segments) { midpoint = angle1+(angle2-angle1)/2; float startx=centerx+radius*cos(rads(angle1)); float starty=centery+radius*sin(rads(angle1)); float endx=centerx+radius*cos(rads(angle2)); float endy=centery+radius*sin(rads(angle2)); int t1 = rads(angle1)*1000 ; int t2 = rads(angle2)*1000; int t3 = angle1; int t4 = angle2; drawCurve(startx,starty,endx,endy, centerx+2*(radius*cos(rads(midpoint))-.25*(radius*cos(rads(angle1)))-.25*(radius*cos(rads(angle2)))), centery+2*(radius*sin(rads(midpoint))-.25*(radius*sin(rads(angle1)))-.25*(radius*sin(rads(angle2)))) ); angle1=angle2; } } void drawCircles(int number, int centerx, int centery, int r) { // Draw a certain number of concentric circles at the given center with radius r int dr=0; if (number > 0) { dr = r/number; for (int k=0; k