dam it!

This project is inspired by the tensions between dams, the environment, and people displaced or otherwise affected by dams.

In this animation, you become the dam builder. By pressing the mouse anywhere on the canvas, a dam emerges in the river, affecting the water level, marine life (fish and plants), and nearby communities (houses). Moving the mouse from left to right raises the dam and increases its impact, killing fish and making houses disappear. Pressing the space bar replenishes the fish population. Clicking the mouse advances to different facts about dams, stored in an array. These facts are adapted from research summarized by Earth Law Center and HuffPost.

sketch
/* jaden luscher
jluscher
section a
dammit(!): an educational animation */

var waterlevel1; // water level left of dam (upstream)
var waterlevel2; // water level right of dam (downstream)
var damX = 100;	// x location of dam

var fish = [];
var numFish = 40;

var house = []; // original array of houses
var newhouseProbability = 0.03; // likelihood of a new house popping up

var plants = [];
var plantNum = 100;

var sceneNum = 0;   // main reference for changing objects
var factNum = 0;    // determines index of damFacts array
var damFacts = ['what a beautiful ecosystem... click to screw it up!',
    'great. you built a dam. the river’s flow is restricted. click to learn more.',
    'the united states has over 9,000 dams...',
    '...many are not equipped to handle the amount of water that could result from climate change.',
    'pennsylvania has 145 high hazard dams in poor or unsatisfactory condition.',
    'dams have fragmented two thirds of the worlds large rivers...',
    '...and have flooded a land area the size of california.',
    'their reservoirs contain three times as much water as all the world’s rivers, and speed up evaporation.',
    'dams disrupt fish and bird migration, both physically and chemically...',
    '...and habitat loss is the leading cause of extinction.',
    'upstream: nutrients trapped in reservoirs can cause toxic algae blooms.',
    'downstream: ecosystems suffer from a lack of sedimentation and nutrients.',
    'less nutrients = less vegetation = more erosion',
    'river deltas are deprived of the silt they need to defend against damage from the ocean.',
    'removing damaged and aging dams protects the surrounding population from disaster...',
    '...and allows the rivers to restore their natural and biological integrity.',
    'but often what happens instead is...'
    ];

function setup() {
    createCanvas(480, 360);
	noStroke();
	frameRate(20);
    angleMode(DEGREES);
    textFont("monospace");
    textSize(12);
    if (sceneNum == 0) {
        waterlevel1 = 240;
        waterlevel2 = 240;
    }
    for(var i = 0; i < numFish; i++) {
        var newFish = makeFish();
        fish.push(newFish);
    }
    // first house
    for(var i = 0; i < 10; i++) {
        var firstHouses = makehouse(random(width), 180);
        house.push(firstHouses);
    }
    for (var i = 0; i < plantNum; i++) {
        var newPlant = makePlant();
        plants.push(newPlant);
    }
}

function draw() {
    drawSky();
    if (sceneNum > 0) {     // only occurs once mouse has been pressed
        sceneNum = constrain(floor(map(mouseX, width/2, width, 1, 12)), 1, 12);
        waterlevel1 = 240 - sceneNum * 6;
        waterlevel2 = 240 + sceneNum * 9;
    }
    drawMountain(0, 0.02, 0.00004, 50, 220);   // background mountains    
    drawMountain(1, 0.01, 0.00007, 50, 220);   // midground mountains
    drawMountainAndHouses(0.005, 0.0001, 40, 220); // foreground mountains and houses

    for (var i = 0; i < house.length; i++) {
        house[i].move();
        house[i].show();  
    }
    var keepHouses = []; // stores houses in range
    // keep houses still in range 
    if (house.length > 0) {
        for (var i = 0; i < house.length; i++) {
            if (house[i].houseExists & house[i].x + house[i].w > 0) {
                keepHouses.push(house[i]);
            }
        }
    }
    house = keepHouses; // thank you Chuong!
    water();
    push();
    for (var i = 0; i < plantNum; i++) {
        if (plants[i].plantExists) {
            plants[i].show();
            translate(width / plantNum, 0);
        }
    }
    pop();
    // draw fish
    for (var i = 0; i < numFish; i++) {
        if (fish[i].fishExists) {
            fish[i].move();                
            fish[i].show();
        }
    }
    makeDam();
    spitfacts(factNum);
    if(factNum > damFacts.length - 1) {
        gameOver();
    }
}

function mousePressed() {
    sceneNum = 1;
    factNum ++;
}

function keyPressed() {
    if(key == ' ') {
        sceneNum = 0;
        waterlevel1 = 240;
        waterlevel2 = 240;
        fish = [];  // clear fish array
        for(var i = 0; i < numFish; i++) {
            var newFish = makeFish();
            fish.push(newFish);
        }
    }
}

function gameOver() {
    background("orange");
    fill(255);
    textSize(32);
    text('DAMMIT!', 170, 180);
    textSize(14);
    textAlign(CENTER);
    text('(YOU KILLED ALL THE FISH AND HAVE CAUSED SEVERE DAMAGE TO THE ECOSYSTEM)',
            40, 250, 400)
    noLoop();
}

function drawSky() {
    background("orange");
    push();
    fill("yellow");
    translate(400, 80);
    scale(map(mouseY, 0, height, 0.5, 1));
    ellipse(0, 0, 50, 50);
    pop();
}

function spitfacts(f) {
    push();
    fill(255);
    text(damFacts[f], 30, 30, 220, 80);
    pop();
}

function drawMountain(mc, a, speed, high, low) {
    noStroke();
    if(mc == 0) fill(240, 150, 120);    // background mountain color
    if(mc == 1) fill(220, 130, 100);    // midground mountain color
    if(mc == 2) fill(20, 50, 180);      // water color
    beginShape();
    vertex(width, height);
    vertex(0, height);
    for(var i = 0; i < width + 1; i ++){
        var x = (i * a) + (millis() * speed);
        var y = map(noise(x + mc*1000), 0, 1, high, low); 
        // x + mx*100 ensures mountains look different
        vertex(i, y);
    }
    endShape();
}

function drawMountainAndHouses(a, speed, high, low) {
    noStroke();
    fill(200, 100, 60);     // foreground mountain color
    beginShape();
    vertex(width, height);
    vertex(0, height);
    for(var i = 0; i < width + 1; i ++){
        var x = (i * a) + (millis() * speed);
        var y = map(noise(x), 0, 1, high, low); 
        vertex(i, y);
    }
    endShape();

    if (newhouseProbability > random(1.0)) {  
        // make new house randomly
        var newhouse = makehouse(width + 1, y);
        house.push(newhouse);
    }
}

function makehouse(px, py) {
    var newhouse = {x : px,
                y : random(220, py),
                w : random(10, 30),
                h : random(10, 30),
                rh : random(3, 15),
                c : color(random(100, 255), random(100), 0),
                dx : -1,
                houseExists: true,
                move : movehouse,
                show : showhouse}
    return newhouse;
}

function showhouse() {  // house x, y, width, height, roof height
    push();
    fill(this.c);
    rect(this.x, this.y, this.w, this.h);
    beginShape();
    vertex(this.x - 2, this.y);
    vertex(this.x + (this.w/2), this.y - this.rh); // roof peak
    vertex(this.x + this.w + 2, this.y);
    endShape();
    fill(230, 180, 120);
    rect(this.x + this.w / 2 - 4, this.y + this.h, this.w / 4, -this.h / 2); // door
    pop();
}

function movehouse() {
    this.x += this.dx;
    if(this.y + this.h > waterlevel1) {
        this.houseExists = false;
    }
}

function makePlant() {
    var plant = {x: 0,
                y: 0,
                c: color(random(50), random(100, 200), random(100)),
                n: floor(random(3, 6)),
                len: random(-5, -40),
                plantExists: true,
                show: showPlant,
    }
    return plant;
}

function showPlant() {
    push();
    translate(0, height + 10 + sceneNum * 3);
    rotate(15 / this.n)
    stroke(this.c);
    strokeWeight(6/this.n);
    for (var i = 0; i < this.n; i++) {
        line(0, 0, 0, this.len + random(-1, 1));
        rotate(-30 / this.n);
    }
    pop();
}

function makeFish() {
        var newFish = {x: random(0, width), 
                y: random(waterlevel1 + 10, height-20),
                w: int(random(10, 25)), h: int(random(5, 10)),
                dx: random(-3, 3), 
                c: color(random(100, 255), random(100), random(100)),
                fishExists: true,
                fishDead: false,
                show: showFish,
                move: moveFish,
                }
        return newFish;
}

function moveFish() {
    this.x += this.dx;
    if (sceneNum == 0) {
        // with no dam, fish change directions (off canvas)
        if(this.x > width + 20 || this.x < -20) {
            this.dx = -this.dx;
        }
    } else {
        // if fish is to the left of dam, disappears
        if(this.x < damX + 30) {
            this.fishExists = false;
        } // if fish is above water, dies
        else if(this.y < waterlevel2 + 5) {
            this.fishDead = true;
        }
        // if fish hits dam or goes off screen, change direction
        if(this.x > width + 20 || this.x <= damX + 33) {
            this.dx = -this.dx;
        }
    }
}

function showFish() {
    fill(this.c);
    ellipse(this.x, this.y, this.w, this.h);
    if(this.dx < 0) {  // facing left
        if(this.fishDead) {
            // if fish is dead, eyes make it appear belly-up
            fishEye(this.x - 3, this.y + 3, this.w / 4);
        } else {
            fishEye(this.x - 3, this.y - 3, this.w / 4, true);
        }
        triangle(this.x + this.w/3, this.y, 
                    this.x+this.w, this.y-5, 
                    this.x+this.w, this.y+5);
    } else {  // facing right
        if(this.fishDead) {
            // if fish is dead, eyes make it appear belly-up
            fishEye(this.x + 3, this.y + 3, this.w / 4);
        } else {
            fishEye(this.x + 3, this.y - 3, this.w / 4, true);           
        }
        triangle(this.x - this.w/3,this.y, 
                this.x-this.w, this.y-5, 
                this.x-this.w, this.y+5);
    }
    // if fish is dead, stay floating at water level
    if(this.fishDead) {
        this.y = waterlevel2;
        this.dx = 0;
    }
}

function fishEye(x, y, sz, alive) {
    push();
    fill(255);
    ellipse(x, y, sz, sz);
    if (alive) {
        fill(0);
        ellipse(x, y, 2, 2);
    }
    pop();
}

function water() {
    if(sceneNum == 0) { // initial river ripples using mountain function
        drawMountain(2, 0.005, 0.0005, waterlevel1+10, waterlevel1-10);
    }
    push();
    // water line shows gradient of water loss
    for(var i = 0; i < sceneNum; i++) {
        var alph = 10;     // alpha
        fill(0, alph);    // waterline
        rect(0, 240, width, height -240);
        alph += 3;
        translate(0, 10);
    }
    pop();
	fill(20, 50 + sceneNum * 6, 180 - sceneNum * 6);     // blue water
	if (sceneNum == 0) {
		rect(0, waterlevel1, width, height - waterlevel1);
	} else {
        if (factNum > 9) {   // fact 10 is about algae blooms
            fill(20, 100, 50);
        }
		// water left of dam
		rect(0, waterlevel1, damX, height - waterlevel1);
		// water right of dam
		rect(damX, waterlevel2, width - damX, height - waterlevel2);
	} 
}

function makeDam() {
	fill(180, 180, 150);
	if (sceneNum > 0) {
		beginShape();
		vertex(damX - 10, waterlevel1 - 20);
		vertex(damX + 5, waterlevel1 - 20);
		vertex(damX + 30, height);
		vertex(damX - 10, height);
		endShape();
	}
}

Mimi Ọnụọha – privacy and data

Us, Aggregated (2017)

Mimi Ọnụọha is a visual artist whose work critiques how tech companies’ unprecedented access to data has shaped the information we often blindly accept as complete and holistic. In Us, Aggregated, Ọnụọha takes her own family photos and reverse image-searches them, then compiles the resulting photos into a gallery. While we see image searches so commonly when even just looking through similar google images, Ọnụọha brings attention to the differences between the images and the diversity of people lumped together by an AI algorithm. She explores the power imbalances perpetuated by technology and seeks to de-normalize the “projected realities” we have been conditioned to perceive as natural. 

The Library of Missing Datasets (2016)

The Library of Missing Datasets is a physical repository (both in a file cabinet and on GitHub) that calls attention to the things we do not have quantified, but perhaps should in a world where so much is collected. Ọnụọha calls our attention to issues of the privacy of our information as well as the privacy of data that has either been not collected or intentionally hidden from the public.

gondola moment

sketch
// jaden luscher
// jluscher@andrew.cmu.edu
// section a
// project 11

// this program draws a gondola ascending a mountain
// populated by random cabins on a snowy slope

var hillheight = [];
var noiseParam = 0;
var noiseStep = 0.01;
var gondola;
var house = [];   // array of houses
var newhouseProbability = 0.01; // likelihood of a new house popping up per frame

function preload() {
    gondola = loadImage("https://i.imgur.com/H4WC448.png");
    // gondola drawn in illustrator
}

function setup() {
    createCanvas(400, 400);
    frameRate(20);
    noStroke();

    // set up hill data
    for (i = 0; i <= width; i++) {
        var n = noise(noiseParam);
        var value = map(n, 0, 1, 50, 250);
        hillheight.push(value);
        noiseParam += noiseStep;
    }

    // first house
    var onehouse = makehouse();
    house.push(onehouse);
}


function draw() {
    background("orange");
    drawMoon();

    movehill();
    drawhill();
    drawslope();

    for (var i = 0; i < house.length; i++) {
        movehouse(house[i]);
        showhouse(house[i]);
    }
    if (house.length > 0 & house[0].y - house[0].rh > height) {
        // delete off-screen houses
        house.shift();
    }
    if (newhouseProbability > random(1.0)) {  // make new house randomly
        var newhouse = makehouse();
        house.push(newhouse);
    }

    push();
    stroke(100);
    strokeWeight(2);
    line(0, 260, width, 40);
    image(gondola, 170, 130, 100, 150);
    pop();
}


function showhouse(h) {  // house x, y, width, height, roof height
    push();
    fill(200, 150, 100);
    rect(h.x, h.y, h.w, h.h);
    beginShape();
    vertex(h.x - 2, h.y);
    vertex(h.x + (h.w/2), h.y - h.rh); // roof peak
    vertex(h.x + h.w + 2, h.y);
    endShape();
    fill(230, 180, 120);
    rect(h.x + h.w / 2 - 4, h.y + h.h, 8, -15); // door
    pop();
}

function movehouse(h) {
    h.x += h.dx;
    h.y += h.dy;
}


function makehouse() {
    var house = {x : width + 1,
                y : random(120, 300),
                w : random(15, 50),
                h : random(15, 50),
                rh : random(5, 20),
                dx : -1,
                dy : 0.55,
                show : showhouse}
    return house;
}


function movehill() {
    hillheight.shift();   // creates scrolling effect
    var n = noise(noiseParam);
    var value = map(n, 0, 1, 50, 250);
    hillheight.push(value);
    noiseParam += noiseStep;
}

// background hills
function drawhill() {
    push();
    fill("lightblue")
    beginShape();
    for (var i = 0; i < width +1; i++) {
        var x = i;
        vertex(x, hillheight[i]);
    }
    vertex(width, height);
    vertex(0, height);
    endShape(CLOSE);
    pop();
}

// foreground white slope
function drawslope() {
    push();
    fill(250);
    beginShape();
    vertex(width, height);
    vertex(0, height);
    vertex(0, 370);
    vertex(width, 150);
    endShape();
    pop();
}

function drawMoon() {
    fill(250);
    ellipse(100, 80, 50, 50);
    fill("orange");
    ellipse(105, 80, 45, 45);
}

Blog 11

in the reading “NFTs and Copyright”, Jonathan Bailey discusses problems surrounding the recent rise in NFT popularity, especially ones concerning copyrights. One of the main problems he brings up is the instance where artists had their designs and art pieces stolen and turned into NFT’s without their consent. Moreover, Bailey discusses ways NFT auction sites have been trying to combat this with a stricter verification and certification process that removes everything that does not pass. After discussing the problems surrounding NFT’s, Bailey moves on to the positive and much more intended side of NFT’s – its ability to help creators’ public exposure. NFT’s recent popularity helps people spot truly special or meaningful designs when tons of NFT’s are arrayed with each other. To finish, Bailey takes about the circumstances that surround NFT, discussing the unsureness of its future and the sustainability of the system as it gets more and more easily accessible.

Bailey, Jonathan. “NFTs and Copyright.” Plagiarism Today, 16 Mar. 2021, https://www.plagiarismtoday.com/2021/03/16/nfts-and-copyright/.

LookingOutwards-11 Societal Impacts of Digital Art

The article “Beeple’s digital ‘artwork’ sold for more than any painting by Titian or Raphael. But as art, it’s a great big zero.” by Sophie Davies address the society issue of digital divide, referring to the different between these who can reach the digital world of internet and these who cannot. Sophie argued that People who have no computer skills or a device to access the internet are more likely to receive social exclusion, as more and more people are online. The covid facilitate this process by transferring jobs and works online, and people who could access internet seem to be left behind by the times.

Sophie also discusses how women from certain countries and children from low social & economic status are more likely to not have a device for internet, which leads to an inequality problem. However, almost no solution is mentioned in the article. To me, the only solution in the article that “asking policy makers to help everyone get online for free” seems highly unlikely to happen in reality.

MLA Citation- Spanish art show spotlights ‘hidden’ digital divide in pandemic | Reuters :

Davies, Sophie. “Spanish Art Show Spotlights ‘Hidden’ Digital Divide in Pandemic.” Reuters, Thomson Reuters, 18 Dec. 2020, https://www.reuters.com/article/us-health-coronavirus-tech/spanish-art-show-spotlights-hidden-digital-divide-in-pandemic-idUSKBN28S0IC.

Project 11 – Airplane and parachute

sketchDownload
/* Jiayi Chen
   jiayiche    Section A */
//arrays for display
var birds=[];
var clouds=[];
var flyObject =[];

//array for image storage
var birdsImg=[];
var cloudsImg=[];
var flyObjectImg =[];
//array for links
var cloudLinks = [
    "https://i.imgur.com/suIXMup.png",
    "https://i.imgur.com/7ZHCI63.png",
    "https://i.imgur.com/EFb0w3u.png",
    "https://i.imgur.com/PxLKy41.png"];

var birdLinks = [
    "https://i.imgur.com/Gr1VTU5.png",
    "https://i.imgur.com/EmRp42l.png",
    "https://i.imgur.com/vLWSU4h.png",
    "https://i.imgur.com/Y9BecjA.png"];

var flyObjectLink = [
    "https://i.imgur.com/IXz53Lj.png",
    'https://i.imgur.com/UsKzDwg.png'];

//load the images
function preload(){
    airplane = loadImage("https://i.imgur.com/bEPeF8a.png");
    for (var i = 0; i < cloudLinks.length; i++){
        cloudsImg[i] = loadImage(cloudLinks[i]);
    }
    for (var i = 0; i < birdLinks.length; i++){
        birdsImg[i] = loadImage(birdLinks[i]);
    }
    for (var i = 0; i < flyObjectLink.length; i++){
        flyObjectImg[i] = loadImage(flyObjectLink[i]);
    }
}

function setup() {
    createCanvas(480, 480);
    imageMode(CENTER);
    //initial clouds 
    for (var i = 0; i < 3; i++){
        var rc = floor(random(cloudsImg.length));
        clouds[i] = makeCloud(random(width),random(100,300),random(height),cloudsImg[rc]);
    }
    frameRate(10);
}

function draw() {
    background(135,206,235);
    sun()
    updateAndDisplayClouds();
    addNewobjectsWithSomeRandomProbability();
    removeObjectsThatHaveSlippedOutOfView();
    image(airplane,200,constrain(250+random(-5,5),240,260),200,200);
}

function sun(){
    push();
    fill('orange');
    circle(60,60,50);
    fill('red');
    circle(60,60,40);

}
function updateAndDisplayClouds(){
    // Update the clouds's positions, and display them.
    for (var i = 0; i < clouds.length; i++){
        clouds[i].move();
        clouds[i].display();
    }
    // Update the birds's positions, and display them.
    for (var i = 0; i < birds.length; i++){
        birds[i].move();
        birds[i].display();
    }
    // Update the flyThings's positions, and display them.
    for (var i = 0; i < flyObject.length; i++){
        flyObject[i].move();
        flyObject[i].display();
    }
}

//remove out of sight things
function removeObjectsThatHaveSlippedOutOfView(){
    //remove out of sight clouds
    var cloudsToKeep = [];
    for (var i = 0; i < clouds.length; i++){
        if (clouds[i].x + clouds[i].size/2 > 0) {
            cloudsToKeep.push(clouds[i]);
        }
    }
    clouds = cloudsToKeep; // remember the surviving clouds

    //remove out of sight birds
    var birdsToKeep = [];
    for (var i = 0; i < birds.length; i++){
        if (birds[i].x + birds[i].size/2 > 0){
            birdsToKeep.push(birds[i]);
        }
    }
    birds = birdsToKeep; // remember the surviving birds

    //remove out of sight fly things
    var FlyesToKeep = [];
    for (var i = 0; i < flyObject.length; i++){
        if (flyObject[i].x + flyObject[i].size/2 > 0) {
             FlyesToKeep.push(flyObject[i]);
        }
    }
    flyObject = FlyesToKeep; // remember the surviving fly things
}


function addNewobjectsWithSomeRandomProbability() {
    // With a low probability, add a new clouds to the end.
    var newCloudLikelihood = 0.02; 
    if (random(0,1) < newCloudLikelihood) {
        var rc = floor(random(cloudsImg.length));
        clouds.push(makeCloud(width+75,random(100,150),random(height),cloudsImg[rc]));
    }
    // With a low probability, add a new birds to the end.
    var newbirdLikelihood = 0.03; 
    if (random(0,1) < newbirdLikelihood) {
        var rc = floor(random(birdsImg.length));
        clouds.push(makeBirds(width+30,random(30,60),random(height),floor(random(birdsImg.length))));
    }
    // With a low probability, add a new flying things to the end.
    var newObejctLikelihood = 0.01; 
    if (random(0,1) < newObejctLikelihood) {
        var rc = floor(random(flyObjectImg.length));
        clouds.push(makeFly(width+50,random(50,100),random(0,240),flyObjectImg[rc]));
    }
}

//make clouds as objects
function makeCloud(birthLocationX,cs,ch,cloudCartoon) {
    var cldg = {x: birthLocationX,
                size: cs,
                y:ch,
                speed: -1.0,
                cartoon:cloudCartoon,
                move: cloudMove,
                display: cloudDisplay}
    return cldg;
}

function cloudMove() {//move clouds
    this.x += this.speed;
}

function cloudDisplay(){
    image(this.cartoon, this.x, this.y,this.size, this.size); 
}

//make birds as objects
function makeBirds(birthLocationX,cs,ch,birdCartoon) {
    var mb = {x: birthLocationX,
                size: cs,
                y:ch,
                speed: -3.0,
                cartoonNumber:birdCartoon,
                move: birdsMove,
                display: birdsDisplay}
    return mb;
}

function birdsMove() {
    if(this.cartoonNumber == 0 || this.cartoonNumber == 1){
        this.x += this.speed/2;    //birds facing to the left are flying slower
        this.y += random(-3,3);    //randomly fly
    }else{
        this.x += this.speed;
        this.y += random(-5,5);    //randomly fly
    }

}

function birdsDisplay(){
    image(birdsImg[this.cartoonNumber], this.x, this.y,this.size, this.size); 
}

//make other flying things as objects
function makeFly(birthLocationX,cs,ch,flyCartoon) {
    var mf = {x: birthLocationX,
                size: cs,
                y:ch,
                speed: -2.0,
                cartoon:flyCartoon,
                move: flyMove,
                display: flyDisplay}
    return mf;
}

function flyMove() {//move flying objects
    this.x += this.speed;
    //gravity for things without wings
    this.y -=this.speed/4;
}

function flyDisplay(){
    image(this.cartoon, this.x, this.y,this.size, this.size); 
}

Looking Outwards 11–Section A

I read the article “Women in Media Arts: Does AI think like a (white) man?” by Anna Grubauer. AI is becoming more and more prevalent in our lives. However, this article brings up the societal issue that AI algorithms may be biased even though computers are supposedly supposed to be objective and fact-based. One explanation for this bias discussed could be because algorithms are only as unbiased as the coders who them. But, due to the lack of representation of women as programmers, the algorithms might be biased.

This is important because, as AI starts to be used more and more, we start to trust it with serious matters. In some cases, we cannot afford minor biases, such as when AI is used in predictive studies so AI is used to determine who is hired, offered loans, and make other important decisions (as brought up in the Gender Shades video in the article). AI is starting to be used in serious matters that have the ability to drastically impact people’s lives. If the AI is biased, it could have negative consequences on real people’s lives.

URL:
https://ars.electronica.art/aeblog/en/2020/04/10/women-in-media-arts-ai/

Looking Outwards 11

This week I read about NFT and Copyright, discussing what is NFT, why they are valuable and the issue of its copyright. NFT(Non-fungible Token) means digital and unique token. NFT can give artists a potential revenue stream when they are selling their own art. Everyone can easily access other creators’ NFT, while this raises another question that spammers can also steal it for money. Thus, copyright issues seem to be more critical: NFT auction sites created DMCA processes to prevent the spread of unauthorized NFT, but it’s not effective enough. In this article, the author also mentions that block-chain might be the perfect tool for solving copyright problems, but it still brings new privacy concerns. In a nutshell, NFT itself needs to be scarce if it wants to create artificial scarcity. There is still a long way to go.

https://www.plagiarismtoday.com/2021/03/16/nfts-and-copyright/

Project-11-Landscape

I take references from this animation/rendering competition and made this robot pushing a sphere in an alien planet:

I have trees generation in the background

boulders in front

and hills in the back

/*
 * Andrew J Wang
 * ajw2@andrew.cmu.edu
 * Section A
 *
 * This Program is walking
 */

//sets of links

//location of feets of the walking person
var pointXG = 0;
var pointYG = 0;

//steps (frame) locations of the feets
var stepsX = [0,1,2,3,4,5,6,7,8,9,10,10,10,10,10,10,9,8,7,6,5,4,3,2,1,0];
var stepsY = [0,0.5,1,1.5,2,2.5,3,3.5,4,4.5,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0];

//counters for multiple frames (feet + mountains)
var counter = 0;

//location of the person on the drawing
var locationX = 120;
var locationY = 200;

//arrays for trees for clusters of boulders 
var trees = [];
var clusters = [];

//set a array for land heights (FROM PREVIOUS ASSIGNMENT)
var landHeight = [];
var landHeight2 = [];

//create noice parameter and steps
var noiseParam = 0;
var noiseParam2 = 0;
var noiseStep = 0.005;
var noiseStep2 = 0.01;

function setup() {
    createCanvas(480,300);
    // create an initial collection of trees
    for (var i = 0; i < 5; i++){
        var rx = random(width);
        trees[i] = makeTrees(rx);
    }

    // create an initial collection of boulders
    for (var i = 0; i < 10; i++)
    {
        var rx2 = random(width);
        clusters[i] = makeClusters(rx2);
    }

    //hill #1
    for (var k=0; k<=480; k++)
    {   
        //get noise through noise param
        var n = noise(noiseParam);
        //remapping based on height
        var value = map(n,0,1,0,height/4)+130;
        //add to array
        landHeight.push(value);
        //plus steps
        noiseParam += noiseStep;
    }

    //hill #2
    for (var k=0; k<=480; k++)
    {   
        //get noise through noise param
        var n2 = noise(noiseParam2);
        //remapping based on height
        var value2 = map(n2,0,1,0,height/3)+80;
        //add to array
        landHeight2.push(value2);
        //plus steps
        noiseParam2 += noiseStep2;
    }

}


function draw() {
    background(100);

    //MOON
    push();
    noStroke();
    fill(255,255,220);
    ellipse(380,0,250,250);
    pop();

    //draw first sets of hill
    push();
    noStroke();
    fill(240);
    beginShape();
    //fist vertex
    vertex(0,(locationY+70+60)*0.8-80);
    //for loop to grab all the vertex
    for (var k=0; k<=480; k++)
    {   
    vertex(k,landHeight2[k]);
    }
    //last vertex
    vertex(width,(locationY+70+60)*0.8-80);
    endShape(CLOSE);
    //adding another point by shifting
    var n2=noise(noiseParam2);
    var value2 = map(n2,0,1,0,height/3)+80;
    noiseParam2 += 0.01/20;
    //slowing the speed of refreshing by using a counter
    if (counter%40==0)
    {
        landHeight2.shift();
        landHeight2.push(value2);
    }
    pop();

    //draw second sets of hill
    push();
    noStroke();
    fill(220);
    beginShape();
    //fist vertex
    vertex(0,(locationY+70+60)*0.8-80);
    //for loop to grab all the vertex
    for (var k=0; k<=480; k++)
    {   
    vertex(k,landHeight[k]);
    }
    //last vertex
    vertex(width,(locationY+70+60)*0.8-80);
    endShape(CLOSE);
    //adding another point by shifting
    var n=noise(noiseParam);
    var value = map(n,0,1,0,height/4)+130;
    noiseParam += 0.005/5;
    //slowing the speed of refreshing by using a counter
    if (counter%10==0)
    {
        landHeight.shift();
        landHeight.push(value);
    }
    pop();

    //ground plane
    push();
    noStroke();
    fill(200);
    rect(0,(locationY+70+60)*0.8-80,width, height-((locationY+70+60)*0.8-80));
    pop();

    //set trees and clusters by refreshing the removed objects and clusters
    updateDisplay();
    removeTrees();
    addTrees();
    removeClusters();
    addClusters();

    //walking person
    strokeWeight(3);
    push();

    //scaling it
    scale(0.6);
    translate(0,150);
    walking(locationX,locationY);
    walking2(locationX,locationY);
    body(locationX,locationY);

    //butt
    push();
    strokeWeight(2);
    ellipse(locationX,locationY,15,15);
    pop();
    pop();

    //display clusters in the end
    updateDisplay2();

}


//refreashing trees and display them
function updateDisplay(){
    for (var i = 0; i < trees.length; i++){
        trees[i].move();
        trees[i].display();
    }
}

//refreshing boulders and display them
function updateDisplay2(){
    for (var i = 0; i < clusters.length; i++){
        clusters[i].move();
        clusters[i].display();
    }
}

//removing trees if it is too far away from the screen
function removeTrees(){
    var treesToKeep = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x + trees[i].breadth > 0) {
            treesToKeep.push(trees[i]);
        }
    }
}

//removing boulders if it is too far away from the screen
function removeClusters(){
    var clustersToKeep = [];
    for (var i = 0; i < clusters.length; i++){
        if (clusters[i].x + clusters[i].breadth > 0) {
            clustersToKeep.push(clusters[i]);
        }
    }
}

//add trees 100 units away from border
function addTrees() {
    var Likelihood = 0.01; 
    if (random(0,1) < Likelihood) {
        trees.push(makeTrees(width+100));
    }
}

//add boulders 500 units away from border
function addClusters() {
    var Likelihood = 0.01; 
    if (random(0,1) < Likelihood) {
        clusters.push(makeClusters(width+500));
    }
}

//set trees values and function
function makeTrees(birthLocationX) {
    var tree = {x: birthLocationX,
                breadth: 100,
                speed: -0.4,
                y: 160+round(random(20)),
                treeHeight: round(random(40,50)),
                size: round(random(30,50)),
                move: objectMove,
                display: treeDisplay}
    return tree;
}

//set boulders values and functions
function makeClusters(birthLocationX) {
    var tree = {x: birthLocationX,
                breadth: 100,
                speed: -2.0,
                treeHeight: round(random(40,50)),
                size: round(random(200,350)),
                move: object2Move,
                display: clusterDisplay}
    return tree;
}

//move objects 
function objectMove() {
    this.x += this.speed;
}

function object2Move() {
    this.x += this.speed;
}

//draw trees
function treeDisplay() {
    line(this.x, this.y , this.x, this.y+this.treeHeight);

    push();
    translate(this.x,this.y);
    rectMode(CENTER);
    noFill();
    strokeWeight(1);

    push();
    rotate(-counter/180*Math.PI);
    rect(0,0,this.size,this.size);
    pop();

    push();
    rotate(counter/180*Math.PI);
    rect(0,0,this.size-10,this.size-10);
    pop();


    pop();
}

//draw bolders
function clusterDisplay() {
    push();
    fill(0);
    ellipse(this.x,height+30,this.size,this.size/2);
    strokeWeight(1.5);
    noFill();
    ellipse(this.x,height+30,this.size+20,this.size/2+10);
    pop();
}

//leg #1
function walking(xL,yL)
{   
    //counter/10 get frame number
    var counterK = Math.floor(counter/10)%(stepsX.length);

    //Feet locations
    pointXG = xL-70+stepsX[counterK]*6;
    pointYG = yL+70-stepsY[counterK]*4;

    //Pathegorean theorm to get the knee and legs
    var dis = Math.sqrt((xL-pointXG)*(xL-pointXG)+(yL-pointYG)*(yL-pointYG));
    var num = (10000)-(dis*dis);
    var sid = sqrt(num);
    var midX = xL-(xL-pointXG)/2;
    var midY = yL-(yL-pointYG)/2;
    var tan = atan2(pointXG-xL,pointYG-yL);
    ellipse ((pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2, 5,5);
    line(xL,yL,(pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2);
    line(pointXG,pointYG,(pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2);

    //feet bending
    if (stepsY[counterK]==0)
    {
        line(pointXG,pointYG,pointXG+20,pointYG);
    }
    else
    {
        var tanF = atan2(Math.sqrt(400-stepsY[counterK]*2),stepsY[counterK]*4);
        line(pointXG,pointYG,pointXG+20*sin(tanF),pointYG+20*cos(tanF));
    }

    counter++;
}

//repeat for the second leg
function walking2(xL,yL)
{   
    var counterK = (Math.floor(counter/10)+stepsX.length/2)%(stepsX.length);
    pointXG = xL-70+stepsX[counterK]*6;
    pointYG = yL+70-stepsY[counterK]*4;
    var dis = Math.sqrt((xL-pointXG)*(xL-pointXG)+(yL-pointYG)*(yL-pointYG));
    var num = (10000)-(dis*dis);
    var sid = sqrt(num);
    var midX = xL-(xL-pointXG)/2;
    var midY = yL-(yL-pointYG)/2;
    var tan = atan2(pointXG-xL,pointYG-yL);
    ellipse ((pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2, 5,5);
    line(xL,yL,(pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2);
    line(pointXG,pointYG,(pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2);
    if (stepsY[counterK]==0)
    {
        line(pointXG,pointYG,pointXG+20,pointYG);
    }
    else
    {
        var tanF = atan2(Math.sqrt(400-stepsY[counterK]*2),stepsY[counterK]*4);
        line(pointXG,pointYG,pointXG+20*sin(tanF),pointYG+20*cos(tanF));
    }

    counter++;

}

//body parts and other stuff
function body(xL,yL)
{
    var counterK = (Math.floor(counter/10)+stepsX.length/2)%(stepsX.length);
    var counterK2 = (Math.floor(counter/10)+10)%(stepsX.length);
    var counterK3 = (Math.floor(counter/10)+25)%(stepsX.length);
    push();
    strokeWeight(2);
    fill("grey")
    //shoulder 1
    ellipse(xL+35+stepsY[counterK2],yL-45-stepsX[counterK2],30,30);

    //hand
    ellipse(xL+35+60,yL-45-stepsX[counterK]+10,10,10);
    pop();

    //arms
    line(xL+35+stepsY[counterK],yL-45-stepsX[counterK],xL+35+30,yL-45-stepsX[counterK]+20);
    line(xL+35+30,yL-45-stepsX[counterK]+20,xL+35+60,yL-45-stepsX[counterK]+10);

    //body
    line(xL,yL,xL+35+stepsY[counterK],yL-45-stepsX[counterK]);

    push();
    fill("black");
    ellipse(xL+35+30,yL-45-stepsX[counterK]+20,5,5);
    pop();

    //Round thingy
    push();
    noFill();
    strokeWeight(2);
    ellipse(xL+35+175,yL-45,230,230);
    fill(255);
    ellipse(xL+35+175,yL-45,220,220);

    stroke(255);

    pop();


    //shoulder 2
    push();
    noStroke();
    ellipse(xL+35+stepsY[counterK2],yL-45-stepsX[counterK2],15,15);
    pop();

    //head
    push();
    strokeWeight(1);
    noFill();
    translate(xL+55+stepsY[counterK3],yL-85-stepsX[counterK3]);
    rectMode(CENTER);
    rotate(-counter/180*Math.PI);
    rect(0,0,40,40);
    rect(0,0,30,30);
    pop();

    push();
    strokeWeight(1);
    noFill();
    translate(xL+65+stepsY[counterK2]*2,yL-95-stepsX[counterK2]);
    rectMode(CENTER);
    rotate(counter/180*Math.PI);
    rect(0,0,25,25);
    rect(0,0,30,30);
    pop();

    push();
    strokeWeight(1);
    noFill();
    translate(xL+45+stepsY[counterK]*2,yL-75-stepsX[counterK]);
    rectMode(CENTER);
    rotate(counter/180*Math.PI);
    rect(0,0,25,25);
    rect(0,0,15,15);
    pop();

}





looking outwards-11

In Women in Media Arts: Does AI think like a (white) man?, Grubauer presents the view of Ars Electronica on AI for the purpose of supporting their project, which is to create “a comprehensive database devoted specifically to women in media art.” They did this to help give girls and women role models in terms of media art by increasing the presence of women artists in the public consciousness. Such projects play an important role in countering as hegemonic a phenomenon as patriarchy in the western world, which has shown through feminist philosophy and sociological research, that patriarchal (and white) tendencies permeate the cultural logic or societal common sense to the point of influencing objectivist science. “More and more activists point out the problematic prejudices and distortions of supposedly objective [my italics] algorithms. This has not only to do with the low proportion of female programmers and women in the IT sector in general, but above all with the biased data sets.” The mention of Mary Flanagan in this article aptly points out that this is a structural problem of society that creates the permeation I mention; it would be absurd to say an algorithm is inherently sexist or racist, and this claim is likely apprehended by confused defendants of the activists who push for making AI more equitable. The rest of the article introduces other women in the field of media art and their work such as Buolamwini/Gebru on skin color recognition, Aga/Manton on women-empowering AI, and Sinders’ feminist data set.

All quotes are from the article linked below.

https://ars.electronica.art/aeblog/en/2020/04/10/women-in-media-arts-ai/