Nature of Code: Midterm Project
Stargazer by Katie Pellegrino
Introduction:
The goal of my project was to explore creating a visually pleasing and interactive night sky display. Living in the middle of such a large city, it’s sometimes hard to find stars in the night sky, yet, I think they’re one of the most beautiful things to gaze upon. Additionally, I think there’s a lot of power in the stories and oral history that people save within constellations. Therefore, I thought it would be cool to create a project that allows the user to draw their own constellations and also enjoy a visual display of an array of constantly redrawing constellations across a night sky.
Inspiration:
In researching constellation/star projects, I was inspired mainly by two similar projects. The first is by Akshay L. Aradhya which I especially love for how it maps a peaceful and rather dream-like night-sky visual. The mouse interaction that scatters the stars and the way they continuously redraw new constellations and star connections is beautiful and pleasing.
The second is a project by Diego Garcia. Similarly, it draws connections between stars based on their distance from each other. However, it allows the user to place the points, which afterwards, continuously are mutually attracted to each other using gravitational attraction. I really like how the user can initially place the points within the sketch.
General Mechanics / Assets:
My commented code can be found here for a contextual explanation.
Overall, my code is organized using various functions within the main sketch along with a ‘Star’ class for determining the star movement and procedure.
The main general mechanics is the star movement and oscillation. The oscillation is created with a simple adjustment to their radius as determined by a sinValue. When each star is created I assign them a random frequency which is multiplied by the frameCount, therefore, each star ‘sparkles’ at a different rate. Additionally, the stars are programmed to float around the screen with random acceleration between -0.5 and 0.5. There’s no gravity or attraction in their floating movement to create a sense of them drifting through space.
Initial Constellation State (static):
When the program first starts, it is in the static state which allows the user to draw a constellation by clicking on the screen. Every time this state is initiated, a ‘star’ array is emptied and each time the user clicks on the screen a new star point is drawn and added to the array. Additionally, each star point is connected through a connectConstellation function. Essentially, it filters through each star in the array and compares it to the one next to it and draws a line between the two.
Stargazing State (dynamic):
When the stargazing state is initiated (when the user presses ‘enter’ while in the static state), the stars saved in the temporary ‘star’ array are pushed to a constellation array. Basically, this array stores each constellation as an array of stars so that when the user returns to the static state, the constellations can be redrawn.
Additionally, the stars are given an initial random acceleration to disperse them. I see a parallel between drawing a constellation in the sky and sending it out to the universe to live. At this point, the stars drift on their own, however, whenever they are within 100 pixels of another star they draw a line. Thus, each star that the user adds to the screen then can explore and ‘mingle’ with other stars on the screen in an ever changing connection.
This operation, in theory, was quite simple. Just use a nested for loop to compare each star to each other star and, if they’re within a certain distance of the other, draw a line. However, while this works with a few stars on the screen, once there are a large number of stars on the screen, the complexity is too huge and the program is nearly unreadable because it is so slow.
To avoid this, I employed a regions structure which essentially creates a multidimensional array that grids the screen into 100×100 squares. For each frame of code, this array is reset and each star checks its location and is placed within a section of the array.
Therefore, when the star is checking the stars around it to see whether it should draw a line, the for loop only references the stars within each individual star’s region and the regions surrounding it.
While this process seems more complicated in the code as the regions array is updated and changing in every frame, it significantly lowers the complexity of code because the star is only concerned with stars that are within relative distance to it.
Additionally, in this mode the stars repel the mouse position. To avoid the stars accelerating too much, if their velocity is above a certain threshold, friction is applied.
Returning Constellation State (static):
When the sketch returns to the static mode (when ‘space’ is pressed while in the dynamic mode), the stars are attracted to their original location (stored in each object). Additionally, the sketch checks for when the star’s current position is within 2 pixels of its original location and, if this is true and is true for the star next to it within its array, a line is drawn between them. Thus, each constellation is gradually redrawn.
Additionally, the temporary ‘star’ array from the start is reset so the user can draw another constellation that remains separate from the others. Again, once the user returns to dynamic mode, this array is pushed to the constellations array and saved as a new constellation.
Finally, as a final touch, I added some background music to set the tone. It took some browsing to find the correct feel, but my goal was celestial, mystical, mysterious, and fulfilling. Additionally, I added a swoosh sound effect to add emphasis for when the constellations are dispersed into the sky during the transition from static to dynamic mode along with a twinkling sound for when the stars regather from dynamic mode to static mode. Also, I added a bell ding for when each star is initially drawn/placed on the screen. All of the audio was downloaded from Zapsplat with normal usage license. Unfortunately, some of the sounds weren’t exactly as I’d envisioned them, however, I think they managed for the sketch.
Debug Mode:
My debugMode for the sketch is rather simple. It allows the user to adjust the parameters for drawing a star. The ‘grow’ adjusts the frequency of the star’s pulse while the ‘amp’ adjusts how much the star fluctuates. These are most effective in static mode, however, an issue that arises is that whenever the user adjusts the parameters, they must click on the screen and, thus, draw an unintentional star.
However, while debug mode needs a little adjustment to function smoothly in static mode, in dynamic mode the user can adjust ‘regDist’ which changes the range of the regions. Thus, the bigger the number, the farther the star’s reach and the more other stars it will connect to. This is a simple adjustment, but can dramatically change the feel of dynamic mode.
Finally, when the user enters debug mode, it reveals the outline of the stars which better clarifies their rate and size of oscillation. Something I’d like to add in the future is a line that shows each stars acceleration within dynamic mode, however, for now the debug mode is quite straight forward.
Challenges:
The biggest challenges that I faced in this project was organizing the regions data structure and, overall, conceptualizing which code should be organized as a method within the class and which should be a function within the main sketch. Overcoming these challenges is explained in greater detail above, but, overall, through this project I gained a much better understanding and appreciation for the possibilities of code both in terms of logic, complexity, and clarity.
Improvements:
Among the many improvements I’d like to make with this project, I think the most significant are dealing with the audio and the interface. A feedback advise that I got from our presentation was to add modulation to the ding associated with placing the stars. I’d like to do this because currently the clink is rather bland and just slight modulation might add some more ‘spark’ to the stars. Additionally, currently the ‘twinkle’ effect associated with the stars returning to their initial constellation isn’t connected to the length of time that it takes for the stars to return home. So I think it’d be cleaner if it was related somehow.
Additionally, in terms of the interface, I’d like to somehow make it more user friendly. As of right now, you click to add stars, press enter to save the constellation and switch to dynamic mode, then press space to switch back to static mode. However, while these controls are pretty straight forward, there’s nothing explaining them. I’d like to make it more user-friendly, but also don’t want to lose the clean full screen display aspect of the presentation. So figuring out the best of both worlds would be ideal.
Finally, another suggestion that I received during the presentation was to allow the user to determine how big a star might be based on how long they click to place it. I really like this because it gives the user more control over the stars they create and allows them to better personalize the night sky.
Concepts / Explorations:
For this project, I explored a lot with using states or modes that dictate when the objects should react in a certain way. Additionally, using multidimensional arrays was essential both for organizing the screen into regions and in saving the constellations. Finally, I became much more comfortable with applying force and manipulating objects through oscillation.
Final Remarks:
Overall, this project was super interesting to complete and I feel like it accomplished the mood that I set out to create. I had a lot of help on this project to which I am extremely thankful and learned a lot through the process. While there are certainly a variety of improvements and ways of further expanding this project, I’m very satisfied with the outcome and am all the more amazed by the possibilities of coding animations.