HUMANITY @2024
“HUMANITY” stands as an innovative digital art endeavor seamlessly blending ludic aesthetics with the power of generative coding. This project delivers a dynamic and visually striking representation of diverse countries, showcasing the convergence of creativity and technology. At its core, the project utilizes a dynamic vector field to guide drawing agents across the canvas, creating an ever-evolving tapestry of vibrant lines and colors.
Formally, the artwork takes shape as a playful competition among drawing agents, each embodying a specific country. These agents traverse the canvas, crafting intricate patterns influenced by Perlin noise and random components. The incorporation of dynamic stroke weights and color gradients adds depth and complexity to the visual narrative, resulting in an engaging and ever-changing aesthetic experience.
Conceptually, “HUMANITY” delves into the playful side of aesthetics, transforming geographical data into an interactive and entertaining spectacle. The ludic element invites viewers to witness a friendly competition between nations, where the length and vibrancy of drawn lines become a visual representation of each country’s uniqueness.
From a technical standpoint, the project harnesses the capabilities of p5.js, a JavaScript library designed for creative coding. Integrating real-world country data through an API, the project not only showcases artistic prowess but also enhances the educational aspect by offering insights into the featured nations. The inclusion of country flags and information immerses viewers in a captivating visual journey that extends beyond artistic expression.
In summary, “HUMANITY” transcends traditional boundaries by seamlessly blending the realms of art and technology. Through its dynamic and playful approach, the project invites audiences to engage with geographical data in a novel way, fostering a deeper connection between aesthetics, interactivity, and the exploration of diverse cultures, all under the umbrella of Generative Coding Art.
The technical evolution of the “HUMANITY” project epitomizes a seamless blend of Generative Coding Art techniques and the integration of real-world data, resulting in a visually dynamic and interactive digital art experience. Explore key technical facets that propel the project’s advancement:
Generative Coding with p5.js: “Utilizing the p5.js library, a dynamic JavaScript toolkit for Generative Coding Art, the project serves as a canvas for expressive and interactive graphics. Creative coding techniques come to life, generating a vibrant array of lines, shapes, and colors, showcasing code’s potential as a medium for artistic expression.”
Ludic Aesthetics and Vector Field Dynamics: “The movement of drawing agents is guided by a sophisticated vector field, introducing order and direction to the generative process. Infused with Perlin noise and random components, the vector field adds an element of unpredictability and complexity to the visual output.”
Interactive Geovisualization with Dynamic Stroke Weights: “Real-world country data, including population and area, dynamically influences the stroke weights of lines, creating a visually engaging composition. This integration emphasizes the aesthetic diversity of the artwork, showcasing the impact of geographical data on visual outcomes.”
p5.js Exhibition and Real-World Data Integration: “By fetching real-world country data from a countries API, the project seamlessly integrates external data sources into the Generative Coding Art process. Country properties such as population, area, and name directly influence the visual representation of each drawing agent, establishing a tangible connection to geographical information.”
Cultural Diversity Art with Interactive Educational Elements: “Incorporating country flags and information enhances the interactive and educational aspects of the piece, providing viewers with insights into each represented country. The project transforms raw geographical data into an abstract, visually captivating experience while offering educational value.”
Noise Effects, Gradient Strokes, and Interactive Features: “Noise functions add texture and variability to visual elements, contributing to the overall aesthetic richness. Gradient strokes dynamically change based on the position of drawing agents, creating visually appealing transitions between colors. Interactive features, such as drawing agent competitions, invite viewers to engage with the artwork playfully.”
“The ongoing technical progress of ‘HUMANITY’ showcases the versatility of Generative Coding Art, demonstrating its power in transforming data into a visually immersive and conceptually engaging digital art experience.”
This poster is generated using all the world’s countries. Each country has a specific color, area, and population, contributing to the final art generation with 100 – 10000 frames.
Press the button to see the code in action
Loop Control:
The draw()
loop is interrupted after a specific number of frames (frameMain
). This approach prevents the program from running indefinitely, controlling the total generation time.
Continuous Generation: After completing a drawing cycle, the program is reset to generate a new composition. This means that art is generated continuously, creating a sequence of unique images.
Image Storage: At the end of each cycle, the resulting image is saved on the computer. Each image is unique since a random number is assigned as part of the file name, avoiding repetitions.
Infinite Art and Uniqueness: The continuous execution of the program ensures that art is generated infinitely. The assignment of a unique random number to each image file name ensures that no file name is repeated, contributing to the uniqueness of each composition.
Keep the p5.js window running indefinitely, generating unique posters continuously. At the end of each loop, save the image on the computer.
When the ‘N’ key is pressed, the applyNoiseEffect()
function is triggered. This function adds a grainy noise effect to the entire canvas. Here’s a step-by-step explanation:
- Create an Off-screen Buffer:
- A new off-screen buffer is created with the same dimensions as the main canvas (3500 x 5000 pixels).
- Set Background to Black:
- The background of the off-screen buffer is set to black.
- Iterate Through Pixels:
- The function loops through each pixel in the canvas.
- Add Noise to Brightness:
- For each pixel, a random value between -10 and 10 is added to its brightness. This randomness creates a noisy effect.
- Set Pixel Colors in Buffer:
- The modified brightness values are assigned as the red, green, and blue components of the pixel color in the off-screen buffer.
- Draw Buffer onto Main Canvas:
- The buffer, now containing the noisy effect, is drawn onto the main canvas at the center.
In summary, pressing ‘N’ introduces a visual noise effect by randomly adjusting the brightness of each pixel in the canvas, creating a textured and dynamic appearance.
Noise in “HUMANITY” Art Project:
Role of Noise:
- Unpredictability: Perlin noise introduces randomness to agent movements, ensuring each path is unique.
- Visual Complexity: Noise creates intricate patterns, adding depth and complexity to the artwork.
Implementation:
- Time-Dependent Noise:
timeOffsetX
andtimeOffsetY
evolve noise over time, contributing to dynamic lines. - Vector Field and Randomness: Noise guides vector field angles, while random components enhance unpredictability.
- Gradient Stroke and Color: Noise interpolates colors, resulting in a harmonious and evolving color palette.
Data + API
In the provided code, there’s an example of using an API to fetch information about countries. Let me break down the relevant parts:
API Request:
- The
fetch
function is used to make a network request to the given URL, which is an API endpoint that provides information about all countries. - The response from the API is initially in a raw format. The
.json()
method is called on the response to parse it as JSON. - The data is then processed in the
.then
block, where you can perform operations on the received data. - If there is any error during the request, it’s caught in the
.catch
block and an error message is logged.
fetch("https://restcountries.com/v2/all") .then((response) => response.json()) .then((data) => { // Process data here }) .catch((error) => console.error("Error fetching country data:", error));
Processing Data:
- The data received from the API contains information about all countries. In this example, it’s assumed that
data
is an array of country objects. - The array
allCountries
is populated with all the country objects, andremainingCountries
is initialized with the same data. nAgents
number of random countries are selected fromremainingCountries
without repetition, and these selected countries are pushed into theselectedCountries
array.- Agents are then initialized using the
Agent
class with random positions and the selected countries.
.then((data) => { // Store all countries in the allCountries array allCountries = [...data]; remainingCountries = [...data]; // Initialize remainingCountries // Select nAgents random countries without repetition for (let i = 0; i < nAgents; i++) { const randomIndex = Math.floor(Math.random() * remainingCountries.length); const selectedCountry = remainingCountries.splice(randomIndex, 1)[0]; selectedCountries.push(selectedCountry); } // Log the selected countries console.log("Selected Countries:", selectedCountries); // Initialize agents after fetching country data for (let i = 0; i < nAgents; i++) { agents.push(new Agent(random(width), random(height), [selectedCountries[i]])); } longestLineAgent = agents[0]; })
Agent Class Initialization:
- The
Agent
class is used to create instances (agents) that will be responsible for drawing lines on the canvas. - Each agent is initialized with a random position and an array containing one of the selected countries.
- The
Agent
class constructor takes care of loading the flag image of the starting country and other initializations.
for (let i = 0; i < nAgents; i++) { agents.push(new Agent(random(width), random(height), [selectedCountries[i]])); }
In summary, the code demonstrates how to use an API to fetch country information, process that data, and use it to initialize drawing agents on the canvas. The fetched data is then used creatively in the drawing process based on the logic implemented in the Agent
class.
The “Winner Determination”
Initialization:
- The
longestLineAgent
variable is declared at the beginning to keep track of the agent with the longest drawn line. It is initially set toagents[0]
(the first agent in the array).
let longestLineAgent;
Update During Drawing:
- As the
draw
function is continuously called, the agents move across the canvas, leaving trails. The length of each agent’s drawn line is continuously updated.
this.drawnLineLength += dist(this.pOld.x, this.pOld.y, this.p.x, this.p.y);
Winner Determination:
- After a certain number of frames (
frameMain
), the code checks for the agent with the longest drawn line. This is done by comparing thedrawnLineLength
property of each agent.
longestLineAgent = agents.reduce((a, b) => a.drawnLineLength > b.drawnLineLength ? a : b );
Display Winner Information:
- The winner’s information is then stored in the
winnerInfo
object, including the country name, area, capital, population, and latitude/longitude.
winnerInfo = {
name: longestLineAgent.selectedCountry.name,
area: longestLineAgent.selectedCountry.area,
capital: longestLineAgent.selectedCountry.capital,
population: longestLineAgent.selectedCountry.population,
latlng: longestLineAgent.selectedCountry.latlng, };
Display Winner Information in the End:
- The winner’s information can be displayed towards the end of the animation.
if (frameCount > frameMain - 2) {
if (longestLineAgent) {
longestLineAgent.displayWinnerInfo(); } }
Process in the provided code is based on the length of the lines drawn by the drawing agents (represented by instances of the “Agent” class). The agent with the longest drawn line is considered the “winner.” Here’s how it works:
In summary, the “Winner Determination” process involves monitoring the length of the lines drawn by each agent and identifying the agent with the longest line as the winner. The winner’s information is then stored and can be used for display or further processing.
Culture + Code
In terms of culture, the code integrates information about various countries, highlighting their diversity and uniqueness. The selection of countries and the use of their characteristics to influence the artwork reflect a celebration of global unity and collaboration. The visual representation of these countries, their flags, and associated information transforms cultural diversity into a form of artistic expression.
The intention behind the code seems to align with the idea that true power and beauty emerge not from individual nations but from the collective unity of diverse cultures. By bringing together elements from different parts of the world, the code transforms cultural richness into a captivating piece of digital art. This fusion of cultures in the code serves as a metaphor for the idea that collaboration and unity among nations can lead to the creation of something truly extraordinary and aesthetically pleasing, much like the visual output of the code itself.
The overarching theme of the project, “HUMANITY by Vadym Alyekseyenko,” suggests a focus on the shared human experience and the potential for collaboration and creativity to transcend borders. The integration of country-specific data in the artistic process conveys a message of interconnectedness and the beauty that emerges when diverse elements come together harmoniously.
Work in Progress:
It was a project with many experiments. Here are some examples of the work process and some interesting results.