The Finished Product
What Is My Project?
My project, the “circle of constants”, is a 3D print of 100 circles, where each circle corresponds to a digit of pi, which determines its height. For example, the first, inner circle has a height of 3, the second, a height of 1, and so on. I view it as a cool way to see what pi really looks like. There were a lot of difficulties with my project, but overall, I’m very happy with how it came out.
The original idea for my project came from something I did last year in Intro. The project involved constructing a few hundred circles, with each radius increasing by 1 each iteration, starting at 1. The radius of any given circle would correspond to a digit of pi, which would return a color. For example, the first circle has radius 1, so the color would correspond to whichever color I set 3 to have, since 3 is the first digit of pi. I thought the end result looked really nice, and was interesting way to portray pi.
To make it different I decided to do a reiteration of the pi project, except as a 3D printed model. In this project, however, each digit of pi returns a height instead of a color. So imagine that in the previous picture, instead of each circle having a color, they instead have a height directed out of the screen. It’s difficult to imagine, so I’ll walk through the process.
To Make Circles
In order to make a 3D print of the project, I used a program called “MadeUp”. This involved learning an entirely new language, which was incredibly difficult at first, but with help, I was able to figure it out. The program consists of three functions, each with their own job. The first function I want to talk about is called “makeCircles”, as this is the syntax for function in MadeUp. The code for the function is given below, with sections I borrowed from Mr. Anderson labeled as ¨borrowed.¨
to makeCircles --in java, this would be something along the lines of ¨void makeCircles¨ while i <= 100 --¨make 100 circles¨ b = (calculateHeight n) --This variable is going to be the height, so it must get the height value from pi x2 = x + s --This just defines the second x point of the triangle. --Its the first xpos + width of triangle. --borrowed moveto x,0,0 moveto x2,0,0 moveto x2,b,0 moveto x,0,0 --These above lines just make the triangle. Starting at an original --xposition, then that x position + the width, then the x position + width, --with a height of that digit of pi, then back to the original x position. if i < 75 nsides = 30 end if i >= 75 nsides = 60 end --I threw the above if statements in because when printed, the last 25 --circles are obviously imperfect circles, so I increased --the number of sides revolve 0,1,0,360 --¨revolve the triangles around the y axis, 360 degrees.¨ --end borrowed x = x + s + s2 --The next x position is the previous one --plus the width of the triangle, plus the distance between --each triangle n = n + 1 --This gets the next digit of pi if i == 100 r = x end --The above just means ¨if this is the last time --through the loop, set the radius of the giantCircle equal to --the radius of the last. It will get larger later. i = i + 1 --¨Increase the number of iterations by 1¨ end end
Basically, the function starts at some point on the x axis, then moves along the x axis to a new point, asks a different function, the getHeight method, for a y value, then moves back to the original point it started at, making a triangle. It repeats this process 100 times, moving further along the x axis for every digit of pi. I’ll explain the getHeight function later, so if it seems confusing, just think of it as a function that returns a digit of pi, which is then set as the height for one of the triangles. Before the revolution, this is what it looks like.
You can see that the height of these triangles corresponds to digits of pi. The first triangle all the way to the left is at a height of 3, the next at 1, after that is 4, just slightly higher than the first, and so on. The triangles with height 9 are fairly easy to spot, as they are the tallest. This was originally a bigger problem, but by spacing each triangle a few units from each other before the revolution, and switching from rectangles to triangles, it was fixed. After revolving, we get the (nearly) finished product.
The white bands were an indication that light was shining in between each revolved triangle, which meant that the whole structure had no bottom connecting each piece. To fix this, I made a new function, “makeGiantCircle.”
This function wasn’t easy to code either, but was of lower maintenance than the other functions. The code does exactly what it sounds like; it makes a giant circle. The circle serves as a bottom, so when the project is 3D printed, it can actually be held. Here’s the code.
to makeGiantCircle r = r*((pi/e)^2) --the line above just takes --the 100th circles radius, and --multiplies it by (pi/e)^2. while theta < 360 x = r * cos(theta) --this provides the x coordinates in polar form z = r * sin(theta) --this provides the z coordinates in polar form moveto x,0,z -- theta = theta + 360/60 --this sets the number of points around the --"circle" end extrude 0,-1,0,(pi^e) --"extrude around the negative y axis --pi^e units¨ end
It starts by taking the radius from the 100th circle, multiplying it by a constant so it is larger, then uses that new radius to make a circle through polar coordinates. Polar coordinates make the circle by moving to certain points along a circle-like path, then connecting them. It uses an angle, then multiplies the radius by the cosine or sine of the angle to get an x or y position, respectively. Then the angle increases, and the process is repeated. The number of sides of the ¨circle¨ is just 360/theta, since an actual circle would have an infinite number of sides. Again, the only point of this circle is to enable the print to be all one piece.
The last one I want to talk about is the calculateHeight method, which I’ve referenced many times before. This is the most important part of the program, but was the hardest to actually code. The whole process this function uses is very cyclical, and there was most likely an easier way to do it, but it works. It basically looks at the ¨nth digit of pi¨ using an index of the variable alpha, which is just pi as a string, and then runs through a few ¨if¨ statements to return a height. The biggest problem I had coding this method involved two errors that would prevent it from returning a height, which is the whole point of the method. My friend Karl helped me out a lot, as he is much better at programming than I am, and is going to be majoring in computer science at Northeastern next year. The finished code is given below, with the section Karl helped out on labeled.
The first problem was so incredibly obvious, and took the two of us an embarrassing amount of time to figure out. On the first line of each separate if statement, where it says ¨if alpha[n] == ¨digit¨, I didn’t have the digit in quotation marks, so the digit was being read as an integer, rather than a string. This was a problem because alpha is a string composed of other strings, and strings cannot equal integers, as they are different data types. OK, maybe it wasn’t obvious.
--Karl helped a lot to calculateHeight n if alpha[n] == "0" --"if the nth digit of pi is zero, h = 0 --set the height to zero" end if alpha[n] == "1" --"if the nth digit of pi is one, h = 1 --set the height to one" end if alpha[n] == "2" --"if the nth digit of pi is two, h = 2 --set the height to two" end if alpha[n] == "3" --"if the nth digit of pi is three, h = 3 --set the height to three" end if alpha[n] == "4" --"if the nth digit of pi is four, h = 4 --set the height to four" end if alpha[n] == "5" --"if the nth digit of pi is five, h = 5 --set the height to five" end if alpha[n] == "6" --"if the nth digit of pi is six, h = 6 --set the height to six" end if alpha[n] == "7" --"if the nth digit of pi is seven, h = 7 --set the height to seven" end if alpha[n] == "8" --"if the nth digit of pi is eight, h = 8 --set the height to eight" end if alpha[n] == "9" --"if the nth digit of pi is nine, h = 9 --set the height to nine" end h *(e^(pi)) -- whatever h is, multiply it by e^pi -- because why not? end --end Karl help
The second problem was the bigger of the two. There are no explicit return statements in Madeup, unlike Java which the two of us were way more familiar with. This resulted in Karl and I spending an hour trying to get the “h” values to return. We finally figured out that the last line in a function is the return statement. This was stated in the documentation for MadeUp, but was still confusing to learn. I learned a lot about debugging during this hour though, which made it totally worth it.
What I Would Do With More Time
I actually ¨finished¨ this project relatively early, but I kept making improvements to it, before and after the test print shown above. The spacing between each triangle, the width of each triangle, and the height were all altered many times before finding the right dimensions. I was continuing this process for a while, but eventually ran out of time. The last improvement I would’ve made involved switching from triangles to a single line. Imagine that instead of triangles with a height matching the digits of pi, there is a line that connects the heights, then is revolved around the y axis, like the triangles were. This may have made it easier to see each layer, which was an obvious problem after the test print. I worked on it for a while, but eventually ditched the idea due to time. The spacing between each triangle eventually fixed that problem though, and I am very happy with the final product.