Category Archives: 22-animatedgif

John Mars

10 Feb 2015

Magic Eye images, or Autostereograms are those cool pictures that make a 3D object appear when you cross your eyes funny. I’ve made an application using kylemcdonald/ofxAutostereogram and Geistyp/ofxGif to import a depth-map gif like the one below, and an obfuscation image (the crumpled paper) and export a Magic Eye GIF. I thought it would be an interesting twist on something from my childhood, and I wanted to see if the effect would even work on a lenticular print. I also wanted to add autostereogram 3d to my 3d image toolkit, as well as 3d animations.

I originally tried to generate a rotating icosahedron and use its openGL depth map texture as the depth map image instead of using the Kinect depth video, but I was ultimately unsuccessful. My next venture is certainly going to be exploring Fbos and shaders. I also tried generating a static image instead of using the paper tiles as the background, but it seems that autostereograms can’t use white noise for that purpose.

CAVEATS: I didn’t have access to a Kinect while I was building the application, so it’s currently using stills from a video I found online. I’ll switch it out to a video of me ASAP. Also, I didn’t even realize this until it was too late, but it looks like one of the examples in ofxAutostereogram creates animated stereograms from Kinect video, so, this isn’t even an original idea (although it was derived independently).

Here’s the ofApp.cpp:

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){

    ofSetFrameRate(5);

    i = 0;
    
    bgTile.loadImage("paper.jpg");
    bgTile.resize(128, 128);
    
    gifLoader.load("kinect.gif");
    
    // allocate images
    depthMap.allocate(gifLoader.pages[0].getWidth(), gifLoader.pages[0].getHeight(), OF_IMAGE_GRAYSCALE);
    magicEye.allocate(depthMap.getWidth() + bgTile.getWidth(), depthMap.getHeight(), OF_IMAGE_COLOR);
    
    ofSetWindowShape(magicEye.width, magicEye.height + bgTile.getWidth());
    
    gifSaver.create("output.gif");
}

//--------------------------------------------------------------
void ofApp::update(){
    
    depthMap.setFromPixels(gifLoader.pages[i % 9]);
    depthMap.setImageType(OF_IMAGE_GRAYSCALE);
    
    i++;
}

//--------------------------------------------------------------
void ofApp::draw(){

    ofBackground(0);

    float depthMultiplier = .2;
    ofxAutostereogram::makeAutostereogram(bgTile, depthMap, depthMultiplier, magicEye);

    magicEye.update();
    magicEye.draw(0, 0, ofGetWidth(), ofGetHeight());
    
    if (i < 10) {
        ofImage img;
        img.grabScreen(0, 0, ofGetWidth(), ofGetHeight());
        gifSaver.append(img.getPixelsRef());
    }
    
    if (i == 10) {
        gifSaver.save();
        ofLog() << "SAVED";
    }
}

And the entire project’s code can be found here: https://github.com/marsman12019/stereoGIF

Ron

10 Feb 2015

RonKim

I am a novice Processing user, but I enjoyed using it for this assignment. There is plenty of documentation, which was quite helpful. This particular GIF originated from the workings of my hose nozzle face, which spins counter clockwise when water flows through it and the openings seem to grow and shrink during the rotation. In the GIF, the changing shapes seems proportional through the loop, but the overall animation seems less than smooth to me. I also feel like there could be more added to enhance the animation.

// This is a template for creating a looping animation in Processing. 
// When you press a key, this program will export a series of images
// into an "output" directory located in its sketch folder. 
// These can then be combined into an animated GIF. 
// Prof. Golan Levin, January 2014 - CMU IACD

//===================================================
// Global variables. 

int     nFramesInLoop = 10; // for lenticular export, change this to 10!
int     nElapsedFrames;
boolean bRecording; 

int     screenWidth = 500;
int     screenHeight = 500;

//===================================================
void setup() {
  size (screenWidth, screenHeight); 
  bRecording = false;
  nElapsedFrames = 0;
  frameRate (nFramesInLoop); 
  rectMode(CENTER);
}
//===================================================
void keyPressed() { 
  // Press a key to export frames to the output folder
  bRecording = true;
  nElapsedFrames = 0;
}

//===================================================
void draw() {

  // Compute a percentage (0...1) representing where we are in the loop.
  float percentCompleteFraction = 0; 
  if (bRecording) {
    percentCompleteFraction = (float) nElapsedFrames / (float)nFramesInLoop;
  } else {
    float modFrame = (float) (frameCount % nFramesInLoop);
    percentCompleteFraction = modFrame / (float)nFramesInLoop;
  }

  // Render the design, based on that percentage. 
  renderMyDesign (percentCompleteFraction);

  // If we're recording the output, save the frame to a file. 
  if (bRecording) {
    String myName = "ron";
    saveFrame("output/"+ myName + "-loop-" + nf(nElapsedFrames, 4) + ".png");
    nElapsedFrames++; 
    if (nElapsedFrames == nFramesInLoop) {
      bRecording = false;
    }
  }
}

//===================================================
void renderMyDesign (float percent) {

  // This is an example of a function that renders a temporally looping design. 
  // It takes a "percent", between 0 and 1, indicating where we are in the loop. 
  // This example uses two different graphical techniques. 
  // Use or delete whatever you prefer from this example. 
  // Remember to SKETCH FIRST!

float rotationAmount = percent*90;

  //----------------------
  // here, I set the background and some other graphical properties
  //background (0, 153, 255);
  background (0, 0, 0);
  smooth();
  //stroke (255, 0, 0);
 stroke (255, 255, 255); 
  fill(255, 255, 255); 
  

  //----------------------
  // Here, I assign some handy variables. 
  float screenCenter = screenWidth / 2;
  
  //----------------------
  translate(screenCenter, screenCenter);
  rotate(radians(rotationAmount)); // rotate clockwise
  translate(-screenCenter, -screenCenter);

  pushMatrix();
  //map percent completion to width of collapsable diamond
  float diamondSideVertex = 0.0;
  if (percent < 0.5) {
    diamondSideVertex = map(percent, 0, 1, 0, 50);
  } else {
    diamondSideVertex = map((1-percent), 0, 1, 0, 50);
  }
  translate(250, 250);
  //Draw collapsable square-diamond-thingys
  stroke (0, 0, 0);
  strokeWeight(2);
  ellipse (0, 0, 100, 100);
  beginShape();
  vertex(0, 0);
  vertex(-diamondSideVertex, diamondSideVertex);
  vertex(0, 50);
  vertex(diamondSideVertex, diamondSideVertex);
  endShape(CLOSE);
  beginShape();
  vertex(0, 0);
  vertex(-diamondSideVertex, -diamondSideVertex);
  vertex(0, -50);
  vertex(diamondSideVertex, -diamondSideVertex);
  endShape(CLOSE);
  beginShape();
  vertex(0, 0);
  vertex(-diamondSideVertex, diamondSideVertex);
  vertex(-50, 0);
  vertex(-diamondSideVertex, -diamondSideVertex);
  endShape(CLOSE);
  beginShape();
  vertex(0, 0);
  vertex(diamondSideVertex, diamondSideVertex);
  vertex(50, 0);
  vertex(diamondSideVertex, -diamondSideVertex);
  endShape(CLOSE);
  popMatrix();

  // Draw 8 expanding/collapsing periphery circles
  pushMatrix();
  translate(108.58, 250);
  if (percent <0.5) {
    ellipse(0, 0, 100*percent, 100*percent);
  } else {
    ellipse (0, 0, (100*(1-percent)), 100*(1-percent));
  }
  popMatrix();

  pushMatrix();
  translate(150, 150);
  if (percent <0.5) {
    ellipse(0, 0, 100*percent, 100*percent);
  } else {
    ellipse (0, 0, (100*(1-percent)), 100*(1-percent));
  }
  popMatrix();

  pushMatrix();
  translate(250, 108.58);
  if (percent <0.5) {
    ellipse(0, 0, 100*percent, 100*percent);
  } else {
    ellipse (0, 0, (100*(1-percent)), 100*(1-percent));
  }
  popMatrix();

  pushMatrix();
  translate(350, 150);

  if (percent <0.5) {
    ellipse(0, 0, 100*percent, 100*percent);
  } else {
    ellipse (0, 0, (100*(1-percent)), 100*(1-percent));
  }
  popMatrix();

  pushMatrix();
  translate(391.42, 250);
  if (percent <0.5) {
    ellipse(0, 0, 100*percent, 100*percent);
  } else {
    ellipse (0, 0, (100*(1-percent)), 100*(1-percent));
  }
  popMatrix();

  pushMatrix();
  translate(350, 350);
  if (percent <0.5) {
    ellipse(0, 0, 100*percent, 100*percent);
  } else {
    ellipse (0, 0, (100*(1-percent)), 100*(1-percent));
  }
  popMatrix();

  pushMatrix();
  translate(250, 391.42);
  if (percent <0.5) {
    ellipse(0, 0, 100*percent, 100*percent);
  } else {
    ellipse (0, 0, (100*(1-percent)), 100*(1-percent));
  }
  popMatrix();

  pushMatrix();
  translate(150, 350);
  if (percent <0.5) {
    ellipse(0, 0, 100*percent, 100*percent);
  } else {
    ellipse (0, 0, (100*(1-percent)), 100*(1-percent));
  }
  popMatrix();
}

John Choi

10 Feb 2015


This is an expansion of the Generative Tank Project I did for the Generative Forms part of Assignment 2x. For a more detailed description, check out this link:  https://ems.andrew.cmu.edu/2015/johnchoi/02/10/generative-tank/

Specifically for the GIF aspect of this project, I really wanted to show the depth of the generated tanks, and I think it really shows here.  After iterating through a bunch of randomly generated tanks, I picked one I liked for a rotating 3D view.  I chose this one because it is a really plain, standard tank shows many default features of the variability, and the sides are clean.  A bit too clean, actually.  I really think this GIF could have been a little less bland by choosing a more exotic tank, but this one does get the point across.  (If you look closely, you’ll see the tracks are actually moving.  A subtle detail, but an important one.)

Again, the same sketch:

sketch

Here is the code: (slightly modified from my original generative tank script to allow rotation)

import rhinoscriptsyntax as rs
import random
import math

#select nothing
rs.Command("SelNone")

#helper to get and assign parts
def makePart(name,group):
obj = rs.ObjectsByName(name)[0]
group.append(obj)
return obj

# turret parts:
turretParts = []
turretPoint = makePart("turretPoint",turretParts)
turretPivot = makePart("turretPivot",turretParts)
barrelPivot = makePart("barrelPivot",turretParts)
barrelStart = makePart("barrelStart",turretParts)
turretHull = makePart("turretHull",turretParts)
topHatch = makePart("topHatch",turretParts)
barrel = makePart("barrel",turretParts)
# hull parts:
hullParts = []
sidePort = makePart("sidePort",hullParts)
hull = makePart("hull",hullParts)
# track parts:
trackParts = []
trackPiece = makePart("trackPiece",trackParts)
trackFront = makePart("trackFront",trackParts)
trackBack = makePart("trackBack",trackParts)
trackMid = makePart("trackMid",trackParts)
sprocketFrontParts = []
sprocketBackParts = []
#Sprocket Parts:
spf = []
for i in range(0,5):
spf.append(makePart("spf"+str(i),sprocketFrontParts))
sprocketFront = makePart("sprocketFront",sprocketFrontParts)
sprocketFrontPoint = makePart("sprocketFrontPoint",sprocketFrontParts)
spb = []
for i in range(0,5):
spb.append(makePart("spb"+str(i),sprocketBackParts))
sprocketBack = makePart("sprocketBack",sprocketBackParts)
sprocketBackPoint = makePart("sprocketBackPoint",sprocketBackParts)
#Wheel Parts
wheel = makePart("wheel",trackParts)
wheelPoint = makePart("wheelPoint",trackParts)

#randomize?
randomize = 0
phase = 9;

#turret variables:
barrelLength = 22.4 + random.uniform(-8,8)*randomize
barrelScale = 1.38 + random.uniform(-.5,1)*randomize
barrelCount = 1 + random.randrange(0,3)*randomize
turretScale = 1.22 + random.uniform(-.2,.5)*randomize
#hull variables:
hullHeight = 14.1 + random.uniform(-4,6)*randomize
hullWidth = 19.15 + random.uniform(-8,8)*randomize
hullLength = 36.0 + random.uniform(-12,12)*randomize
portsPerSide = 4 + random.randrange(0,4)*randomize
#track variables:
wheelCount = 4 + random.randrange(-1,5)*randomize
wheelSprocketDistance = 5.36 + random.uniform(-4,4)*randomize
wheelScale = 1.1 + random.uniform(-.5,1)*randomize
sprocketScale = 0.67 + random.uniform(-.5,1)*randomize
suspension = 2.33 + random.uniform(-2,3)*randomize
trackHeight = .68 + random.uniform(-.4,.6)*randomize
trackLength = 1.0 + random.uniform(-.8,.8)*randomize
trackOffset = 0 + phase*.1 + random.uniform(0,trackLength)*randomize
trackCount = 50 + random.randrange(-10,20)*randomize
#color variables
r = 0+random.randrange(0,160)*randomize
g = 45+random.randrange(0,160)*randomize
b = 12+random.randrange(0,160)*randomize
hullColor1 = [r,g,b]
hullColor2 = [r*4/5,g*4/5,b*4/5]
hullColor3 = [r*3/5,g*3/5,b*3/5]
r1 = 12+random.randrange(0,60)*randomize
g1 = 53+random.randrange(0,60)*randomize
b1 = 17+random.randrange(0,60)*randomize
wheelColor = [r1,g1,b1]
trackColor = [r1/2,g1/2,b1/2]

#print variables?
printvars = True
if (printvars):
#turret variables
print "barrelLength = "+str(barrelLength)
print "barrelScale = "+str(barrelScale)
print "barrelCount = "+str(barrelCount)
print "turretScale = "+str(turretScale)
#hull variables
print "hullHeight = "+str(hullHeight)
print "hullWidth = "+str(hullWidth)
print "hullLength = "+str(hullLength)
print "portsPerSide = "+str(portsPerSide)
#track variables
print "wheelCount = "+str(wheelCount)
print "wheelSprocketDistance = "+str(wheelSprocketDistance)
print "wheelScale = "+str(wheelScale)
print "sprocketScale = "+str(sprocketScale)
print "suspension = "+str(suspension)
print "trackHeight = "+str(trackHeight)
print "trackLength = "+str(trackLength)
print "trackOffset = "+str(trackOffset)
print "trackCount = "+str(trackCount)
#color variables
print "(r,g,b) = "+str(r)+", "+str(g)+", "+str(b)
print "(r1,g1,b1) = "+str(r1)+", "+str(g1)+", "+str(b1)

# --- color objects --- #
#hullColor1
for part in turretParts:
rs.ObjectColor(part,hullColor1)
for part in hullParts:
rs.ObjectColor(part,hullColor1)
#hullColor2
rs.ObjectColor(turretPivot,hullColor2)
rs.ObjectColor(barrelPivot,hullColor2)
#hullColor3
for part in trackParts:
rs.ObjectColor(part,hullColor3)
#wheelColor
rs.ObjectColor(sprocketFront,wheelColor)
rs.ObjectColor(sprocketBack,wheelColor)
rs.ObjectColor(wheel,wheelColor)
#trackColor
rs.ObjectColor(trackPiece,trackColor)
# --- control hull --- #
#resize hull (hullLength,hullWidth,hullHeight)
(x,y,z) = [hullLength/36.0,hullWidth/20.0,hullHeight/10.0]
rs.ScaleObject(hullParts,(0,0,0),[x,y,z])
rs.ScaleObject(trackFront,(0,0,0),[x,1,z])
rs.ScaleObject(trackBack,(0,0,0),[x,1,z])
rs.ScaleObject(trackMid,(0,0,0),[x,1,z])
#move track parts to accommodate
rs.MoveObject(trackParts,[0,hullWidth/2.0-10.0,0])
rs.MoveObject(sprocketFrontParts,[0,hullWidth/2.0-10.0,0])
rs.MoveObject(sprocketBackParts,[0,hullWidth/2.0-10.0,0])
#move turret parts to accommodate
rs.MoveObject(turretParts,[0,0,hullHeight-10.0])
#move sprockets to accomodate
rs.MoveObject(sprocketFrontParts,[hullLength/2.0-18.0,0,0])
rs.MoveObject(sprocketBackParts,[-hullLength/2.0+18.0,0,0])
#make ports
if(portsPerSide > 1):
rs.MoveObject(sidePort,[hullLength*.3,0,0])
for i in range(1,portsPerSide):
distance = (hullLength*.6)/(portsPerSide-1)*(-i)
rs.CopyObjects(sidePort,[distance,0,0])

# --- CONTROL WHEELS --- #
#scale wheels (wheelScale, sprocketScale)
rs.ScaleObject(sprocketFrontParts,sprocketFrontPoint,[sprocketScale,1,sprocketScale])
rs.ScaleObject(sprocketBackParts,sprocketBackPoint,[sprocketScale,1,sprocketScale])
rs.ScaleObject(wheel,wheelPoint,[wheelScale,1,wheelScale])

#move wheels down (suspension)
rs.MoveObject([wheel,wheelPoint],[0,0,-suspension])

#create wheels and curve(wheelCount, wheelSprocketDistance)
trackPoints = []
trackPoints.extend(spf)
sx = hullLength/2.0-wheelSprocketDistance
sy = hullWidth/2.0+2.5
sz = -wheelScale*2.5-suspension
trackPoints.append([sx+wheelSprocketDistance/4.0,sy,sz])
rs.MoveObject([wheel,wheelPoint],[hullLength/2.0-wheelSprocketDistance,0,0])
for i in range(1,wheelCount):
distance = (hullLength-2.0*wheelSprocketDistance)/(wheelCount-1)*(-i)
rs.CopyObjects([wheel,wheelPoint],[distance,0,0])
trackPoints.append([sx + distance,sy,sz])
trackPoints.append([-sx-wheelSprocketDistance/4.0,sy,sz])
trackPoints.extend(spb)
trackPoints.append(spf[0])
trackCurve = rs.AddCurve(trackPoints)

# --- control turret --- #
#scale turret
rs.ScaleObject(turretParts,turretPoint,[turretScale,turretScale,turretScale])

#barrel (barrelLength, barrelCount)
rs.ScaleObject(barrel, barrelStart, [barrelLength/20.0,barrelScale,barrelScale])

#make barrels (barrelCount)
if(barrelCount > 1):
rs.MoveObject(barrel,[0,4,0])
for i in range(1,barrelCount):
distance = (8)/(barrelCount-1)*(-i)
rs.CopyObjects(barrel,[0,distance,0])
#create track pieces (trackCount, trackHeight, trackLength)
rs.ScaleObject(trackPiece,(0,hullWidth/2.0,0), [trackLength,1,trackHeight])
rs.MoveObject(trackPiece,[trackOffset,0,sprocketScale*2.5])

#these commands are not in Rhino Python.
rs.Command("ArrayCrv") # make track along curve.
rs.Command("RunScript") # Set Material Render Colors.
rs.Command("Mirror") # mirror features.

#select all and rotate
rs.Command("SelAll")
all = rs.SelectedObjects()
rs.RotateObjects(all,(0,0,0), math.cos(phase*2.0*math.pi / 10.0)*10, axis = [0,0,1])

The final rendered images were compiled into a GIF with GIMP.

Yeliz Karadayi

10 Feb 2015

 

gif sketch

What inspired MY design? Well Jose Garcia del Castillo introduced me to an interesting javascript library he created himself. It was built around the workflow of parametricism, so naturally, I was interested.

Having only learned javascript in another class last week, I figured I should take the opportunity to make my gif with this libarary, called sketchpad, so that I can learn javascript animations a lot more thoroughly than I was able to with anitype project. Definitely learned a lot, or at least was confused a lot…

Either way I was looking to get an effect that was mesmerizing and soothing to stare at. The colors are subtle transparent colors of red, green, and blue, and as the shapes rotate they melt together to create hues of gray or overlap with other circle of the same fill to highlight that color more. On top of that I drew some simple but cool-looking lines from a pentagon that I learned to construct using descriptive geometry methods [ergo, parametricism]. It was a lot of fun. I wish I had had more time. It wasn’t at all what I was intending for it to be, as my sketches had shown fully opaque pentagons and circles revolving around a center point from a very close radius and rotating slowly, ideally having pentagons poke out behind circles poking out behind more pentagons, and so on. Unfortunately the library he made was only just released yesterday, and he has a lot left to do with it. It cannot make shapes with fills as far as I can tell yet, so I’ve contacted Jose with some feedback on his library. I felt pretty good about my decision to use it regardless so that I could be put his library to the test and help out with his project while completing my own.

If I could change anything I just would have been able to implement even more basic javascript functionality, as I currently felt quite limited without much knowledge of it and depending heavily on his library, unable to do many work-arounds for any missing functionalities. Things like the layer order so that I could control what covered what directly. Or making basic shapes.

The other failure is that this animation is best at a slow pace and it seems huge when I try to make it into a gif. Instead, I do have a youtube video and a smaller gif.


< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

xmlns="http://www.w3.org/1999/xhtml">
 <head>
<span class="hiddenSpellError" pre="" data-mce-bogus="1">Sketchpad</span>.js - Basic Template
 css/styles.css" type="text/css"/>
 </head>

 <body>
 <div id="sketchpadDiv">
 sketchpadCanvas"> 
 </div>

 
 
 
 <script>


 // Sketchpad code goes here
 var pad = new Sketchpad('sketchpadCanvas'); // instantiate a new Sketchpad on canvas



 var black = new pad.Style({
 strokeWidth: 6.0
 });
 var invis = new pad.Style({
 strokeWidth: 0.0001
 });
 var circleF = new pad.Style({
 strokeWidth: 0.1,
 fill: 'rgba(100,200,200, .2)'
 });
 var circleF1 = new pad.Style({
 strokeWidth: 0.1,
 fill: 'rgba(200,100,200, .2)'
 });
 var circleF2 = new pad.Style({
 strokeWidth: 0.1,
 fill: 'rgba(200,200,100, .2)'
 });

 var styles = [circleF, circleF1, circleF2];

 
 function makeShape(B, ABmid) {
 pad.currentStyle(invis);
 var ABrad = pad.Measure.distance(ABmid,B);
 var ABcir = pad.Circle.centerRadius(ABmid, ABrad);
 var ABmidB = pad.Line.between(ABmid, B);
 var A = pad.Point.intersection(ABmidB, ABcir).items[0];
 var ABlen = pad.Measure.distance(A,B);




 var Acir = pad.Circle.centerRadius(A, ABlen);
 var Bcir = pad.Circle.centerRadius(B, ABlen);
 var ABint = pad.Point.intersection(Acir, Bcir).items[0];

 var ABperp0 = pad.Line.between(ABmid, ABint);
 var abPerpInt = pad.Point.intersection(ABperp0, ABcir).items[0];

 var ABperp = pad.Line.between(ABmid, abPerpInt);

 var ABPmid = pad.Point.along(ABperp, .5);
 var ABPrad = pad.Measure.distance(ABPmid, ABmid);
 var ABPcir = pad.Circle.centerRadius(ABPmid, ABPrad);
 var ABPB = pad.Line.between(B, ABPmid);

 var ABPBints = pad.Point.intersection(ABPB, ABPcir).items;
 var ABPBint0 = ABPBints[0];
 var ABPBint1 = ABPBints[1];

 var Brad0 = pad.Measure.distance(ABPBint0,B);
 var Brad1 = pad.Measure.distance(ABPBint1,B);
 
 var Bcir0 = pad.Circle.centerRadius(B,Brad0);
 var Bcir1 = pad.Circle.centerRadius(B,Brad1);

 var Bcir0ints = pad.Point.intersection(Bcir0,ABcir);
 var Bcir1ints = pad.Point.intersection(Bcir1,ABcir);

 var pt1 = Bcir0ints.items[1];
 var pt2 = Bcir0ints.items[0];
 var pt3 = Bcir1ints.items[0];
 var pt4 = Bcir1ints.items[1];
 var pts1 = [pt1, pt2, pt3, A, pt4];
 // var pts = new Set(pts1);
 // pts.type = pad.C.SET;
 // pts.subtype = pad.C.POINT;
 // var pts = pad.Set.prototype.setItems(pts1, pad.C.POINT);
 pad.currentStyle(black);
 // var l1 = pad.Line.between(ABmid, pts);
 // var l2 = pad.Line.between(pt2, pt3);
 // var l3 = pad.Line.between(pt3, A);
 // var l4 = pad.Line.between(A, pt4);
 // var l5 = pad.Line.between(pt4, pt1);
 var midpts = []
 for (i = 0; i < 5; i++) {
 var ircle = pad.Circle.centerRadius(pts1[i], 100);
 ircle.setStyle(styles[(thisStyle+=1)%3]);
 pad.currentStyle(black);
 }
 for (i = 0; i < 5; i++) {
 for (j = 0; j < 5; j++) {
 if(j > i){
 var line = pad.Line.between(pts1[i], pts1[j]);
 // for (k = .2; k < 1; k+=.2) {
 var x = pad.Point.along(line, .5);
 // var y = pad.Point.along(line, .7);
 midpts.push(x);
 // midpts.push(y);
 // }
 }
 }
 }
 for (i = 0; i < midpts.length; i++) {
 pad.currentStyle(circleF);
 rcle = pad.Circle.centerRadius(midpts[i], 100);
 pad.currentStyle(black);
 }
 for (i = 0; i < midpts.length; i++) {
 for (j = 0; j < midpts.length; j++) {
 if(j > i){
 var line = pad.Line.between(midpts[i], midpts[j]);
 }
 }
 
 }
 }
 var a1= new pad.Point(pad.width.value/2, pad.height.value/2 + 100);
 var b1 = new pad.Point(pad.width.value/2, pad.height.value/2);

 var a2= new pad.Point(pad.width.value/2, pad.height.value/2 + 100);
 var b2 = new pad.Point(pad.width.value/2, pad.height.value/2);
 
 var a3= new pad.Point(pad.width.value/2, pad.height.value/2 + 100);
 var b3 = new pad.Point(pad.width.value/2, pad.height.value/2);

 thisStyle = 0;

 makeShape(a3,b3);
 makeShape(a1,b1);
 makeShape(a2,b2);


 var d1Y = 300;
 var d1X = 3*pad.width.value/4 
 var d2X = pad.width.value+200;
 var d3X = pad.width.value/2;
 var dir = 1;
 var dir1 = 1;
 // pad.tagElementNames(); // create automatic nametags
 pad.update = function() {
 if(dir == 1 && d1X< =pad.width.value+200) {
 a1.setPosition(d1X+=2, d1Y);
 if (d1X>=pad.width.value+200) dir = 0;
 }
 else{
 a1.setPosition(d1X-=2, d1Y);
 if (d1X< =-200) dir = 1;
 }

 if(dir == 1 && d2X>=-200) {
 a2.setPosition(d2X-=2, d1Y);
 }
 else{
 a2.setPosition(d2X+=2, d1Y);
 }

 if(dir1 == 1 && d3X< =pad.width.value+200) {
 a3.setPosition(d3X+=2, d1Y);
 if (d3X>=pad.width.value+200) dir1 = 0;
 }
 else{
 a3.setPosition(d3X-=2, d1Y);
 if (d3X< =-200) dir1 = 1;
 }
 };

 </script>
 </script></body>
</html>

dsrusso

10 Feb 2015

//PARALLAX

drusso_lenticular

 

This gif was created via node box, which is a visual programing environment for graphics and animation.  The concepts of this animation is simple.  The gif was created specifically for the context of a lenticular image.  The gif shifts itself to directionally match the lenticular and give a parallax effect to the geometry.  The gif was created via the embedded math library in conjunction with a generated sine wave.

lent_an1

The animation is a grid of points at it’s lowest level and then projects the hair like strands from each point.  The perspective is then calculated and shifted via the change in frame.