text:
# Attack, Decay, Sustain, Release

Sound synthesizers use envelope generators to control how certain parameters of the sound (such as overall loudness) change with time. In many synthesizers an envelope is defined by four parameters, as represented in the following figure from Wikipedia:

• Attack time (A): time taken for the envelope to reach its maximum level, starting from zero, when the key is first pressed.
• Decay time (D): time taken for the envelope to reach the specified sustain level.
• Sustain level (S): level which is maintained, after the initial attack and decay, for as long as the key is being pressed.
• Release time (R): time taken for the envelope to reach zero when the key is released.

# The challenge

Input the four parameters A, D, S, R and plot the envelope.

Parameters will be integer values from 0 to 127.

The maximum level (reached at the end of the attack phase) will be assumed to be 127.

The horizontal segment at the sustain level will be assumed to have duration 64 (in the actual sound this duration is not fixed, but is determined by the amount of time that the key is held).

# Format and further details

The output should be an image in raster or vector format. If it's raster, the polygonal line should occupy at least 50 pixels vertically an horizontally.

The image can be either displayed or produced as a file in a standard image format. The file can be written to disk, or its exact contents can be output, either to STDERR or as function return argument.

The graph need only contain the polygonal line that defines the envelope. The scale of each axis can be freely chosen. Other elements such as axis lines, numeric labels or line colors are optional.

Input means and format are flexible as usual. For example, you can take the four numbers in any order, or an array containing them. A program or a function can be provided. Standard loopholes are forbidden.

Shortest code in bytes wins.

# Test cases

Input is in the format [A D S R]. Note that the scale is different in each figure (in accordance with the rule that scale can be freely chosen)

[15 30 70 40]

[64 64 64 64]

[0 10 50 80]

[0 0 90 80]

[5 50 0 0]

[5 50 0 80]

[24 32 127 48]

# MATL, 31 22 bytes

Oii64ivYsO127itO5$h&XG  Accepts four separate inputs ordered as A, D, R, S Try it out at MATL Online Explanation 0 % Push a literal 0 to the stack ii % Grab the first two inputs 64 % Push the number literal 64 to the stack i % Grab the third input v % Vertically concatenate all values Ys % Compute the cumulative sum 0 % Push the number literal 0 to the stack 127 % Push the number literal 127 to the stack i % Grab the fourth input t % Duplicate the fourth input O % Push the number literal 0 to the stack 5$h % Concatenate the last 5 elements on the stack
&XG % Plot the result using the first array as x and second array as y

# TikZ, 195193181177172167163160 159 bytes

\documentclass[tikz]{standalone}\begin{document}\tikz\def~#1{\typein[#1];}~\a~\s~\d~\r\def\u{)--(\a+\d}\draw(,)--(\a,127\u,\s\u+64,\s\u+\r+64,);\end{document}

Yes, you heard right TikZ.

## Explanation

This uses a couple of techniques to achieve its goal. The first thing is input. Most people might not know that LATEX can take input. Well it can. This is achieved with the command \typein. This will halt the compiler and request input from the user as assign it to a variable.

The other main technique is the use of \def. \def in Tikz is absurdly powerful. It essentially defines a piece of code and pastes it everywhere you call the variable. In this code we define two things \typein[#1]{} so that we can assign our variables golfily and )--(\a+\d because this code shows up a bunch of times in the ungolfed version.

Here are two versions of the code (without the wrapper):

### Golfed:

\documentclass[tikz]{standalone}\begin{document}\tikz\def~#1{\typein[#1];}~\a~\s~\d~\r\def\u{)--(\a+\d}\draw(,)--(\a,127\u,\s\u+64,\s\u+\r+64,);\end{document}

### Ungolfed:

\typein[\a]{}\typein[\s]{}\typein[\d]{}\typein[\r]{}\draw(0,0)--(\a,127)--(\a+\d,)--(\a+\d+64,)--(\a+\d+\r+64,0);

## Image:

Since I cannot upload a pdf image directly, and converting it to any other format seems to cause the line to disappear altogether, here is what an image might look like when opened in Preview (input for this image is [64 64 64 64]):

As you can see it is very thin. However because it is a PDF image and not a raster image does not have to comply with thickness requirements.

• I sincerely admire the fact that you know TikZ so well that it's the first solution that comes into your mind. (And if it wasn't, that's what legend will remember) – Right Leg Feb 15 '17 at 2:05
• Doesn't input tikz\begin{document} work? – Fatalize Feb 15 '17 at 7:50
• how about pictures? 😉 – Display Name Feb 15 '17 at 12:25
• How do you actually render this? pdflatex adsr.tex doesn't seem to work. — Oh wait, it does work, I just didn't expect it would request interactive input! – ceased to turn counterclockwis Feb 15 '17 at 12:52
• @WheatWizard imagemagick can convert PDF reasonably well if you do it right – Display Name Feb 15 '17 at 15:24

# Python 2, 8380 79 bytes

from turtle import*
def f(A,D,S,R):X=A+D+64;map(goto,[A,A+D,X,X+R],[127,S,S,0])

Try it online (83-byte version, because it runs online)

Note that certain outputs may not be completely visible using Trinket, because of the way the canvas works. You'll need to download and install Python if you want it to work better.

### Ungolfed:

from turtle import*
A,D,S,R=input()
goto(A,127)
goto(A+D,S)
goto(A+D+64,S)
goto(A+D+64+R,0)

This version doesn't work in Trinket, because Trinket doesn't support value unpacking of input.

• You can use map in Python 2: lambda A,D,S,R:map(goto,[A,A+D,A+D+64,A+D+R+64],[127,S,S,0]) – xnor Feb 14 '17 at 18:19
• @xnor I get SuspensionError: Cannot call a function that blocks or suspends here on line undefined in main.py on Trinket. Have you confirmed that it works? I'm not sure if the error is unique to Trinket or not. – mbomb007 Feb 14 '17 at 19:06
• Works for me in 2.7.12. – xnor Feb 14 '17 at 19:11
• @xnor Mmk, thanks. It's probably a limitation in Skulpt. – mbomb007 Feb 14 '17 at 19:12
• I submitted a simpler version of this program as an example to the Skulpt github repo, and they thought it was a nice find. Hopefully they'll be able to fix it, but the pace of their "turtle sprint" seems to be more of a walk. – mbomb007 Feb 16 '17 at 17:15

## Mathematica, 61 58 bytes

ListLinePlot[{Accumulate@{0,##3,64,#2},{0,127,#,#,0}}]&

 is the operator for Transpose and is rendered as a superscript T by Mathematica.

Takes the arguments in the order S, R, A, D and returns a vector graphics object.

Results for all seven test cases:

Click for larger version.

• That was quick! – Luis Mendo Feb 14 '17 at 15:45
• +1 for teaching me ListLinePlot :) And there's a ListStepPlot as well—so useful! – Greg Martin Feb 14 '17 at 18:46

## R, 66 63 bytes

function(A,D,S,R)plot(cumsum(c(0,A,D,64,R)),c(0,127,S,S,0),"l")

Displays the image, with axis labs being cumsum(c(0,A,D,64,R)) and c(0,127,S,S,0), as well axis lines and numeric labels.

Thanks to @Zahiro Mor for shaving off 3 bytes !

function(A,D,S,R)plot(c(0,A,A+D,b<-A+D+64,b+R),c(0,127,S,S,0),"l")

• you can use cumsum(c(0,A,D,64,R)) to replace the first term in the plot. with cumsum you will not need the b trick and still shave 3 bytes :) function(A,D,S,R)plot(cumsum(c(0,A,D,64,R)),c(0,127,S,S,0),"l") – Zahiro Mor Feb 15 '17 at 16:46

# Matlab, 50 bytes

@(A,D,S,R)plot(cumsum([0,A,D,64,R]),[0,127,S,S,0])

This yields an anonymous function "ans" that has to be called as ans(A,D,S,R).

## JavaScript (ES6) + HTML, 126 + 23 = 149

c=O.getContext2d;c.moveTo(a=0,z=O.height=128);g=(y,x=prompt())=>c.lineTo(a+=+x,y)||g;g(0)(s=z+~prompt())(s,64)(z);c.stroke()
<canvas id=O width=512>

Takes input one at a time in the order A, S, D, R.

## JavaScript (ES6), 114 111 bytes

f=(a,d,s,r)=><svg width=446 height=128><path stroke=red fill=none d=M0,127L${a},0l${d},${127-s}h64l${r},${s}>
<input type=number value=0 min=0 max=127 id=a><input type=number value=63 min=0 max=127 id=d><input type=number value=127 min=0 max=127 id=s><input type=number value=0 min=0 max=127 id=r>
<svg width=446 height=128><path stroke=red fill=none d=M0,127L0,0l63,0h64l0,127 /></svg> Returns an SVG image suitable for innerHTML. Add 18 bytes for valid XML. • It's great how the figure is updated in real time! – Luis Mendo Feb 15 '17 at 10:41 • This is great, I should learn SVG syntax sometime. Perhaps add default values to the <input>s? – ETHproductions Feb 15 '17 at 20:54 • @ETHproductions Did you have any particular defaults in mind? (Given that setting defaults won't actually trigger the initial graph anyway...) – Neil Feb 15 '17 at 20:59 • I was thinking perhaps just 64,64,64,64. Normally I'd hardcode the correct output for the default input, but I see how that would be difficult here... – ETHproductions Feb 15 '17 at 21:16 ## Haskell, 112 110 bytes import Graphics.Gloss (a#d)s r=display(InWindow""(600,300)(0,0))red$line$zip(scanl(+)0[a,d,64,r])[0,127,s,s,0]  Usage example: (0#10) 50 80. This uses the Gloss library. The display function expects a window to plot in (here: a window without title (""), size 600x300, position (0,0) on desktop), a background color (red) and picture witch is a line along the path made by zipping the cumulative sum of [0,a,d,64,r] = [0,a,a+d,a+d+64,a+d+64+r] as the x coordinates and [0,127,s,s,0] as the y coordinates. Edit: Thanks @xnor for 2 bytes! • Should be shorter to write scanl(+)0[a,d,64,r] – xnor Feb 14 '17 at 19:23 # Processing, 134 108 + 14(call to size) = 148 122 bytes First we need a call to size somewhere in the program so that the output will fit in the window (default at 100x100). size(400,400);  And here's the actual function: void g(int a,int b,int c,int d){line(0,127,a,0);line(a,0,b+=a,c=127-c);line(b,c,b+=64,c);line(b,c,b+d,127);}  Call it like f(15,20,70,40); ### Screenshot 15, 20, 70, 40  My newer answer is more straightforward than the older answer, but I like the older one more (even if it is bigger). ### Old answer (148 bytes) size(400,400);  and the two functions void f(int[]v){translate(0,127);l(v[0],-127);l(v[1],127-v[2]);l(64,0);l(v[3],v[2]);}void l(int x,int y){line(0,0,x,y);translate(x,y);}  Call it like f(int_array_containing_values); and the result will look something like: f(new int[]{15,20,70,40}); # SmileBASIC, 90 bytes INPUT A,D,S,R B=A+D+64W=#Y-S GLINE.,#Y,A,0GLINE A,0,A+D,W GLINE A+D,W,B,W GLINE B,W,B+R,#Y  # PHP, 149 130 bytes [,$a,$d,$s,$r]=$argv;imagepolygon($i=imagecreatetruecolor(446,127),[0,127,$a,0,$d+=$a,$s,$d+=64,$s,$d+$r,127],5,999);imagepng($i);

takes input from command line arguments, writes image (PNG with graph blue on black) to stdout. Requires PHP 7.1 or later.

usage e.g.

# any OS with ImageMagick:
php -r '' <parameters> | display

# linux with feh:
php -r '' <parameters> | feh

+4 bytes for older PHP: Replace [,$a,$d,$s,$r] with list(,$a,$d,$s,$r).

There is a small hack in there: instead of using imageopenpolygon to hide the base line, the finishing polygon line is drawn outside the canvas. (y=127 would only display on an image with height >= 128.)

I could have saved more with color 99 or 9 instead of 999; but those are pretty hard to see on black. :)

## Bash + grace, 70 bytes

t=$[$1+$2] echo "0 0$1 127
$t$3
$[t+64]$3
$[t+64+$4] 0">f
xmgrace f

The script writes to file f the coordinates of each point, and xmgrace (the GUI version) reads the file and displays the plot using lines by default.

Run:

./plot_ADSR.sh 15 30 70 40

Output: (print screen)

I think this can be done directly by a grace script, if it can accept input, but I'm not familiar with its syntax. I'll look into it.

Explanation:

t=$[$1+$2] # store the value of (A+D) for later usage echo "0 0 # start writing the coordinates to file "f", first the origin$1 127              # then (A, 127)
$t$3               # then (A + D, S)
$[t+64]$3          # then (A + D + 64, S)
$[t+64+$4] 0">f     # then (A + D + 64 + R, 0)
xmgrace f           # call xmgrace to plot the generated XY file

## Go, 947915 506 bytes

This is far from optimized, trying to learn the language while participating in these questions. Feel free to point out what I can do.

Condensed:

package main;import (."os";."image";k"image/png";c"image/color";."strconv";."math");func main(){g:=NewRGBA(Rect(0,0,127*4,127));a,_:=ParseFloat(Args[1],4);d,_:=ParseFloat(Args[2],4);s,_:=ParseFloat(Args[3],4);r,_:=ParseFloat(Args[4],4);z:=[5][]float64{{0,0},{a,127},{a+d,s},{a+d+64,s},{a+d+64+r,0}};for i:=1;i<len(z);i++{v,w,x,y:=z[i-1][0],z[i-1][1],z[i][0],z[i][1];m:=(y-w)/(x-v);t:=y-m*x;for v<=x{g.Set(int(Ceil(v)),127-int(Ceil(w)),c.RGBA{0,0,0,255});v+=.01;w=m*v+t}};f,_:=Create("o.png");k.Encode(f,g)}

Uncondenced:

package main

import (
."os"
."image"
k"image/png"
c"image/color"
."strconv"
."math"
"fmt"
)

func main(){
g := NewRGBA(Rect(0, 0, 127*4, 127))

a, _ := ParseFloat(Args[1], 4)
d, _ := ParseFloat(Args[2], 4)
s, _ := ParseFloat(Args[3], 4)
r, _ := ParseFloat(Args[4], 4)

z := [5][]float64{{0,0},{a,127},{a+d,s},{a+d+64,s},{a+d+64+r,0}}
for i:=1;i<len(z);i++{
v,w,x,y:=z[i-1][0],z[i-1][1],z[i][0],z[i][1]
m:=(y-w)/(x-v)
t:=y-m*x
for v<=x{
g.Set(int(Ceil(v)),127-int(Ceil(w)), c.RGBA{0,0,0,255})
v+=.01
w=m*v+t
}
}
f,_:=Create("o.png")
k.Encode(f,g)
}

• @LuisMendo it is. By default 0,0 is top left. Ill inverse everything as soon as I can. – kemicofa ghost Feb 16 '17 at 18:04
• I never coded in go, so I don't know. Users here golf their code manually because they can save more bytes than a general minifier. Bad coding practices and tricks are welcomed here. For ex, wouldn't replacing struct objects with variables (like l1x, l1y, l1X, l1Y) be golfier perhaps? – seshoumara Feb 17 '17 at 11:40
• @rugdealer This may help, in case you haven't seen it – Luis Mendo Feb 17 '17 at 14:37
• Lost almost 400 bytes thanks to your link @LuisMendo – kemicofa ghost Feb 17 '17 at 15:56
• @rugdealer Wow, that's a lot \o/ – Luis Mendo Feb 17 '17 at 16:11

## dc, 120 bytes

Initially I thought I can't answer in dc, but I see that printing the syntax of a vector image is allowed.

?sR127r-sS[<svg><path d="M0 127 L]nrdn[ 0 L]n+dn32PlSn[ L]n64+dn32PlSn[ L]nlR+n[ 127" fill="none" stroke="red"/></svg>]p

The code calculates the translated coordinates of each point and generates the SVG syntax for the plot. Since an image editor has the origin at the top-left corner, I had to subtract the y values from height, 127 in this case, so that the image is shown as if the origin is at the bottom-left corner.

Run example: or Try it Online!

dc -f plot_ADSR.dc <<< "15 30 70 40"

Output:

<svg><path d="M0 127 L15 0 L45 57 L109 57 L149 127" fill="none" stroke="red"/></svg>

To display the image plot, save that exact output to a file and open it with Gimp, for example, or enter the text in an html page as I did above.

Explanation: dc is a reverse-polish desk calculator stack language

The script is a long concatenation of the SVG syntax string. The keyword M stands for move to coordinate and L stands for draw line from current position to given coordinate.

?                           # read input (in reverse order by default). Stack: RSDA
sR                          # pop top value, store it in register 'R'. Stack: SDA
127r-sS                     # push 127, swap top 2 values, pop them and push
#subtracting result, save it to 'S', pop it. Stack: DA
[<svg><path d="M0 127 L]n   # [..]n print string (push then pop). Stack: unchanged
rdn                         # swap, duplicate top, print (A) and pop it. Stack: AD
[ 0 L]n                     # printing
+dn                         # pop top 2 values, push addition result, duplicate it,
#print and pop it. Stack: (A+D)
32P                         # print a space
lSn                         # push value from register 'S', print and pop it.
#Stack: unchanged
[ L]n                       # printing
64+dn                       # push 64, pop top 2 values, push addition result,
#duplicate it, print and pop it. Stack: (A+D+64)
32PlSn[ L]n                 # print space, print register 'S', more printing
lR+n                        #push value from register 'R', pop top 2 values, push
#addition result, print it and pop it. Stack: empty
[ 127" fill="none" stroke="red"/></svg>]p   # printing

# Processing, 111 bytes

size(400,128);line(0,127,a,0),line(a,0,a+d,127-s),line(a+d,127-s,a+d+64,127-s),line(a+d+64,127-s,a+d+64+r,127);

Used a simpler method of input compared to user41805.

## Output (formatted)

0,0,90,80

0,10,50,80

5,50,0,0

5,50,0,80

15,30,70,40

24,32,127,48

64,64,64,64

## Ungolfed code with formatting

void settings() {
size(a+d+64+r, 129);
}
void setup() {
translate(1,0);
background(255);
strokeWeight(3);

//axes
line(0,127,600,127);
line(0,0,0,127);

//graph
stroke(53,113,9);
line(0,127,a,0);
stroke(228,77,40);
line(a,0,a+d,127-s);
stroke(26,39,232);
line(a+d,127-s,a+d+64,127-s);
stroke(110,27,109);
line(a+d+64,127-s,a+d+64+r,127);

//save to file
save("a"+a+"d"+d+"s"+s+"r"+r+".png");
}
int a=24,d=32,s=127,r=48;

This program will save your images to disk in the same folder.


text:
### WOTS+ -- Shorter Signatures for Hash-Based Signature Schemes

Andreas Hülsing

##### Abstract

We present WOTS+, a Winternitz type one-time signature scheme (WOTS). We prove that WOTS+ is strongly unforgeable under chosen message attacks in the standard model. Our proof is exact and tight. The first property allows us to compute the security of the scheme for given parameters. The second property allows for shorter signatures than previous proposals without lowering the security. This improvement in signature size directly carries over to all recent hash-based signature schemes. I.e. we can reduce the signature size by more than 50% for XMSS+ at a security level of 80 bits. As the main drawback of hash-based signature schemes is assumed to be the signature size, this is a further step in making hash-based signatures practical.

Available format(s)
Category
Public-key cryptography
Publication info
Published elsewhere. MINOR revision.AFRICACRYPT 2013
DOI
10.1007/978-3-642-38553-7
Keywords
digital signaturesone-time signature schemeshash-based signaturesprovable securityhash functions
Contact author(s)
andreas @ huelsing net
History
Short URL
https://ia.cr/2017/965

CC BY

BibTeX

@misc{cryptoeprint:2017/965,
author = {Andreas Hülsing},
title = {WOTS+ -- Shorter Signatures for Hash-Based Signature Schemes},
howpublished = {Cryptology ePrint Archive, Paper 2017/965},
year = {2017},
doi = {10.1007/978-3-642-38553-7},
note = {\url{https://eprint.iacr.org/2017/965}},
url = {https://eprint.iacr.org/2017/965}
}

Note: In order to protect the privacy of readers, eprint.iacr.org does not use cookies or embedded third party content.

format: plain


text:
# Sprite is getting out of screen when changing resolution - Unity

Hello I am making this layout:

I used sprites for birds but used UI for the blue food thrower. I used UI for it so it will not get cut when screen resolution changes. But I also need to add food itself which I need to make 2D to interact with birds. Now It is not visible over UI, So I changes Canvas-Render Mode to world space. But I cannot adjust text in that mode. Its not visible. Then I tried converting the food thrower to Sprite but it get cut. Any authentic and cleaner way to do it?


text:
# [java] Check my understanding...

This topic is 4944 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

##### Share on other sites
from my what i have seen in programming (2 CPP classes, 1 java class) if you have more than one of the same type of object (multiple orcs or bullets) the easiest way to program them is to have one set class for that type and then have an array of them. This makes the code a lot nicers than having orc1, orc2, orc3. Yes you would have something like Entity.bullets.fireball in Java just remember that inorder to have it you yourself must program it

##### Share on other sites
Quote:
 am going to go ahead and say that from what I have seen, LWJGL seems to be the closest to what I think my needs are. However, one thing is bothering me about the LWJGL things that I have seen. It appears that the LWJGL game programmers almost strictly do not use Java's objects during their main loops. In fact, all of the tutorial material I saw seemed to have a particularly annoying limitation. What I need to know is do I have my head on straight about this.

Well have you looked at full code for any real LWJGL games ? Small demos and examples don't count, of course they will put everything into a single source file just for ease of learning. Personally my LWJGL engine, which is currently interfacing with the TrueAxis physics engine is mostly object-oriented. I have an EntityManager, with respective StaticEntity, DynamicEntity classes. From a file I will load positions/orientations of all the objects in my scene and create a DynamicEntity for each, as well as creating a StaticEntity for the "world" geometry. Then I add these all to my EntityManager singleton, which is really just a wrapper around (not an array *gasp*!) a LinkedList. With a LL you get cheap adds, cheap iteration+ (semi-)cheap deletes, and NO resizing.

Is this the kind of object-oriented system you think LWJGL is forbidden from? it certainly works quite well for me.

The thing is, LWJGL is made to be as small, fast, and portable as possible. For this reason it doesn't have a huge codebase with a bunch of OOP mumbojumbo. Basically, it is up to you to come up with a clever scheme of scene management.

I think maybe a large part of the phobia of objects is the garbage-collecting system. Most people think that they should avoid at all costs ever calling "new" during your game loop. The problem is that people that get locked into these coding styles for "performance" are actually getting more and more outsmarted by each new JVM.

##### Share on other sites
Yes, I understand that, but the problem with Arrays is that they are fixed. Unless I am totally missing something, you can't change the number of objects involved very easily. For example, suppose you are using a Roguelike type of game. You want to have random level generation (you know, one of those things where it runs one of those dungeon tunnelers to hollow out a bunch of rooms, and then populates them with Slimes and Torches and crap.) In that environment, just as an example, it is very difficult to put a cap on the number of things you'll want to have. How many Orcs is enough? 50, 100, 250? Also, wouldn't the memory be occupied regardless? I am not trying to be an http://www.gamedev.net/community/forums/topic.asp?topic_id=326558, but I am ready to move on to games just a bit more complex than Space Invaders.

I'll lay it out on the table. I have successfully made a playable (althought I must confess I never polished it) Tetris, space invaders, asteroids kind of stuff. I really can't learn too much else that way. My next step is more complex 2D single player fare. Not talking Civilizations or anything like that, nothing with an advanced AI yet. I am thinking of trying to write a platformer, and then after that I would like to attempt to make a 2D graphical Roguelike. So while I am being slightly ambitious, this is nothing completely insane here. And for the record, I will probably re-write Tetris and such in Java before moving on to anything more complex. I realize people with huge, noobish visions are a dime a dozen, I just wanted to make sure I was clear that I have a HUGE sense of reality going on here, I am only one person, and a n00b at that.

Here, let me just show you some vaguepseudocode for what I mean by dynamic.

Main loop start
{
do that timing thingie to see how much time has passed
run as many game logic loops as necessary(based on timer millisecs)
run one screen flip
{
process various game logic, see if input keys were hit etc
blah blah blah
....
check to see if game condition calls for spawning anything. If it does then spawn
....
for each Entity.enemy check their status, collisions etc
during the check of each entity allow for dynamic deletion of enemy
}
}

What I am referring to are the various methods people use to achieve this effect. I.E. having an unsorted, not specifically named list you can sort through, add to, and remove things from TOTALLY dynamically, without resorting to, for example, having "ghosts" of enemies that you turn on and off, but that still occupy memory.

##### Share on other sites
This isn't a Java specific thing- you're getting "game programming" confused with "engine programming"

Game programming is nice and intuitive. You spend your time writing things like you describe:

if(!endOfLevel)   Engine.spawn(new HammerOrc());else   Engine.spawn(new Boss());...if(playerHit){   if(playerWearingArmor)      player.damage(damage / armorAmmount);   else      player.damage(damage);}

Engine programming is difficult and mindnumbing.

public void spawn(Entity e){   Tree worldTree = Engine.getWorldTree();   Vector3df origin = e.getOrigin();   for(Enumeration e = worldTree.getNodes(); e.hasMoreElements){      Node n = (Node)e.nextElement();         if(n.isFound(origin))      n.Insert(e);   else if(n.hasChildren()){         Node parent = n;         while(parent.hasChildren()){            Node[] children = parent.getChildren();            for(int i = 0; i < children.length; i++){               if(children.isFound())                  children.Insert(e);            }         }    }    else       Throw new EngineException("Entity location not found in world tree.  Invalid coordinates!");}

Ok, so, that was completely fictional. However, it still makes sense. Spawning and manipulating Entities in a game world is potentially very very complex stuff! This is the case in any language you use.

No language has a built in game Engine. There are 3rd party engines available for Java (JMonkeyEngine, JOgre, AgentFX, etc) and C++ (Ogre, Irrlicht, Genesis3D, etc)- but these exist only because somebody took the time to do all the dirty stuff.

As far as creating/destroying objects during the loop- there are issues with this sort of thing in any language if you don't know what you're doing. Typically though, these are the worries of someone writing an engine- trying to prevent memory leaks and hiccups. If all you're doing is creating/destroying Orcs and such, this won't be a problem. If you're optimizing your particle engine to prevent it from garbage collecting 5000 particles every second, then this might be a concern :D

Java 1.5 is very good at these sort of things though- Don't worry about creating/destroying objects in the main loop.

##### Share on other sites
(From c++ point of view) To add to memory leaks you also tend to worry about memory fragmentation.

##### Share on other sites
So which of these extensions are Engines, and which are the things that you use to build engines? Is LWJGL an engine? While I may become interested in engine development at some point, my inclination right now is that I would like to learn more about actual game design. Which java setup would be the best for diving right in(with a solid understanding of Java itself of course) and making stuff happen?

Just to be clear, I am not looking for a glorified RPGMaker2000 type of thing. I don't want any assumptions to be made as far as the games BEHAVIORS, I want to to ALL of that myself. I don't want built in systems for HP/MP. I really just want a way so that I can focus maybe 30% on Java and 70% on the game logic itself.

Of those 3RD party engines you listed(and I am not saying this to be lazy, I Know I can easily Google them all, I am asking you because you seem more experienced than I) which(if any) would be perfect for focusing purely on 2D game design, preferably for running on a windows/Linux desktop in fullscreen? (Note that when I say 2D, I mean 2D from my perspective. I don't have any problem with ones that do 2D sprites as 3D flats as opposed to per-pixel) I am not saying this to avoid googling, just wondered if any of them were "dead on" for my needs.

EDIT: Fresh off Google> http://goldenstudios.or.id/products/GTGE/ I wonder if this is what I am looking for?

##### Share on other sites
The big ones (JOgre, JMonkeyEngine) might be too big for what you want.

I'd suggest GTGE (http://www.goldenstudios.or.id/).
- The creator frequents these boards so you can get some nice help from him.

I havn't used it myself, but from looking at it, it'll probably be best thing to bring you to the "30/70% ratio" you want. However, without knowing what type of game you're shooting for I fear that "30/70" might be wishful thinking. 1:1 might be more realistic for a simple game.

A step from that is Java2D itself- which is just using the Java graphics library in conjunction with an applet or frame. This is probably too loose though. However- Java2D is a great progession from GTGE once you've gotten some game logic under your belt. Especially because GTGE is written in Java2D.

Also, to help you organize your thoughts about engines/game logic. Here is a nice tutorial by kevGlass http://www.cokeandcode.com/info/tut2d.html I've sent a few of my friends there who were wishing to learn about Java game programming.

Good luck!

##### Share on other sites
Well my 30/70 thing was just talking out of my butt :) I appreciate the help on this thread, now I better get back to getting the rest of plain ol' Java under my belt so I can start into this.

##### Share on other sites
If you want to make a game, not the basic stuff, then yes, GTGE is what you looking for!
This is very true especially when you say you want to make 2D game, cos GTGE is focusing on 2D game development.
Then you can indeed focus 30% on Java and 70% on the game logic/game design.

And GTGE can also use OpenGL mode (both LWJGL and JOGL supported), but the basic GTGE will only using Java2D, that way GTGE can make pure 2D game without the need of any other library instead of Java SDK of course.
The beauty thing is to port from GTGE Java2D to GTGE OpenGL via LWJGL/JOGL, the game only need to change 2 lines of code roughly, and the game is already in OpenGL world.
Basically GTGE use OpenGL mode only for performance wise, but not closed for mixing 3D objects in 2D ;)

Now here is the list of GTGE features :
http://goldenstudios.or.id/products/GTGE/

And the most important thing is, GTGE is actively developed with the best support I can say.

Any question? :)

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 13
• 9
• 9
• 15
• 14
• ### Forum Statistics

• Total Topics
634071
• Total Posts
3015336
×


text:
# What is the distance between (-7,6,10) and (7,-4,9)?

Mar 29, 2018

#### Answer:

distance $= 3 \sqrt{33} \approx 17.2$ square units

#### Explanation:

We seek the distance $d$, say, between the coordinates $\left(- 7 , 6 , 10\right)$ and $\left(7 , - 4 , 9\right)$? in euclidean space.

Applying Pythagoras theorem in $3$-Dimensions we have:

${d}^{2} = {\left(- 7 - 7\right)}^{2} + {\left(6 - \left(- 4\right)\right)}^{2} + {\left(10 - 9\right)}^{2}$
$\setminus \setminus \setminus \setminus = {\left(- 14\right)}^{2} + {\left(10\right)}^{2} + {\left(1\right)}^{2}$
$\setminus \setminus \setminus \setminus = 196 + 100 + 1$
$\setminus \setminus \setminus \setminus = 297$

Thus:

$d = \sqrt{297} \setminus \setminus \setminus$ (NB - we seek the positive solution)
$\setminus \setminus = \sqrt{9 \cdot 33}$
$\setminus \setminus = 3 \sqrt{33}$
$\setminus \setminus \approx 17.2$


text:
## Making Movies with Processing III

This week, we begin a discussion of creating movies consisting of animated fractals.  Last week’s post about the dot changing colors was at a beginning level as far as Processing goes.  This week’s post will be a little more involved, but will assume a knowledge of Iterated Function Systems.  I talked about IFS on Day034, Day035, and Day036.  Feel free to look back for a refresher….

Today, we’ll see how to create the following movie.  You’ll notice that both the beginning and final Sierpinski triangles are fractals discussed on Day034.

As a reminder, these are the three transformations which produce the initial Sierpinksi triangle:

$F_1\left(\begin{matrix}x\\y\end{matrix}\right)=\left[\begin{matrix}0.5&0\\0&0.5\end{matrix}\right] \left(\begin{matrix}x\\y\end{matrix}\right),$

$F_2\left(\begin{matrix}x\\y\end{matrix}\right)=\left[\begin{matrix}0.5&0\\0&0.5\end{matrix}\right] \left(\begin{matrix}x\\y\end{matrix}\right)+\left(\begin{matrix}1\\0\end{matrix}\right),$

$F_3\left(\begin{matrix}x\\y\end{matrix}\right)=\left[\begin{matrix}0.5&0\\0&0.5\end{matrix}\right] \left(\begin{matrix}x\\y\end{matrix}\right)+\left(\begin{matrix}0\\1\end{matrix}\right).$

Also, recall that to get the modified Sierpinski triangle at the end of the video, all we did was change the first transformation to

$F_1\left(\begin{matrix}x\\y\end{matrix}\right)=\left[\begin{matrix}0.25&0\\0&0.5\end{matrix}\right] \left(\begin{matrix}x\\y\end{matrix}\right).$

We’ll how to use linear interpolation to create the animation.  But first, let’s look at the Python code for creating a fractal using an iterated function system.

The parameter p is for the linear interpolation (which we’ll discuss later), and n is the number of points to plot.  First, import the library for generating random integers — since each transformation will be weighted equally, it’s simpler just to choose a random integer from 1, 2, and 3.  The variable points keeps track of all the points, while last keeps track of the most recently plotted point.  Recall from earlier posts that you only need the last point in order to get the next one.

Next, the for loop just creates new points, one at a time, and appends them to points.  Once an affine transformation is randomly chosen by selecting a randint in the range from 1 to 3, it is applied to the last point generated.  For the purpose of writing Python code, it’s easier to use the notation

$F_2\left(\begin{matrix}x\\y\end{matrix}\right)=\left(\begin{matrix}0.5 \ast x+1\\0.5\ast y\end{matrix}\right)$

rather than matrix notation.  In order to use vector and matrix notation, you’d need to indicate that (1,2) is a vector by writing

v = vector(1,2),

and similarly for matrices.  Since we’re doing some fairly simple calculations, just writing out the individual terms of the result is easier and requires less code.

Once the points are all created, it’s time to plot them.  You’ll recognize the background, stroke, and strokeWeight functions from last week.  Nothing fancy here, since we’re focusing on algorithms today.  Just a black background and small orange dots.

The last line plots the points, and is an example of what is called list comprehension in Python.  First, note that the iterated function system would create a fractal which would fit inside a triangle with vertices (0,2), (0,0), and (2,0).  So we need to suitably scale the fractal — in this case by a factor of 225 so it will be large enough to see.  Remember that units are in pixels in Processing.

Then we need to compensate for Processing’s coordinate system.  You’ll notice a similarity to what we did a few weeks ago.

What the last line does is essentially this:  for every point x in the list points, adjust the coordinates for screen space, and then plot x with the point function.  List comprehension is convenient because you don’t have to make a loop or other iterative construct — it’s done automatically for you.

Of course that doesn’t mean you never need a for loop.  It wouldn’t be easy to replace the for loop above with a list comprehension as each new point depends on the previous one.  But for plotting a bunch of points, for example, it doesn’t matter which one you plot first.

Now for the linear interpolation!  We want the first frame to be the usual Sierpinski triangle, and the last frame to be our modified triangle.  The only difference is that one of the constants in the first function changes from 0.5 to 0.25.

This is perfect for using linear interpolation.  We’d like our parameter p to be 0.5 when p = 0, and 0.25 when p = 1.  So we just need to create a linear function of p which passes through the points (0, 0.5) and (1, 0.25).  This isn’t hard to do; you should easily be able to get

$0.5 - 0.25 \ast p.$

The effect of using the parameter p in this way is to create a series of fractals, each one slightly different from the one before.  Since we’re taking 360 steps to vary from 0.5 to 0.25, there is very little difference from one fractal to the next, and so when strung together, the fractals make a convincing animation.

I should point out the dots look like they’re “dancing” because each time a fractal image is made, a different series of random affine transformations is chosen.  So while the points in each successive fractal will be close to each other, most of them will actually be different.

For completeness, here is the code which comes before the sierpinski function is defined.

It should look pretty familiar from last week.  Similar setup, creating the parameter p, writing out the frames, etc.  You’ll find this a general type of setup which you can use over and over again.

So that’s all there is to it!  Now that you’ve got a basic grasp of Processing’s screen space and a few different ways to use linear interpolation, you can start making movies on your own.

Of course there are lots of cool effects you can add by using linear interpolation in more creative ways.  We’ll start to take a look at some of those next week!

## Making Movies with Processing II

Last week we learned a little about the history of Processing, as well as what the coordinate system is like in Processing (and many other graphics applications as well).  Today I’d like to discuss an idea which I find very helpful in making movies — linear interpolation.  We’ll only have time for one simple example today, but we’ll go through that example very thoroughly.

So here’s the movie we’ll explore today.  Not glamorous, but it’s a start.

You’ll notice what’s happening — the dot slowly turns from magenta to black, while the background does the opposite.  Let’s look at the dot first.  In Processing, RGB values go from 0 to 255.  Magenta is (255, 0, 255) in RGB, and black is (0, 0, 0).  We want the dot to go smoothly from magenta to black.

The way I like to do this is to introduce a parameter p.  I think of p = 0 as my starting point, and p = 1 as my ending point.  In this example, p = 0 corresponds to magenta, and p = 1 corresponds to black.  As p varies from 0 to 1, we want the dot to go from magenta go black.

This is where linear interpolation comes in.  For any start and end values, the expression

(1 – p) * start + p * end

will vary continuously from the start value to the end value as p goes from 0 to 1.  It should be clear that when p = 0, you get the start value, and when p = 1, you get the end value.  Any value of p in between 0 and 1 will be in between the start and end values — closer to the start value when p is near 0, and closer to the end value when p is near 1.

Because this expression is linear in p — no quadratic terms, no square roots, no sines or cosines — we say that this expression gives a linear interpolation between the start and end values.

Let’s see how this works in Processing.  Here’s a screen shot of the code that produced the video shown above.

The basic functions for making a simple movie are setup and draw.  The setup function is executed once before the movie starts.  Then the draw function is called repeatedly — each time the draw function is called, a new frame of the movie is created.

In a typical program, if you wanted to repeat something over and over, you’d need to make a loop.  But in Processing — since its purpose is to create frames for movies — this is built in to how the application works.  No need to do it yourself.

So in Processing, the variable frameCount automatically keeps track of which frame you’re creating.  And it is automatically incremented each time the draw function executes.  You’ll find that this is a very nice feature!  This way, you don’t have to keep track of frames yourself.

Note the size declaration in the setup function.  Last week, I mentioned that you’ve got to set the size of your coordinate system when you start your movie.  The “P2D” means you’re creating a two-dimensional image.  You can make 3D objects in processing, but we won’t look at that today.

Typical applications which make movies (like PhotoShop, or the Movie Maker found in Processing’s “Tools” menu) use about 30 frames per second.  So 360 frames (as above) will be a 12-second movie.  Enough to see the dot and background change colors.

The if/else clause determines the frames produced.  Note that when frameCount gets larger than 360, you skip to the “else” clause, which is “noLoop()”.  This essentially stops Processing from creating new frames.  The saveFrame command saves the individual frames to whatever directory you specify; if you forget the else clause, Processing will just keep generating more and more .tiff files and clutter up your directory.

So the if/else clause basically tells Processing this:  make 360 frames, one at a time, and save then in a directory called “frames.”  Once all 360 frames are made, it’s time to stop.

The makedot function is what actually creates the frame.  Now we’re getting to the linear interpolation!  The frameCount/360. is what creates the value of p.  When frameCount is 1, the value of p is 1/360 (close enough to 0 for the purposes of our movie), and when frameCount is 360, the value of p is 1.  As the value of frameCount increases, p increases from about 0 to 1.

It’s important to use a decimal point after the number 360.  If you don’t, Python will use integer division, and you’ll get 0 every time until frameCount reaches 360, and only then will you get 1.  (I learned this one the hard way…took a few minutes to figure out what went wrong.)

So let’s go through the makedot function line by line.  First, we set the background color.  Note that when p is 0, the color is (0, 0, 0) — black.  As p moves closer to 1, the black turns to magenta.  It is also important to note that when you call the background function, the entire screen is set to the color you specify.  Processing will write over anything else that was previously displayed.  So be careful where you put this command!

Next, the width of lines/points drawn is set with strokeWeight.  Remember that the units are pixels — so the width of the dot is 300 pixels on a screen 500 pixels wide.  Pretty big dot.

The stroke command sets the color of lines/points on the screen.  Notice the (1 – p) here — we want to begin with magenta (when p = 0), and end with black (when p = 1).  So we go the “opposite” direction from the background.

Maybe you noticed that at one point, the dot looked like it “disappeared.”  Not really — note that when p = 1/2, then 1 – p = 1/2 as well!  At this time, the dot and background are exactly the same color.  That’s why it looked like the dot vanished.

And last but not least — the dot.  Remembering the coordinate system, the dot is centered on the screen at (250, 250).

That’s it.  Not a long program, but all the essentials are there.  Now you’ve got a basic idea of how simple movies can me made.  The next post will build on this week’s and look at some more examples of linear interpolation.  Stay tuned!

## Making Movies with Processing I

If you’ve been following my Twitter (@cre8math), you’ll have noticed I posted quite a few videos last fall.  At the time I was writing a lot about creating fractal images, and I really wanted to learn how to make animations using these images.  I had heard about Processing from a lot of friends, and decided that it was time to dive in!  Here is one of earlier movies, but still one of my favorites.

Processing has been around since 2001.  From the very beginning, Processing was used in the classroom as a tool to allow students to quickly create graphical images and movies.  It is now used widely by educators, artist, designers, architects, and researchers.  Many companies use Processing for data visualization.  Click on the link to read more!

One of the great things about Processing is that it’s open source — a specific intention of the developers.  Now, there’s even a Processing Foundation.  Its purpose is to “promote software literacy within the visual arts, and visual literacy within technology-related fields — and to make these fields accessible to diverse communities.”  The idea is to provide everyone access to software you can use to create a wide range of visual media.  Not just those who can afford it.

I support open-source initiatives as well.  Most of the digital art I’ve talked about on my blog was written in Mathematica, a powerful programming language, but expensive to buy.  I rewrote all the algorithms you’ve seen on the Sage worksheets in Python because I wanted them to be available to anyone who has access to the internet.  Not just those who can afford pricey software….

Now there won’t be time to go into everything about Processing — that’s what the internet is for.  I often google phrases like “How do you change the background color in Processing?”, and usually get the information I need pretty quickly.

What I want to focus on today is the coordinate system used in Processing.  If you’re new to computer graphics, it might be a little unfamiliar — the coordinate system is based on pixels.  For example, the screen on my Mac is 1440 x 900 pixels.  But the origin (0, 0) is in the upper left corner of the screen, so that  the lower right corner has coordinates (1440, 900).  In other words, while the positive x-axis is still to the right, the positive y-axis is now pointing down.  This is sometimes called a screen coordinate system, or screen space.

This convention has an interesting history.  Older television screens used cathode ray tubes, and literally updated the screen by refreshing one line at a time, from top to bottom and from left to right.  After updating the pixel at the lower right, refreshing began again at the upper left.  This process occurred several times each second to give the illusion of continuous motion.  Because the refresh was done from top to bottom, the y-coordinates increased from top to bottom as well.

Such a coordinate system is not unusual.  The PostScript programming language (which I told you about two weeks ago) has a coordinate system based on points.  The definition of a point has changed over time, but PostScript uses a coordinate system where there are 72 points per inch, and the lower left corner has coordinates (0,0).

PostScript is used for printing physical documents.  Because copier paper typically has dimensions 8.5″ x 11″ in the United States, the upper right corner of your document would have coordinates (612, 792).

In Processing, you need to specify the size of the screen you want for your movie.  In the example above, I chose 768 x 768 pixels.  This may sound like a strange number, but a commonly used screen size is 1024 x 768.  Because of what my image looked like, though, I wanted the screen to be square so there wouldn’t be extra space on the left and right.

Now the objects you see in the movie have rotational symmetry.  So it would make sense for the origin (0,0) to be at the center of the movie screen, not the upper left corner.  A convenient coordinate system for these objects might have the upper left corner be (-1, 1), and the lower right corner be (1, -1), just like the usual Cartesian coordinate system.  This system of coordinates is sometimes called local space or user space.  In other words, it’s the space the user is thinking in when designing various images.

So now the issue is converting from user space to screen space.  This isn’t difficult, so we’ll just work through this example to see how it’s done.  All you need to remember is how to find the equation of a line.

Why a line?  Let’s look at x-coordinates first.  In user space, x-coordinates range from -1 to 1.  In screen space, they range from 0 to 768.  If you went 1/4 of the way from -1 to 1 in user space — which would put you at -0.5 — then you’d expect the corresponding point in screen space to be 1/4 of the way from 0 to 768, which would be 192.  You’d expect this for any ratio, not just 1/4.  This is precisely what it means for the transformation of coordinates from user space to screen space to be linear.

Since -1 in user space corresponds to 0 in screen space, and 1 corresponds to 768, all we need to do is find the equation of the line between the points (-1,0) and (1,768).  In Cartesian coordinates, this would be $y=384(x+1).$ Or we might alternatively say

$x_{\rm screen} = 384(x_{\rm user}+1).$

Once we know how to do this for the x-coordinates, we can proceed the same way for the y-coordinates.  You should be able to figure out that

$y_{\rm screen} = 384(1-y_{\rm user}).$

Note that the minus sign in front of $y_{\rm user}$ is a result of the fact that the positive y direction is pointing down.

This is a very general idea which will allow you to convert from one space to another fairly easily.  And it’s definitely necessary in Processing to set up the screen for your movie.

Next week we’ll look at linear interpolation — another important concept which will help us make movies.  Until then!

## Bridges: Mathematics and Art I

Just registered for Bridges 2016 last week!

Simply put, Bridges is the best mathematics conference ever.  You meet people from all around the world who are interested in the interplay between mathematics and art.

Not just M. C. Escher, either (though many are interested in his work).  Some Bridges attendees (shall we call them Bridgers?) are artists by profession, but others are mathematicians, computer scientists, physicists — you name it.  All are artists by vocation.

Interests span not only art in a more usual sense — watercolor, acrylic, oil, pastel, drawing — but also digital art, sculpture in almost any medium you can think of, poetry, architecture, music, fiber arts, dance, digital animations and movies, fashion, origami, and likely there will be some new art form introduced this summer as well!

The art exhibition is amazing.  You can see a few examples above.  You see the wooden spiral?  Each inlaid rectangle is a different piece of wood!  The craftsmanship is really superb.

One neat aspect is that most of the artists also attend Bridges.  That means if you see something you really like, you can just look for the right name tag and start up a conversation.  As you would expect, all the artists are eager to discuss their work.

Be ready for some surprises, too.  I met my friend Phil Webster at the conference – we starting talking because I was from San Francisco, and he also lives in the Bay area.  So we’ve met up a few times since the conference to discuss mathematics, art, and programming.  He even gave a talk in our Mathematics Colloquium at the University of San Francisco.  Of course, his talk was great….

Even if you don’t go to the conference, you can still appreciate all the art.  You can visit the Bridges 2015 online gallery and see all the art that was exhibited.  Not only are there descriptions of all the works by the artists themselves, but there’s also contact information so you can get in touch if you’d like.  Please do!

The Bridges 2016 gallery is not online yet, but I’ve got two pieces accepted for this year’s exhibition.  This is my favorite.

Then there are the talks.  You learn so much just by going to them.  The range of topics is incredibly diverse — look back at the list above!  Last summer, I gave a talk about Random Walks on Vertices of Archimedean Tilings.  My favorite work discussed in the paper is Bear.  You can read the paper to learn how it was made, if you’re interested.  The first print of Bear is hanging in my friend Cory’s house in Florida.  Hi, Cory!

As you’ll see if you click on the link to my paper, there is an archive of all papers — over 1000! — given at Bridges conferences since 1998.  What’s nice is that you can actually search for specific topics, so it’s easy to use.  No shortage of reading material on mathematics and art….

In addition to the exhibition and all the presentations, there are also dance performances, poetry readings, theatre performances, movie showings, a music night — any number of interesting activities relating mathematics and art.  If you want to learn more, just go to the Bridges 2016 website.  There’s complete information on the upcoming conference there.

This year, the conference is being held at the University of Jyväskylä in Jyväskylä, Finland.  I’ve never been to Finland before, so I’m looking forward to an exciting trip!  What’s also nice about the conference is that in the evenings, you can just take a stroll with other Bridgers, looking for some interesting place to have dinner.  I always love exploring new countries, and especially like trying new cuisines!

But even though Bridges 2016 is in July, I actually starting preparing last November.  Since there was a January deadline for submitting papers to the conference, and since I knew I’d be doing a lot of traveling over our Winter Break, I wanted to get an early start.  The papers are all reviewed by three referees, so your mathematics should be sound.  Usually they have comments to make, and so you often need to make some revisions a few months later before a final submission.

My paper is on fractals this year.  A lot of what I wrote in that paper you’ve already seen on my blog — but I’ll be sure to give a link when I write a follow-up post on Bridges 2016 later on in the summer.  Here’s one of my favorite images discussed in the paper.

There are deadlines to submit artwork as well, so it’s important to be organized.  For both papers and artwork, the online submission system is actually really easy to use.  I just wanted to let you know something about the process so you can submit something to next year’s conference….

Last Fall, I received an email about a new addition to the Bridges menu — student scholarships.  And in my calculus class, I had a student Nick who is a double major in mathematics and art.

Turns out Nick was really interested in trying to submit to Bridges, so we worked out a one-credit directed study course just for that purpose.  As of this moment, I’m happy to say that two of Nick’s artworks were accepted!  And we just submitted the final revisions to his paper, and are waiting to hear back.  We should know about the scholarship soon — I’ll update this post when I have more information.  One of my favorite images from Nick’s paper is this one.

You can read the paper to see how he creates it….link to follow.

So think about including Bridges in your future travel!  Many artists bring their families and make a summer vacation out of the conference.  It’s quite an experience.

And if you’re a student, consider submitting as well!  Maybe you’ll earn a scholarship to attend:  here’s more information on the Student Travel Scholarship.  Preference is given to those student who submit papers, artwork, or movies.

You will need a letter from one of your teachers or professors — so ask someone to be your mentor.  If you can’t find someone, well, just ask me.  I’ll be glad to help out (as long as I don’t get too many requests!).

Later on in the summer, I’ll tell you all about the experience.  Hope to see you at some Bridges conference soon!

P.S. (10 July 2106):  Nick did receive the travel scholarship.  Congratulations!

## Creating Fractals VIII: PostScript Programming

June 1998.

That’s when I wrote the code I’m going to talk about today.

When I became interested in computer graphics, a windows environment you’re used to by now just didn’t exist.  For example, the computer I used (called a Zenith H19) had a screen 80 x 25 characaters.  Yes, characters.  Rather like a larger version of those still unimaginable TI calculator screens (couldn’t resist).

There was no graphical user interface (GUI), mouse, touch-screen.  If you wanted to draw a picture, you had to write a computer program to do it.

And if you wanted to see what it looked like, well, you had to print it out.

Yep.  That was the only way to see if your code was correct.  It made debugging very challenging.  But that’s all there was.  So I learned how to write PostScript code.

There are two features of PostScript I want to discuss today.  First, the syntax is written in postfix notation, like most HP calculators.  If you wanted to add 2 and 3 on a typical calculator, you’d type in “2 + 3 =.”  The result would be 5.  This is called infix notation, where the operator is written in between the arguments.

In PostScript, though, you’d write “2 3 add.”  In other words, the arguments come first.  Then they’re added together — the operator comes last, which is referred to as postfix notation.  So if you wanted to write

(2 + 3 ) x (10 – 4)

in PostScript, you’d write

2 3 add 10 4 sub mul.

Notice that the multiplication is done last.

When programming in Python, most functions are described using prefix notation.  In other words, you give the function name first, and then the arguments to the function.  For example, randint(1,10) would output a random number between 1 and 10, inclusive.  If we had to write the arithmetic expression above in prefix notation, it would look like

You probably encounter these ideas on a daily basis.  For example, if you want to delete a bunch of files, you first select them, and then do something like click “Move to trash” from a dropdown menu.  But if you’re writing an email, you usually click on the attach icon first, and then select the files you’d like to attach.  Postfix and prefix.

Of course this is just an introduction to using the different types of notation.  In general, you’d transform the above arithmetic expression into what it called an expression tree, like this:

Then prefix notation may be derived from a preorder traversal of the expression tree, infix notation from an inorder traversal of the tree, and finally, postfix notation comes from a postorder traversal of the tree.  Feel free to ask the internet all about binary trees and tree traversals.  Trees are very important data structures in computer science.

The second feature of PostScript I’d like to discuss today is that it is an example of a stack-based language.  For example, if you typed

4  5  3  7  8

in a PostScript program, the number 4 would be pushed onto the stack — that is, the working memory of the program — and then 5, then 3, 7, and finally 8.  (For convenience, we’ll always think of the bottom of the stack as being on the left, and the top of the stack as being on the right.  Easier to write and read that way.)

If you want to follow along, do the following:  write 4 on an index card or small piece of paper, then write 5 on another and put it on top of the 4, and so on, until you put the 8 on top of the stack.  You really do have a stack of numbers.

Now when you type the “add” function, PostScript thinks, “OK, time to add!  What are the top two numbers on the stack?  Oh, 8 and 7!  I’ll add these and put the sum back on the stack for you!”

So you type

4  5  3  7  8  add,

and PostScript performs the appropriate action and the stack now becomes

4  5  3  15.

If you now want to divide (div in PostScript), the interpreter looks at the top number on the stack and divides it by the second number on the stack, and puts that result on the stack.  So

4  5  3  7  8  add  div

would create the stack

4  5  5.

You should be able to figure out that

4  5  3  7  8  add  div  mul  sub

would just leave the single number 21 on the stack.

Graphics are drawn this way, too.  For example, we would create a square with the commands

0 0 moveto  0 1 lineto  1 1 lineto  1 0 lineto  0 0 lineto  closepath  stroke.

Again, the arguments come first.  We move to the point (0,0), and then draw a line segment to (0,1), and so forth.  Closepath “ties” the beginning and end of our path together, and the command “stroke” actually draws the square on the page.

Commands like

1  0.5  0  setrgbcolor

set the current color to orange, and

5 setlinewidth

sets the width of lines to be drawn.  You can change any aspect of any drawn image — the only limit is your imagination!

Of course this is only the most basic introduction to the PostScript programming language.  But if you’re interested, there’s good news.  First, it shouldn’t be hard to download a PostScript interpreted for your computer.  I use MacGhostView — installing will also require you to install XQuartz, too, but not to worry.

Second, there are some great resources online.  Back when I was learning PostScript, there were three very helpful books — the Blue Book, the Red Book, and the Green Book.  Yep, that’s what there were called.   The Blue Book is the place you should start — it includes a tutoral on all the basics.  The Red Book  is the Reference Manual — handy in that it lists PostScript commands, their syntax, and examples of how to use them.  The Green Book is for the serious programmer, and discusses at a high level how the PostScript language is organized.

Finally, here is the code I wrote all those years ago!  (Click here: Sierpinski.)    I did modify the original code so it produces a Sierpinski triangle.  It will be a little daunting to figure out if you’re just starting to learn PostScript, but I include it as it motivated me to talk about PostScript today.

And a final few words about motivation.  Try to learn programming languages which expose you to different ways of thinking.  This develops flexibility of mind for coding in general.  Whenever I learn a new language, I’m always thinking things like, “Oh, that’s the same as stacks in PostScript,” or “Yeah, like maps in LISP.”

As you learn more, your programming toolbox gets bigger, and you find that the time it takes from conceiving of an idea to successfully implementing it becomes shorter and shorter.  That’s when it starts really getting fun….

## Creating Fractals VII: Iterated Function Systems III

Today, we’re going to wrap up our discussion of iterated function systems by looking at an algorithm which may be used to generate fractal images.

Recall (look back at the first post if you need to!) the Sierpinski triangle.  No matter what initial shape we started with, the iterations of the function system eventually looked like the Sierpinski triangle.

But there’s a computational issue at play.  Since there are three different transformations, each iteration produces three times the number of objects.  So if we carried out 10 iterations, we’d have 310 = 59,049 objects to keep track of. Not too difficult for a computer.

But let’s look at the Sierpinski carpet. With eight different transformations, we’d have 810 = 1,073,741,824 objects to keep track of. Keeping track of a billion objects just isn’t practical.

Of course you could use fewer iterations — but it turns out there’s a nice way out of this predicament. We can approximate the fractal using a random algorithm in the following way.

Begin with a single point (usually (0,0) is the easiest).  Then randomly choose a function in the system, and apply it to this point.  Then iterate:  keep randomly choosing a function from the system, then apply it to the last computed point.

What the theory says (again, read the Barnsley book for all the proofs!) is that these points keep getting closer and closer to the fractal image determined by the system.  Maybe the first few are a little off — but if we just get rid of the first 10 or 100, say, and plot the rest of the points, we can get a good approximation to the fractal image.

Consider the Sierpinski triangle again.  Below is what the first 20 points look like (after (0,0)), numbered in the order in which they’re produced.

Let’s look at this in a bit more detail.  For reference, we’ll copy the function system which produces the Sierpinski triangle from the first post.

$F_1\left(\begin{matrix}x\\y\end{matrix}\right)=\left[\begin{matrix}0.5&0\\0&0.5\end{matrix}\right] \left(\begin{matrix}x\\y\end{matrix}\right)$

$F_2\left(\begin{matrix}x\\y\end{matrix}\right)=\left[\begin{matrix}0.5&0\\0&0.5\end{matrix}\right] \left(\begin{matrix}x\\y\end{matrix}\right)+\left(\begin{matrix}1\\0\end{matrix}\right)$

$F_3\left(\begin{matrix}x\\y\end{matrix}\right)=\left[\begin{matrix}0.5&0\\0&0.5\end{matrix}\right] \left(\begin{matrix}x\\y\end{matrix}\right)+\left(\begin{matrix}0\\1\end{matrix}\right)$

Now here’s how the color scheme works.  Any time $F_1$ is randomly chosen, the point is colored red.  For example, you can see that after Point 6 was drawn, $F_1$ was chosen, so Point 7 was simply halfway between Point 6 and the origin.

Any time $F_2$ is chosen, the point is colored blue.  For example, after Point 8 was drawn, $F_2$ was randomly chosen.  You can see that if you move Point 8 halfway to the origin and then over right one unit, you land up exactly at Point 9.

Finally, any time $F_3$ is chosen, the point is colored orange.  So for example, it should be clear that moving Point 7 halfway toward the origin and then up one unit results in Point 8.

Of course plotting more points results in a more accurate representation of the fractal.  Below is an image produced using 5000 points.

To get more accuracy, simply increase the number of points, but decrease the size of the points (so they don’t overlap).  The following image is the result of increasing the number of points to 50,000, but using points of half the radius.

There’s just one more consideration, and then we can move on to the Python code for the algorithm.  How do we randomly choose the next affine transformation?

Of course we use a random number generator to select a transformation.  In the case of the Sierpinski triangle, each of the three transformations had the same likelihood of being selected.

Now consider one of the fractals we looked at last week.

If the algorithm chose either transformation with equal probability, this is what our image would look like:

Of course there’s a huge difference!  What’s happening is that transformation $F_{{\rm orange}}$ actually corresponds to a much smaller portion of the fractal than $F_{{\rm green}}$ — and so to get a more realistic idea of what the fractal is really like, we need to choose it less often.  Otherwise, we overemphasize those parts of the fractal corresponding to the effect of $F_{{\rm orange}}.$

Again, according to the theory, it’s best to choose probabilities roughly in proportion to the portions of the fractal corresponding to the affine transformations.  So rather than a 50/50 split, I chose $F_{{\rm green}}$ 87.5% of the time, and $F_{{\rm orange}}$ just 12.5% of the time.  As you’ll see when you experiment, a few percentage points may really impact the appearance of a fractal image.

From a theoretical perspective, it actually doesn’t matter what the probabilities are — if you let the number of points you draw go to infinity, you’ll always get the same fractal image!  But of course we are limited to a finite number of points, and so the probabilities do in fact strongly influence the final appearance of the image.

So once you’ve chosen some transformations, that’s just the beginning.  You’ve got to decide on a color scheme, the number of points and their size, as well as the probabilities that each transformation is chosen.  All these choices impact the result.

Now it’s your turn!  Here is the Sage link to the python code which you can use to generate your own fractal images.  (Remember, you’ve got to copy it into one of your own Projects first.)  Freely experiment — I’ve also added examples of non-affine transformations, as well as affine transformations in three dimensions!

And please comment with interesting images you create.  I’m interested to see what you can come up with!

## Creating Fractals VI: Iterated Function Systems II

What I find truly remarkable about iterated function systems is the astonishing variety of fractals you can create with just two affine transformations.  Today, we’ll explore some more examples so you can get a better feel for how the particular affine transformations used affect the final image.

Let’s begin with the example from last week, which I color coded for easy reference.

Below are the affine transformations which generated this fractal.

$F_{{\rm green}}\left(\begin{matrix}x\\y\end{matrix}\right)=\left[\begin{matrix}0.95&0\\0&0.95\end{matrix}\right]\left[\begin{matrix}\cos(20^\circ)&-\sin(20^\circ)\\\sin(20^\circ)&\cos(20^\circ)\end{matrix}\right]\left(\begin{matrix}x\\y\end{matrix}\right)$

$F_{{\rm orange}}\left(\begin{matrix}x\\y\end{matrix}\right)=\left[\begin{matrix}0.4&0\\0&0.4\end{matrix}\right]\left(\begin{matrix}x\\y\end{matrix}\right)+\left(\begin{matrix}1\\0\end{matrix}\right)$

Now compare the different colors in the image with the transformations.  The first transformation combines a scaling by 0.95 with a rotation by 20 degrees.  If you look closely, you’ll see that the green part of the image looks the same as a slightly smaller copy of the entire fractal, except rotated by 20 degrees from the center of the spiral (note that there is no translation involved in $F_{{\rm green}}$).

The orange part of the image is simply a scaled version of the entire fractal (by a factor of 0.4), but moved over 1 unit.  You can see this by looking at the form of the affine transformation $F_{{\rm orange}}.$

The pair of affine transformations used to generate the spiral exactly describes the self-similarity.  This is easy to see after the fact — but I really have no helpful suggestion as to how to predict the form of this wonderful spiral just by looking at the transformations.

Now let’s just slightly alter the second transformation so that in addition to scaling by a factor of 0.4, there is a shear as well.

$F_{{\rm orange}}\left(\begin{matrix}x\\y\end{matrix}\right)=\left[\begin{matrix}0.4&0.4\\0&0.4\end{matrix}\right]\left(\begin{matrix}x\\y\end{matrix}\right)+\left(\begin{matrix}1\\0\end{matrix}\right)$

Notice how the fractal changes.

The shear distorts each arm of the spiral — stretching it in the process and creating more interaction between the various arms.

Now let’s go back to the original spiral and change the first transformation instead, slightly altering the scale factor.

$F_{{\rm green}}\left(\begin{matrix}x\\y\end{matrix}\right)=\left[\begin{matrix}0.9&0\\0&0.9\end{matrix}\right]\left[\begin{matrix}\cos(20^\circ)&-\sin(20^\circ)\\\sin(20^\circ)&\cos(20^\circ)\end{matrix}\right]\left(\begin{matrix}x\\y\end{matrix}\right)$

Here is what happens:

I really don’t how to predict that this is what would happen — but I find it fascinating how even small changes in parameters can really change the way a fractal looks.

I can’t resist one more image created by changing the second transformation to

$F_{{\rm orange}}\left(\begin{matrix}x\\y\end{matrix}\right)=\left[\begin{matrix}0.4&0\\0.4&0.15\end{matrix}\right]\left(\begin{matrix}x\\y\end{matrix}\right)+\left(\begin{matrix}1\\0\end{matrix}\right).$

Here is the result.There’s so much you can do with just one pair of transformations!

While it may not be possible to guess exactly what a fractal will look like, it’s possible to know some features of a fractal based upon how you set up your transformations.  For example, condsider this combination of a shear and a scaling:

$G_1\left(\begin{matrix}x\\y\end{matrix}\right)=\dfrac23\left[\begin{matrix}1&-1/2\\0&1\end{matrix}\right]\left(\begin{matrix}x\\y\end{matrix}\right)+\left(\begin{matrix}1\\1\end{matrix}\right).$

There will be some aspect of the fractal which can be described by a shear.  For the second transformation, just take the opposite of the first, as follows.

$G_2\left(\begin{matrix}x\\y\end{matrix}\right)=-\dfrac23\left[\begin{matrix}1&-1/2\\0&1\end{matrix}\right]\left(\begin{matrix}x\\y\end{matrix}\right)-\left(\begin{matrix}1\\1\end{matrix}\right).$

This must force the fractal to have 180 degree rotational symmetry!  Think about how the algorithm works — take the image under one transformation, then the other — but by their definitions, the images must be symmetric about the origin.

So it is possible to use our knowledge of affine transformations to design, even if to a limited extent, some features of the resulting fractal.

As another example, we can assemble a fractal similar to two smaller copies of itself, one piece of which is a 90 degree rotation of the other.  Use $G_1$ as above, and then use

$G_2=\left[\begin{matrix}0&-1\\1&0\end{matrix}\right]G_1.$

Here is the resulting fractal.

You can clearly see how the red piece is a 90 degree counterclockwise rotation of the purple piece.  This follows from how we created the second transformation from the first.

One reason for the diversity of fractals is the number of parameters needed to specify two affine parameterizations — twelve in all.  Now some sets of parameters may create the same fractal — but even so, the wealth of variations is still staggering.

But will just any affine transformations work?  There are some constraints — for example, you can’t describe a fractal in terms of larger copies of itself.  So the affine transformations cannot make a starting object bigger, or else each successive iteration will expand.  Of course you can still use such affine transformations to create interesting graphical effects — but the resulting image will not be an approximation to a fractal.

Next week, we’ll look at the algorithm which I used to create all these fractal images, and I’ll give you some Python code you can use yourself.  But before I close, I’d like to share a few favorite fractals which are generated by just two affine transformations.

First, the Beetle.  It looks like it’s scampering toward you.

And the second, well, it’s just yellow.

Until next week!