HAHA! commit

This commit is contained in:
gauthiier 2015-03-02 08:56:44 +01:00
parent ae034bc897
commit 813a6139be
16 changed files with 13343 additions and 1 deletions

47
+++/le_style.css Normal file
View File

@ -0,0 +1,47 @@
body {
font-family: questrial, sans-serif;
font-size:0.95em;
line-height: 1.5;
color: #f7f7f7;
background-color: #1744fa;
}
a:link {color: #f7f7f7; text-decoration: underline; }
a:active {color: #f7f7f7; text-decoration: underline; }
a:visited {color: #f7f7f7; text-decoration: underline; }
content {
padding: 1.5em;
max-width: 45em;
display: block;
overflow:hidden;
text-align: justify;
margin: auto;
word-wrap: break-word;
}
content img {
text-align: center;
display: block;
margin: 0 auto;
width: 100%;
}
content #draw_canvas {
display: block;
margin: 0 auto;
width: 45em;
height: 13em;
border: 1px solid #aaaaaa;
}
.noir {
xborder: 1px solid black;
}
.rouge {
xborder: 1px solid red;
}

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
_site
.DS_Store

13
_config.yml Normal file
View File

@ -0,0 +1,13 @@
# Site settings
title: Objects & Simulations
email: d@gauthiier.info
description: Course focusing on basic concepts and techniques of object oriented programming and graphical computer simulations.
baseurl: ""
url: "http://127.0.0.1:4000" # the base hostname & protocol for your site
github_username: gauthiier
# Build settings
markdown: kramdown
# Custom Variables
#navigation: true

18
_layouts/default.html Normal file
View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Objects & Simulations</title>
<link rel="stylesheet" type="text/css" href="{{ site.url }}/+++/le_style.css" media="screen"/>
<script src="//use.edgefonts.net/questrial.js"></script>
</head>
<body>
<content>
<div id="main" class="section">
{{ content }}
</div>
</content>
</body>
</html>

40
_layouts/index.html Normal file
View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Objects & Simulations</title>
<link rel="stylesheet" type="text/css" href="{{ site.url }}/+++/le_style.css" media="screen"/>
<script src="//use.edgefonts.net/questrial.js"></script>
<script type="text/javascript" src="js/paper.js"></script>
<script type="text/javascript" src="js/paper-error.js"></script>
<script type="text/javascript" src="js/paper-agents.js"></script>
<script type="text/paperscript" canvas="draw_canvas">
for(var i = 0; i < 10; i++) {
var randomAgent = new Agent(view.center);
randomAgent.addBehaviour(new Behaviour.RandomWalk());
randomAgent.addBehaviour(new Behaviour.Trace())
var creepyAgent = new Agent(view.center);
creepyAgent.addBehaviour(new Behaviour.FollowPoint(randomAgent.position));
creepyAgent.shape.fillColor = "#f7f7f7";
}
function onFrame() {
}
</script>
</head>
<body>
<content>
<div id="main" class="section">
{{ content }}
</div>
</content>
</body>
</html>

29
_layouts/math.html Normal file
View File

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Objects & Simulations</title>
<link rel="stylesheet" type="text/css" href="{{ site.url }}/+++/le_style.css" media="screen"/>
<script src="//use.edgefonts.net/questrial.js"></script>
<!-- mathjax config similar to math.stackexchange -->
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
asciimath2jax: {
delimiters: [['$','$'], ['`','`']],
skipTags: ["script","noscript","style","textarea","pre","code"]
},
});
</script>
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=AM_HTMLorMML-full" type="text/javascript"></script>
</head>
<body>
<content>
<div id="main" class="section">
{{ content }}
</div>
</content>
</body>
</html>

4
_layouts/page.html Normal file
View File

@ -0,0 +1,4 @@
---
layout: default
---
{{ content }}

43
affine.md Normal file
View File

@ -0,0 +1,43 @@
---
layout: math
title: Environment
---
## Affine Transforms & Vector Math
<!-- ASCIImath -->
Matrix multiplication
$
[[a, b, c], [d, e, f], [g, h, i]] [[x], [y], [z]] = [[ax + by + cz], [dx + ey + fz], [gx + hy + iz]]
$
Translation
$
[[1, 0, tx], [0, 1, ty], [0, 0, 1]] [[x], [y], [1]] = [[dot x], [dot y], [1]]
$
Scaling
$
[[sx, 0, 0], [0, sy, 0], [0, 0, 1]] [[x], [y], [1]] = [[dot x], [dot y], [1]]
$
Rotation $theta$
$
[[cos theta, -sin theta, 0], [sin theta, cos theta, 0], [0, 0, 1]] [[x], [y], [1]] = [[dot x], [dot y], [1]]
$
Shearing
$
[[1, shx, 0], [shy, 1, 0], [0, 0, 1]] [[x], [y], [1]] = [[dot x], [dot y], [1]]
$
Affine Transform (Translation + Scaling + Rotation + Shearing)
$
[[sx * cos theta, -sin theta * shx, tx], [sin theta * shy, sy * cos theta, ty], [0, 0, 1]] [[x], [y], [1]] = [[dot x], [dot y], [1]]
$

BIN
img/OO-NotePad.pdf Normal file

Binary file not shown.

View File

@ -1 +0,0 @@
Objects & Simulations

81
index.md Normal file
View File

@ -0,0 +1,81 @@
---
layout: index
title: Objects & Simulations
---
#Objects & Simulations
<canvas id="draw_canvas"></canvas>
###Keywords
object-oriented programming, graphical simulation, physics, behaviour modelling
##Introduction
This class investigates the use of software as ground for design observations, explorations and artistic expression. Using software one can formally describe objects and the types of relations these objects can have with each other and their environment. Simulations can be devised to perform such relational dynamics between objects and their environment. Emergent object-environment behaviours can thus be observed which would otherwise be impossible to even predict.
This course focuses on basic concepts and techniques of object oriented programming and graphical computer simulations, that is, it introduces ways in which object oriented modelling may be used to create performative contexts where complex graphical artefacts may emerge from.
Participants will have a chance to derive a practical “hands-on” understanding of computational and graphical programming with an emphasis on object and behaviour modelling.
##Content
Five areas of exploration will be covered during this course: (1) Object-Oriented Programming, (2) Affine Transformation, (3) Oscillations, (4) Physics Simulation, and (5) (Basic) Behaviour Modelling.
Each area is composed of various small exercises where participants are expected to program computational artefacts reflecting their learning as they go along. Participants will be presented various ways of quickly and easily composing programs incorporating a mix of the above subjects, leading them to conceptualise and implement a final exploration of their own.
This course not only focuses on tools, but on how these tools can become a part of the ways participants work and think, enabling them to prototype, experiment and explore emerging ideas more quickly and more effectively using software.
##Syllabus
[Objects](objects.html)
[Environment](/)
[Simulation](/)
##Learnings Expectations
__Discourse:__
- develop an appreciation of the field of generative design.
- develop a critical view of software in regards to design practices.
- acquire basic programming and graphical vocabulary to be used in future research work.
__Skills:__
- learn how to fast prototype software-based graphical and interactive designs.
- learn how to develop expressive and interactive graphical artefacts and representations.
- learn how to develop social interactions using software.
##Evaluation Criteria
__Evaluation Criteria (course)__
The course will be a success if ...
- the students are challenged and successful in designing software based graphical prototypes.
- the mini-exercises assist students in the fabrication of presentable working prototypes.
- the final piece is explored, tested and critiqued for future development.
__Evaluation Criteria (students)__
On which basis will the students and their work be evaluated?
- development: how much the student's understanding of the field increases over the course of the workshop.
- collaboration: how much effort did the student invest into sharing skill sets and acquired knowledge with others.
- commitment: how much energy did the student invest over the course of the workshop.
##Reading List
[DeLanda, Manuel. _Philosophy and Simulation: The Emergence of Synthetic Reason_. London; New York, NY: Continuum, 2011.](http://www.amazon.com/Philosophy-Simulation-Emergence-Synthetic-Reason/dp/1441170286/ref=sr_1_1?s=books&ie=UTF8&qid=1425221232&sr=1-1&keywords=Philosophy+and+Simulation%3A)
[Baudrillard, Jean. _Simulacra and Simulation_. Ann Arbor: University of Michigan Press, 1994.](http://www.amazon.com/Simulacra-Simulation-Body-Theory-Materialism/dp/0472065211/ref=sr_1_1?s=books&ie=UTF8&qid=1425221338&sr=1-1&keywords=Simulacra+and+Simulation)
[Braitenberg, Valentino. _Vehicles: Experiments in Synthetic Psychology_. Cambridge, Mass.: MIT Press, 1986.](http://www.amazon.com/Vehicles-Experiments-Psychology-Valentino-Braitenberg/dp/0262521121/ref=sr_1_1?s=books&ie=UTF8&qid=1425221365&sr=1-1&keywords=Vehicles%3A+Experiments+in+Synthetic+Psychology)
[Gamma, Erich, ed. _Design Patterns: Elements of Reusable Object-Oriented Software_. Reading, Mass: Addison-Wesley, 1995.](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612/ref=sr_1_1?s=books&ie=UTF8&qid=1425221395&sr=1-1&keywords=Design+Patterns%3A+Elements+of+Reusable+Object-Oriented+Software)
<!-- Notes -->
<!-- Jacob von Uexkull -->
<!-- http://www.gliffy.com/uses/uml-software/ -->

280
js/paper-agents.js Normal file
View File

@ -0,0 +1,280 @@
var Point = paper.Point;
Point.prototype.scale = function(t) {
return new Point(this.x * t, this.y * t);
}
function Agent(position) {
position = position || new Point(0, 0);
Agent.list.push(this);
this.canvas = document.getElementById('draw_canvas');
this.position = position;
this.prevPosition = position.clone();
this.force = new Point();
this.shape = new paper.Path.Circle(new Point(), 10);
this.shape.position = position;
this.shape.fillColor = 'black';
this.rotation = 0;
this.behaviours = [];
if (!Agent.updateCalled) {
Agent.updateCalled = true;
Agent.update();
}
}
Agent.prototype.setPath = function(shape) {
this.shape.remove();
this.shape = shape;
}
Agent.prototype.update = function(deltaTime, frame) {
var self = this;
this.force = this.force.scale(0);
this.behaviours.forEach(function(behaviour) {
behaviour.update(self, deltaTime, frame);
});
var newPosition = this.position.add(this.force.scale(deltaTime));
if(newPosition.x > 0 && newPosition.y > 0 && newPosition.x < this.canvas.width && newPosition.y < this.canvas.height) {
this.prevPosition = this.position.clone();
this.position.x = newPosition.x;
this.position.y = newPosition.y;
this.shape.position.x = newPosition.x;
this.shape.position.y = newPosition.y;
}
}
Agent.prototype.addBehaviour = function(behaviour) {
this.behaviours.push(behaviour);
}
Agent.prototype.removeBehaviour = function(behaviour) {
var i = this.behaviours.indexOf(behaviour);
if(i > -1) {
this.behaviours.splice(i,1);
}
}
Agent.prototype.removeAllBehaviours = function() {
this.behaviours = [];
}
Agent.prototype.clone = function() {
var a = new Agent(this.position.clone());
a.behaviours = this.behaviours.map(function(b) { return b; });
a.shape = this.shape.clone();
a.prevPosition = this.position.clone();
a.position = this.position.clone();
return a;
}
Agent.list = [];
Agent.prevTime = Date.now();
Agent.frame = 0;
Agent.canvas = document.getElementById('draw_canvas');
Agent.update = function() {
if (!Agent.tool) {
Agent.mousePos = new Point(paper.view.center.x, -100)
Agent.tool = new paper.Tool();
Agent.tool.onMouseMove = function(e) {
Agent.mousePos = e.point;
}
}
var now = Date.now();
var deltaTime = (now - Agent.prevTime)/1000;
Agent.prevTime = now;
Agent.frame++;
Agent.list.forEach(function(agent) {
agent.update(deltaTime, Agent.frame);
})
window.requestAnimationFrame(Agent.update);
}
window.Agent = Agent;
window.Behaviour = Behaviour;
function Behaviour() {
this.update = function() {console.log("nothing")};
}
Behaviour.Walk = function(direction) {
direction = direction || new Point(0, -50)
this.update = function(agent, deltaTime, frame) {
agent.force = agent.force.add(direction);
}
}
Behaviour.RandomWalk = function(probabilty, angle) {
var direction = new Point(35, -35);
angle = angle || 90;
probabilty = probabilty || 0.1;
this.update = function(agent, deltaTime, frame) {
//if (frame % 30 == 0) {
if (Math.random() > 1 - probabilty) {
direction = direction.rotate(angle * Math.floor(Math.random()*3-1));
}
agent.force = agent.force.add(direction);
}
}
Behaviour.SplitWalk = function(direction, time, angle, splits, speedRatio) {
var splitTime = 0;
time = time || 2;
angle = angle || 30;
var numSplits = (typeof(splits) == 'undefined') ? 5 : splits;
speedRatio = speedRatio || 1;
this.update = function(agent, deltaTime, frame) {
if (numSplits > 0) {
agent.force = agent.force.add(direction);
splitTime += deltaTime;
if (splitTime > time) {
direction = direction.rotate(angle);
splitTime = 0;
numSplits--;
var copy = agent.clone();
for(var i=0; i<copy.behaviours.length; i++) {
if (copy.behaviours[i] == this) {
var walkClone = new Behaviour.SplitWalk(direction.rotate(-2*angle).scale(speedRatio), time, angle, numSplits)
copy.behaviours.splice(i, 1, walkClone);
break;
}
}
}
}
}
}
Behaviour.Trace = function(color, maxLength) {
maxLength = maxLength || 200;
color = color || 'black'
this.update = function(agent, deltaTime, frame) {
if (!agent.trace) {
agent.trace = new paper.Path();
agent.trace.strokeColor = color;
}
agent.trace.add(agent.position);
if (agent.trace.segments.length > maxLength) {
agent.trace.removeSegment(0)
}
}
}
Behaviour.FollowMouse = function() {
var ratio = 0.5 + 0.5 * Math.random();
this.update = function(agent, deltaTime, frame) {
agent.force = agent.force.add(Agent.mousePos.subtract(agent.position).scale(ratio));
}
}
Behaviour.Shake = function(radius, speed) {
speed = speed || 20;
var time = Math.random() * Math.PI * 2
this.update = function(agent, deltaTime, frame) {
time += deltaTime * speed;
agent.force = agent.force.add(new Point(radius * Math.sin(time), radius * Math.cos(time)));
}
}
Behaviour.FollowPoint = function(point) {
var ratio = 0.5 + 0.5 * Math.random();
this.update = function(agent, deltaTime, frame) {
agent.force = agent.force.add(point.subtract(agent.position).scale(ratio));
}
}
Behaviour.Repulse = function(radius) {
this.update = function(agent, deltaTime, frame) {
var force = new Point(0, 0);
var numNeighbours = 0;
Agent.list.forEach(function(otherAgent) {
if (agent != otherAgent) {
var dist = otherAgent.position.subtract(agent.position);
var len = dist.length;
if (len < radius) {
if (len > 0.2) {
force = force.subtract(dist.scale(radius/len));
numNeighbours++;
}
}
}
})
if (numNeighbours > 0) {
force = force.scale(1/numNeighbours);
//agent.force += force.normalize() * radius * deltaTime;
agent.force = agent.force.add(force);// * deltaTime;
}
}
}
Behaviour.RepulseMouse = function(radius) {
this.update = function(agent, deltaTime, frame) {
var force = new Point(0, 0);
var dist = Agent.mousePos.subtract(agent.position);
var len = dist.length;
if (len < radius) {
if (len > 0.2) {
force = force.subtract(dist.scale(radius/len));
}
}
agent.force = agent.force.add(force);
}
}
Behaviour.RepulsePoint = function(point, radius) {
radius = radius || 50
this.update = function(agent, deltaTime, frame) {
var force = new Point(0, 0);
var dist = point.subtract(agent.position);
var len = dist.length;
if (len < radius) {
if (len > 0.2) {
force = force.subtract(dist.scale(radius/len));
}
}
agent.force = agent.force.add(force);
}
}
Behaviour.FollowPath = function(path, loop, speed, snapRadius) {
loop = loop || false;
snapRadius = snapRadius || 10;
speed = speed || 100;
var activePointIndex = 0;
this.update = function(agent, deltaTime, frame) {
if (activePointIndex > path.segments.length - 1) {
if (loop) {
activePointIndex = 0;
}
else {
return;
}
}
var activePoint = path.segments[activePointIndex].point;
var dist = activePoint.subtract(agent.position);
//var ratio = 0.5 + 0.5 * Math.random();
agent.force = agent.force.add(activePoint.subtract(agent.position)).normalize().scale(speed);
if (dist.length < snapRadius) {
activePointIndex++;
}
}
}
Behaviour.Orient = function() {
var agentRotation = 0;
this.update = function(agent, deltaTime, frame) {
var dir = agent.position.subtract(agent.prevPosition);
if (dir.length > 0.1) {
var rotation = Math.atan2(dir.y, dir.x) * 180 / Math.PI + 90;
agent.shape.rotate(rotation - agentRotation);
agentRotation = rotation;
}
}
}

44
js/paper-error.js Normal file
View File

@ -0,0 +1,44 @@
window.addEventListener('DOMContentLoaded', function() {
var canvas = document.getElementById('draw_canvas');
if (!canvas) {
throw 'No <canvas> element found with id "draw_canvas"';
}
var scriptTags = document.getElementsByTagName('script');
var paperScriptCodeFound = false;
for(var i=0; i<scriptTags.length; i++) {
var script = scriptTags[i];
if (script.type == 'text/paperscript') {
paperScriptCodeFound = true;
}
}
if (!paperScriptCodeFound) {
throw 'No paper script code found. Did you add type="text/paperscript" to your <script> tag?';
}
if (typeof(paper) == 'undefined') {
throw 'No paper.js library found. Have you added proper script tag?';
}
})
window.onerror = function(error, url, lineNumber) {
//From http://sketch.paperjs.org/assets/js/editor.js
var columNumber = 0, match;
if (match = error.match(/(.*)\s*\((\d*):(\d*)\)/)) { // Acorn
error = match[1];
lineNumber = Number(match[2]);
columNumber = match[3];
} else if (match = error.match(/(.*)Line (\d*):\s*(.*)/i)) { // Esprima
error = match[1] + match[3];
lineNumber = Number(match[2]);
}
//Find paper script tag line number + 2 (html line and doctype line)
var html = document.body.parentNode.innerHTML;
var lines = html.split('\n');
lines.forEach(function(line, lineIndex) {
if (line.indexOf('paperscript') > 0) {
console.log(error, 'at Line', lineIndex + lineNumber + 2);
}
})
};

461
js/paper-timeline.js Normal file
View File

@ -0,0 +1,461 @@
// Timeline.js v0.1 / 2011-05-01
// A compact JavaScript animation library with a GUI timeline for fast editing.
// by Marcin Ignac (http://marcinignac.com)
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
var Timeline = function() {
this.name = "Global";
this.anims = [];
this.time = 0;
this.totalTime = 0;
this.loopCount = 0;
this.loopMode = 0;
this.playing = true;
this.verbose = false;
var self = this;
//setInterval(function() {
// self.update();
//}, 1000/30);
};
Timeline.currentInstance = null;
Timeline.getGlobalInstance = function() {
if (!Timeline.globalInstance) {
Timeline.globalInstance = new Timeline();
}
return Timeline.globalInstance;
};
Timeline.prevTime = Date.now();
Timeline.update = function() {
var now = Date.now();
delta = (now - Timeline.prevTime)/1000;
Timeline.prevTime = now;
Timeline.getGlobalInstance().update()
}
//Possible values of n:
//-1 infinite loop
//0 play forever without looping, continue increasing time even after last animation
//1 play once and stop at the time the last animation finishes
//>1 loop n-times
Timeline.prototype.loop = function(n) {
this.loopMode = n;
};
Timeline.prototype.stop = function() {
this.playing = false;
this.time = 0;
this.prevTime = this.time - 1/30; //FIXME 1/30
};
Timeline.prototype.pause = function() {
this.playing = false;
};
Timeline.prototype.play = function() {
this.playing = true;
};
Timeline.prototype.preUpdate = function() {
//placeholder for hooks like GUI rendering
};
Timeline.prototype.update = function(deltaTime) {
deltaTime = deltaTime || 1/30;
this.preUpdate();
if (this.playing) {
this.totalTime += deltaTime;
this.prevTime = this.time;
this.time += deltaTime;
}
if (this.loopMode !== 0) {
var animationEnd = this.findAnimationEnd();
if (this.time > animationEnd) {
this.loopCount++;
this.time = 0;
for(var i=0; i<this.anims.length; i++) {
this.anims[i].hasStarted = false;
}
}
if (this.loopMode == -1) {
//loop infinitely
for(var i=0; i<this.anims.length; i++) {
this.anims[i].hasStarted = false;
}
}
else {
if (this.loopCount >= this.loopMode) {
this.playing = false;
}
}
}
this.applyValues();
};
Timeline.prototype.findAnimationEnd = function() {
var endTime = 0;
for(var i=0; i<this.anims.length; i++) {
if (this.anims[i].endTime > endTime) {
endTime = this.anims[i].endTime;
}
}
return endTime;
};
Timeline.prototype.getValue = function(obj, name) {
if (name == 'rotation') {
if (typeof(obj._timelineRotation) == 'undefined') {
obj._timelineRotation = obj.rotation || 0;
}
return obj._timelineRotation;
}
else if (name == 'scale') {
if (typeof(obj._timelineScale) == 'undefined') {
obj._timelineScale = 1;
}
return obj._timelineScale;
}
else {
return obj[name];
}
}
Timeline.prototype.setValue = function(obj, name, value) {
if (name == 'rotation') {
obj.rotate(value - obj._timelineRotation);
obj._timelineRotation = value;
}
else if (name == 'scale') {
obj.scale(value/obj._timelineScale)
obj._timelineScale = value;
}
else {
obj[name] = value;
}
}
Timeline.prototype.applyValues = function() {
for(var i=0; i<this.anims.length; i++) {
var propertyAnim = this.anims[i];
if (this.time < propertyAnim.startTime) {
continue;
}
if (this.time >= propertyAnim.startTime && !propertyAnim.hasStarted) {
propertyAnim.startValue = this.getValue(propertyAnim.target, propertyAnim.propertyName)
propertyAnim.hasStarted = true;
propertyAnim.onStart();
}
var t = (this.time - propertyAnim.startTime)/(propertyAnim.endTime - propertyAnim.startTime);
t = Math.max(0, Math.min(t, 1));
t = propertyAnim.easing(t);
var value = propertyAnim.startValue + (propertyAnim.endValue - propertyAnim.startValue) * t;
this.setValue(propertyAnim.target, propertyAnim.propertyName, value);
if (propertyAnim.parent.onUpdateCallback) {
propertyAnim.parent.onUpdateCallback(propertyAnim);
}
if (this.time >= propertyAnim.endTime && !propertyAnim.hasEnded) {
propertyAnim.hasEnded = true;
propertyAnim.onEnd();
}
if (t == 1) {
if (this.loopMode == 0) {
this.anims.splice(i, 1);
i--;
}
}
}
};
//--------------------------------------------------------------------
Timeline.Anim = function(name, target, timeline) {
this.startTime = 0;
this.endTime = 0;
this.time = 0;
this.propertyAnims = [];
this.hasStarted = false;
this.hasEnded = false;
this.onStartCallbackCalled = false;
this.onEndCallbackCalled = false;
this.onUpdateCallbackCalled = false;
this.name = name;
this.target = target;
this.timeline = timeline;
this.animGroups = [];
}
//delay, properties, duration, easing
Timeline.Anim.prototype.to = function() {
var args = [];
for(var i=0; i<arguments.length; i++) {
args.push(arguments[i]);
}
var delay;
var properties;
var duration;
var easing;
if (typeof(args[0]) == "number") {
delay = args.shift();
}
else {
delay = 0;
}
if (typeof(args[0]) == "object") {
properties = args.shift();
}
else {
properties = {};
}
if (typeof(args[0]) == "number") {
duration = args.shift();
}
else {
duration = 1;
}
if (typeof(args[0]) == "function") {
easing = args.shift();
}
else {
easing = Timeline.Easing.Linear.EaseNone;
}
var animGroup = [];
var nop = function() {}
for(var propertyName in properties) {
var animInfo = {
hasStarted: false,
timeline: this.timeline,
targetName: this.name,
target: this.target,
propertyName: propertyName,
endValue: properties[propertyName],
delay: delay,
startTime: this.timeline.time + delay + this.endTime,
endTime: this.timeline.time + delay + this.endTime + duration,
easing: easing,
parent: this,
onStart: nop,
onEnd: nop
};
this.timeline.anims.push(animInfo);
animGroup.push(animInfo);
}
this.animGroups.push(animGroup);
this.endTime += delay + duration;
return this;
};
Timeline.Anim.prototype.onStart = function(callback) {
var currentAnimGroup = this.animGroups[this.animGroups.length-1];
if (!currentAnimGroup) return;
var called = false;
currentAnimGroup.forEach(function(anim) {
anim.onStart = function() {
if (!called) {
called = true;
callback();
}
}
})
return this;
}
Timeline.Anim.prototype.onUpdate = function(callback) {
var self = this;
this.onUpdateCallback = function() {
callback();
};
return this;
}
Timeline.Anim.prototype.onEnd = function(callback) {
var currentAnimGroup = this.animGroups[this.animGroups.length-1];
if (!currentAnimGroup) return;
var called = false;
currentAnimGroup.forEach(function(anim) {
anim.onEnd = function() {
if (!called) {
called = true;
callback();
}
}
})
return this;
}
Timeline.anim = function(targetName, targetObject, parentTimeline) {
var args = [];
for(var i=0; i<arguments.length; i++) {
args.push(arguments[i]);
}
var name;
var target;
var timeline;
if (typeof(args[0]) == "string") {
name = args.shift();
}
if (typeof(args[0]) == "object") {
target = args.shift();
}
else {
target = {};
}
if (typeof(args[0]) == "object") {
timeline = args.shift();
}
else {
timeline = Timeline.getGlobalInstance();
}
return new Timeline.Anim(name, target, timeline);
}
//--------------------------------------------------------------------
Timeline.Easing = { Linear: {}, Quadratic: {}, Cubic: {}, Quartic: {}, Quintic: {}, Sinusoidal: {}, Exponential: {}, Circular: {}, Elastic: {}, Back: {}, Bounce: {} };
Timeline.Easing.Linear.EaseNone = function ( k ) {
return k;
};
Timeline.Easing.Quadratic.EaseIn = function ( k ) {
return k * k;
};
Timeline.Easing.Quadratic.EaseOut = function ( k ) {
return - k * ( k - 2 );
};
Timeline.Easing.Quadratic.EaseInOut = function ( k ) {
if ( ( k *= 2 ) < 1 ) return 0.5 * k * k;
return - 0.5 * ( --k * ( k - 2 ) - 1 );
};
Timeline.Easing.Cubic.EaseIn = function ( k ) {
return k * k * k;
};
Timeline.Easing.Cubic.EaseOut = function ( k ) {
return --k * k * k + 1;
};
Timeline.Easing.Cubic.EaseInOut = function ( k ) {
if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k;
return 0.5 * ( ( k -= 2 ) * k * k + 2 );
};
Timeline.Easing.Elastic.EaseIn = function( k ) {
var s, a = 0.1, p = 0.4;
if ( k === 0 ) return 0; if ( k == 1 ) return 1; if ( !p ) p = 0.3;
if ( !a || a < 1 ) { a = 1; s = p / 4; }
else s = p / ( 2 * Math.PI ) * Math.asin( 1 / a );
return - ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) );
};
Timeline.Easing.Elastic.EaseOut = function( k ) {
var s, a = 0.1, p = 0.4;
if ( k === 0 ) return 0; if ( k == 1 ) return 1; if ( !p ) p = 0.3;
if ( !a || a < 1 ) { a = 1; s = p / 4; }
else s = p / ( 2 * Math.PI ) * Math.asin( 1 / a );
return ( a * Math.pow( 2, - 10 * k) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) + 1 );
};
Timeline.Easing.Elastic.EaseInOut = function( k ) {
var s, a = 0.1, p = 0.4;
if ( k === 0 ) return 0; if ( k == 1 ) return 1; if ( !p ) p = 0.3;
if ( !a || a < 1 ) { a = 1; s = p / 4; }
else s = p / ( 2 * Math.PI ) * Math.asin( 1 / a );
if ( ( k *= 2 ) < 1 ) return - 0.5 * ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) );
return a * Math.pow( 2, -10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) * 0.5 + 1;
};
Timeline.Easing.Back.EaseIn = function( k ) {
var s = 1.70158;
return k * k * ( ( s + 1 ) * k - s );
};
Timeline.Easing.Back.EaseOut = function( k ) {
var s = 1.70158;
return ( k = k - 1 ) * k * ( ( s + 1 ) * k + s ) + 1;
};
Timeline.Easing.Back.EaseInOut = function( k ) {
var s = 1.70158 * 1.525;
if ( ( k *= 2 ) < 1 ) return 0.5 * ( k * k * ( ( s + 1 ) * k - s ) );
return 0.5 * ( ( k -= 2 ) * k * ( ( s + 1 ) * k + s ) + 2 );
};
Timeline.Easing.Bounce.EaseIn = function( k ) {
return 1 - Timeline.Easing.Bounce.EaseOut( 1 - k );
};
Timeline.Easing.Bounce.EaseOut = function( k ) {
if ( ( k /= 1 ) < ( 1 / 2.75 ) ) {
return 7.5625 * k * k;
} else if ( k < ( 2 / 2.75 ) ) {
return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;
} else if ( k < ( 2.5 / 2.75 ) ) {
return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;
} else {
return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;
}
};
Timeline.Easing.Bounce.EaseInOut = function( k ) {
if ( k < 0.5 ) return Timeline.Easing.Bounce.EaseIn( k * 2 ) * 0.5;
return Timeline.Easing.Bounce.EaseOut( k * 2 - 1 ) * 0.5 + 0.5;
};
Timeline.easingFunctionToString = function( f ) {
for(var name in Timeline.easingMap) {
if (Timeline.easingMap[name] == f) {
return name;
}
}
};
Timeline.stringToEasingFunction = function( name ) {
return Timeline.easingMap[name];
};
Timeline.easingMap = {
};
for(var easingFunctionFamilyName in Timeline.Easing) {
var easingFunctionFamily = Timeline.Easing[easingFunctionFamilyName];
for(var easingFunctionName in easingFunctionFamily) {
Timeline.easingMap[easingFunctionFamilyName + "." + easingFunctionName] = easingFunctionFamily[easingFunctionName];
}
}

12219
js/paper.js Normal file

File diff suppressed because one or more lines are too long

62
objects.md Normal file
View File

@ -0,0 +1,62 @@
---
layout: default
title: Objects
---
# Objects
![Systema Naturæ](http://de.academic.ru/pictures/dewiki/83/SN1_Regnum_Lapideum.png)
[Linnæan Taxonomy](https://en.wikipedia.org/wiki/Linnaean_taxonomy)
### Object Oriented Programming I: Class and Objects
#### A. [OO-NotePad](img/OO-NotePad.pdf)
Using the _OO-NotePad_ sheet, observe four (4) objects in your surrounding and formally describe them usign the following descriptors:
1. Name of the object
2. Visual diagram / representation
3. List of Attributes
+ Static -- an attribute that does not change (much) over time
+ Dynamic -- an attribute that changes aspect over time
Questions:
1. Is there an atribute that is common to all (or some) of your objects?
2. Do you see any familiarity between your objects?
3. Is there any hierarchical realtionship(s) that could be devise between your objects?
#### B. OO Modeling
Following your OO obervations, formalise your (paper) descriptions using the **U**nified **M**odeling **L**anguage (UML)
- [online UML editor](http://www.gliffy.com/uses/uml-software/) (note: please take screen shots of your UML design)
Questions:
1. Do you think the UML translates well your observation?
2. Do you understand the difference between UML's attribute and method?
3. Is your UML diagram readable?
#### C. OO Programming
Now that you have created a simple UML diagram of your objects, translate this diagram into code using a _class_.
class Name {
...
};
Questions:
1. How does your class relate to your UML diagram?
2. How does your class relate to your paper observation?
3. Was it easy to translate your UML diagram into code? What was ambiguous? What was not?
3. Is your class readable?
### Object Oriented Programming II: Polymorphism and Inheritance