September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -0,0 +1,51 @@
# Return the position of the highest 1-bit in n.
# The least significant bit is position 0.
# For example n=13 is binary "1101" and the high bit is pos=3.
# If n==0 then the return is 0.
# Arranging the test as n>=2 avoids infinite recursion if n==NaN (any
# comparison involving NaN is always false).
#
high_bit_pos(n) = (n>=2 ? 1+high_bit_pos(int(n/2)) : 0)
# Return 0 or 1 for the bit at position "pos" in n.
# pos==0 is the least significant bit.
#
bit(n,pos) = int(n / 2**pos) & 1
# dragon(n) returns a complex number which is the position of the
# dragon curve at integer point "n". n=0 is the first point and is at
# the origin {0,0}. Then n=1 is at {1,0} which is x=1,y=0, etc. If n
# is not an integer then the point returned is for int(n).
#
# The calculation goes by bits of n from high to low. Gnuplot doesn't
# have iteration in functions, but can go recursively from
# pos=high_bit_pos(n) down to pos=0, inclusive.
#
# mul() rotates by +90 degrees (complex "i") at bit transitions 0->1
# or 1->0. add() is a vector (i+1)**pos for each 1-bit, but turned by
# factor "i" when in a "reversed" section of curve, which is when the
# bit above is also a 1-bit.
#
dragon(n) = dragon_by_bits(n, high_bit_pos(n))
dragon_by_bits(n,pos) \
= (pos>=0 ? add(n,pos) + mul(n,pos)*dragon_by_bits(n,pos-1) : 0)
add(n,pos) = (bit(n,pos) ? (bit(n,pos+1) ? {0,1} * {1,1}**pos \
: {1,1}**pos) \
: 0)
mul(n,pos) = (bit(n,pos) == bit(n,pos+1) ? 1 : {0,1})
# Plot the dragon curve from 0 to "length" with line segments.
# "trange" and "samples" are set so the parameter t runs through
# integers t=0 to t=length inclusive.
#
# Any trange works, it doesn't have to start at 0. But must have
# enough "samples" that all integers t in the range are visited,
# otherwise vertices in the curve would be missed.
#
length=256
set trange [0:length]
set samples length+1
set parametric
set key off
plot real(dragon(t)),imag(dragon(t)) with lines

View file

@ -0,0 +1,20 @@
## plotdcf.gp 1/11/17 aev
## Plotting a Dragon curve fractal to the png-file.
## Note: assign variables: ord (order), clr (color), filename and ttl (before using load command).
## ord (order) # a.k.a. level - defines size of fractal (also number of mini-curves).
reset
set style arrow 1 nohead linewidth 1 lc rgb @clr
set term png size 1024,1024
ofn=filename.ord."gp.png" # Output file name
set output ofn
ttl="Dragon curve fractal: order ".ord
set title ttl font "Arial:Bold,12"
unset border; unset xtics; unset ytics; unset key;
set xrange [0:1.0]; set yrange [0:1.0];
dragon(n, x, y, dx, dy) = n >= ord ? \
sprintf("set arrow from %f,%f to %f,%f as 1;", x, y, x + dx, y + dy) : \
dragon(n + 1, x, y, (dx - dy) / 2, (dy + dx) / 2) . \
dragon(n + 1, x + dx, y + dy, - (dx + dy) / 2, (dx - dy) / 2);
eval(dragon(0, 0.2, 0.4, 0.7, 0.0))
plot -100
set output

View file

@ -0,0 +1,20 @@
## pDCF.gp 1/11/17 aev
## Plotting 3 Dragon curve fractals.
## Note: assign variables: ord (order), clr (color), filename and ttl (before using load command).
## ord (order) # a.k.a. level - defines size of fractal (also number of dots).
#cd 'C:\gnupData'
##DCF11
ord=11; clr = '"red"';
filename = "DCF"; ttl = "Dragon curve fractal, order ".ord;
load "plotdcf.gp"
##DCF13
ord=13; clr = '"brown"';
filename = "DCF"; ttl = "Dragon curve fractal, order ".ord;
load "plotdcf.gp"
##DCF15
ord=15; clr = '"navy"';
filename = "DCF"; ttl = "Dragon curve fractal, order ".ord;
load "plotdcf.gp"

View file

@ -0,0 +1,42 @@
<!-- DragonCurve.html -->
<html>
<head>
<script type='text/javascript'>
function pDragon(cId) {
// Plotting Dragon curves. 2/25/17 aev
var n=document.getElementById('ord').value;
var sc=document.getElementById('sci').value;
var hsh=document.getElementById('hshi').value;
var vsh=document.getElementById('vshi').value;
var clr=document.getElementById('cli').value;
var c=c1=c2=c2x=c2y=x=y=0, d=1, n=1<<n;
var cvs=document.getElementById(cId);
var ctx=cvs.getContext("2d");
hsh=Number(hsh); vsh=Number(vsh);
x=y=cvs.width/2;
// Cleaning canvas, init plotting
ctx.fillStyle="white"; ctx.fillRect(0,0,cvs.width,cvs.height);
ctx.beginPath();
for(i=0; i<=n;) {
ctx.lineTo((x+hsh)*sc,(y+vsh)*sc);
c1=c&1; c2=c&2;
c2x=1*d; if(c2>0) {c2x=(-1)*d}; c2y=(-1)*c2x;
if(c1>0) {y+=c2y} else {x+=c2x}
i++; c+=i/(i&-i);
}
ctx.strokeStyle = clr; ctx.stroke();
}
</script>
</head>
<body>
<p><b>Please input order, scale, x-shift, y-shift, color:</></p>
<input id=ord value=11 type="number" min="7" max="25" size="2">
<input id=sci value=7.0 type="number" min="0.001" max="10" size="5">
<input id=hshi value=-265 type="number" min="-50000" max="50000" size="6">
<input id=vshi value=-260 type="number" min="-50000" max="50000" size="6">
<input id=cli value="red" type="text" size="14">
<button onclick="pDragon('canvId')">Plot it!</button>
<h3>Dragon curve</h3>
<canvas id="canvId" width=640 height=640 style="border: 2px inset;"></canvas>
</body>
</html>

View file

@ -0,0 +1,55 @@
// version 1.0.6
import java.awt.Color
import java.awt.Graphics
import javax.swing.JFrame
class DragonCurve(iter: Int) : JFrame("Dragon Curve") {
private val turns: MutableList<Int>
private val startingAngle: Double
private val side: Double
init {
setBounds(100, 100, 800, 600)
defaultCloseOperation = EXIT_ON_CLOSE
turns = getSequence(iter)
startingAngle = -iter * Math.PI / 4
side = 400.0 / Math.pow(2.0, iter / 2.0)
}
fun getSequence(iterations: Int): MutableList<Int> {
val turnSequence = mutableListOf<Int>()
for (i in 0 until iterations) {
val copy = mutableListOf<Int>()
copy.addAll(turnSequence)
copy.reverse()
turnSequence.add(1)
copy.mapTo(turnSequence) { -it }
}
return turnSequence
}
override fun paint(g: Graphics) {
g.color = Color.BLUE
var angle = startingAngle
var x1 = 230
var y1 = 350
var x2 = x1 + (Math.cos(angle) * side).toInt()
var y2 = y1 + (Math.sin(angle) * side).toInt()
g.drawLine(x1, y1, x2, y2)
x1 = x2
y1 = y2
for (turn in turns) {
angle += turn * Math.PI / 2.0
x2 = x1 + (Math.cos(angle) * side).toInt()
y2 = y1 + (Math.sin(angle) * side).toInt()
g.drawLine(x1, y1, x2, y2)
x1 = x2
y1 = y2
}
}
}
fun main(args: Array<String>) {
DragonCurve(14).isVisible = true
}

View file

@ -0,0 +1,68 @@
--
-- demo\rosetta\DragonCurve.exw
--
include pGUI.e
Ihandle dlg, canvas
cdCanvas cddbuffer, cdcanvas
integer colour = 0
procedure Dragon(integer depth, atom x1, y1, x2, y2)
depth -= 1
if depth<=0 then
cdCanvasSetForeground(cddbuffer, colour)
cdCanvasLine(cddbuffer, x1, y1, x2, y2)
-- (some interesting colour patterns emerge)
colour += 2
-- colour += 2000
-- colour += #100
else
atom dx = x2-x1, dy = y2-y1,
nx = x1+(dx-dy)/2,
ny = y1+(dx+dy)/2
Dragon(depth,x1,y1,nx,ny)
Dragon(depth,x2,y2,nx,ny)
end if
end procedure
function redraw_cb(Ihandle /*ih*/, integer /*posx*/, integer /*posy*/)
cdCanvasActivate(cddbuffer)
cdCanvasClear(cddbuffer)
-- (note: depths over 21 take a long time to draw,
-- depths <= 16 look a little washed out)
Dragon(17,100,100,100+256,100)
cdCanvasFlush(cddbuffer)
return IUP_DEFAULT
end function
function map_cb(Ihandle ih)
cdcanvas = cdCreateCanvas(CD_IUP, ih)
cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas)
cdCanvasSetBackground(cddbuffer, CD_PARCHMENT)
return IUP_DEFAULT
end function
function esc_close(Ihandle /*ih*/, atom c)
if c=K_ESC then return IUP_CLOSE end if
return IUP_CONTINUE
end function
procedure main()
IupOpen()
canvas = IupCanvas(NULL)
IupSetAttribute(canvas, "RASTERSIZE", "420x290")
IupSetCallback(canvas, "MAP_CB", Icallback("map_cb"))
IupSetCallback(canvas, "ACTION", Icallback("redraw_cb"))
dlg = IupDialog(canvas,"RESIZE=NO")
IupSetAttribute(dlg, "TITLE", "Dragon Curve")
IupSetCallback(dlg, "K_ANY", Icallback("esc_close"))
IupShow(dlg)
IupMainLoop()
IupClose()
end procedure
main()

View file

@ -0,0 +1,33 @@
# Generate and plot Dragon curve.
# translation of JavaScript v.#2: http://rosettacode.org/wiki/Dragon_curve#JavaScript
# 2/27/16 aev
# gpDragonCurve(ord, clr, fn, d, as, xsh, ysh)
# Where: ord - order (defines the number of line segments);
# clr - color, fn - file name (.ext will be added), d - segment length,
# as - axis scale, xsh - x-shift, ysh - y-shift
gpDragonCurve <- function(ord, clr, fn, d, as, xsh, ysh) {
cat(" *** START:", date(), "order=",ord, "color=",clr, "\n");
d=10; m=640; ms=as*m; n=bitwShiftL(1, ord);
c=c1=c2=c2x=c2y=i1=0; x=y=x1=y1=0;
if(fn=="") {fn="DCR"}
pf=paste0(fn, ord, ".png");
ttl=paste0("Dragon curve, ord=",ord);
cat(" *** Plot file -", pf, "title:", ttl, "n=",n, "\n");
plot(NA, xlim=c(-ms,ms), ylim=c(-ms,ms), xlab="", ylab="", main=ttl);
for (i in 0:n) {
segments(x1+xsh, y1+ysh, x+xsh, y+ysh, col=clr); x1=x; y1=y;
c1=bitwAnd(c, 1); c2=bitwAnd(c, 2);
c2x=d; if(c2>0) {c2x=(-1)*d}; c2y=(-1)*c2x;
if(c1>0) {y=y+c2y} else {x=x+c2x}
i1=i+1; ii=bitwAnd(i1, -i1); c=c+i1/ii;
}
dev.copy(png, filename=pf, width=m, height=m); # plot to png-file
dev.off(); graphics.off(); # Cleaning
cat(" *** END:",date(),"\n");
}
## Testing samples:
gpDragonCurve(7, "red", "", 20, 0.2, -30, -30)
##gpDragonCurve(11, "red", "", 10, 0.6, 100, 200)
gpDragonCurve(13, "navy", "", 10, 1, 300, -200)
##gpDragonCurve(15, "darkgreen", "", 10, 2, -450, -500)
gpDragonCurve(16, "darkgreen", "", 10, 3, -1050, -500)

View file

@ -1,35 +1,31 @@
/*REXX program creates & draws an ASCII Dragon Curve (or Harter-Heighway dragon curve).*/
z=1; d.=1; d.L=-d.; @.=' '; x=0; x2=x; y=0; y2=y; @.x.y=""
plot_pts = '123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZΘ' /*plot chrs*/
minX=0; maxX=0; minY=0; maxY=0 /*assign various constants & variables.*/
d.=1; d.L=-d.; @.=' '; x=0; x2=x; y=0; y2=y; z=d.; @.x.y=""
plot_pts = '123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZΘ' /*plot chars*/
minX=0; maxX=0; minY=0; maxY=0 /*assign various constants & variables.*/
parse arg # p c . /*#: number of iterations; P=init dir.*/
if #=='' | #=="," then #=11 /*Not specified? Then use the default.*/
if p=='' | p=="," then p=0 /* " " " " " " */
if p=='' | p=="," then p= 'north'; upper p /* " " " " " " */
if c=='' then c=plot_pts /* " " " " " " */
if length(c)==2 then c=x2c(c) /*was a hexadecimal code specified? */
if length(c)==3 then c=d2c(c) /* " " decimal " " */
$= /*assign a null to dragon curve string.*/
do # /* [↓] create (part of) a dragon curve*/
$=$'R'reverse( translate($, "RL", 'LR') ) /*append char, flip, and then reverse.*/
end /*#*/ /* [↑] TRANSLATE (flip) the characters*/
/* [↓] create the dragon curve. */
do j=1 for length($); _=substr($, j, 1) /*obtain the next direction for curve. */
p= (p+d._)//4; if p<0 then p=p+4 /*move dragon curve in a new direction.*/
if p==0 then do; y=y+1; y2=y+1; end /*curve is going east cartologically.*/
if p==1 then do; x=x+1; x2=x+1; end /* " " south " */
if p==2 then do; y=y-1; y2=y-1; end /* " " west " */
if p==3 then do; x=x-1; x2=x-1; end /* " " north " */
if j>2**z then z=z+1 /*identify the dragon curve being built*/
p=translate(left(p,1), 0123, 'NESW'); $= /*get the orientation for dragon curve.*/
do #; $=$'R'reverse(translate($,"RL",'LR')) /*create the start of a dragon curve. */
end /*#*/ /*append char, flip, and then reverse.*/
/* [↓] create the rest of dragon curve*/
do j=1 for length($); _=substr($,j,1) /*get next cardinal direction for curve*/
p= (p+d._)//4; if p<0 then p=p+4 /*move dragon curve in a new direction.*/
if p==0 then do; y=y+1; y2=y+1; end /*curve is going east cartologically.*/
if p==1 then do; x=x+1; x2=x+1; end /* " " south " */
if p==2 then do; y=y-1; y2=y-1; end /* " " west " */
if p==3 then do; x=x-1; x2=x-1; end /* " " north " */
if j>2**z then z=z+1 /*identify a part of curve being built.*/
!=substr(c,z,1); if !==' ' then !=right(c,1) /*choose plot point character (glyph). */
@.x.y=!; @.x2.y2=! /*draw part of the dragon curve. */
minX=min(minX,x,x2); maxX=max(maxX,x,x2); x=x2 /*define the min & max X graph limits*/
minY=min(minY,y,y2); maxY=max(maxY,y,y2); y=y2 /* " " " " " Y " " */
end /*j*/ /* [↑] process all of $ char string.*/
/* [↓] display the dragon curve. */
do r=minX to maxX; a= /*nullify the line that will bee drawn.*/
do c=minY to maxY /*create a line (row) of curve points. */
a=a || @.r.c /*append single column of row at a time*/
end /*c*/
a=strip(a, 'T') /*be nice and strip any trailing blanks*/
if a\=='' then say a /*display a line (row) of curve points.*/
end /*r*/ /*stick a fork in it, we're all done. */
end /*j*/ /* [↑] process all of $ char string.*/
do r=minX to maxX; a= /*nullify the line that will be drawn. */
do c=minY to maxY; a=a || @.r.c /*create a line (row) of curve points. */
end /*c*/ /* [↑] append a single column of a row.*/
if a\='' then say strip(a, 'T') /*display a line (row) of curve points.*/
end /*r*/ /*stick a fork in it, we're all done. */

View file

@ -0,0 +1,38 @@
levels = 16
level = 0
step = 1
>
draw(level)
level += step
? level>levels
step = -1
level += step*2
.
? level=0, step = 1
#.delay(1)
<
draw(level)=
mx,my = #.scrsize()
fs = #.min(mx,my)/2
r = fs/2^((level-1)/2)
x = mx/2+fs*#.sqrt(2)/2
y = my/2+fs/4
a = #.pi/4*(level-2)
#.scroff()
#.scrclear()
#.drawline(x,y,x,y)
ss = 2^level-1
> i, 0..ss
? #.and(#.and(i,-i)*2,i)
a += #.pi/2
!
a -= #.pi/2
.
x += r*#.cos(a)
y += r*#.sin(a)
#.drawcolor(#.hsv2rgb(i/(ss+1)*360,1,1):3)
#.drawline(x,y)
<
#.scr()
.

View file

@ -0,0 +1,36 @@
n_folds=10
folds=[];
folds=[0 1];
old_folds=[];
vectors=[];
i=[];
for i=2:n_folds+1
curve_length=length(folds);
vectors=folds(1:curve_length-1)-folds(curve_length);
vectors=vectors.*exp(90/180*%i*%pi);
new_folds=folds(curve_length)+vectors;
j=curve_length;
while j>1
folds=[folds new_folds(j-1)]
j=j-1;
end
end
scf(0); clf();
xname("Dragon curve: "+string(n_folds)+" folds")
plot2d(real(folds),imag(folds),5);
set(gca(),"isoview","on");
set(gca(),"axes_visible",["off","off","off"]);

View file

@ -1,19 +1,19 @@
define halfpi = Math.pi/2;
define halfpi = Num.pi/2
# Computing the dragon with a L-System
var dragon = 'FX';
var dragon = 'FX'
{
dragon.gsub!('X', 'x+yF+');
dragon.gsub!('Y', '-Fx-y');
dragon.tr!('xy', 'XY');
} * 10;
dragon.gsub!('X', 'x+yF+')
dragon.gsub!('Y', '-Fx-y')
dragon.tr!('xy', 'XY')
} * 10
# Drawing the dragon in SVG
var (x, y) = (100, 100);
var theta = 0;
var r = 2;
var (x, y) = (100, 100)
var theta = 0
var r = 2
print <<'EOT';
print <<'EOT'
<?xml version='1.0' encoding='utf-8' standalone='no'?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN'
'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
@ -24,14 +24,14 @@ EOT
dragon.each { |c|
given(c) {
when ('F') {
printf("<line x1='%.0f' y1='%.0f' ", x, y);
printf("x2='%.0f' ", x += r*Math.cos(theta));
printf("y2='%.0f' ", y += r*Math.sin(theta));
printf("style='stroke:rgb(0,0,0);stroke-width:1'/>\n");
printf("<line x1='%.0f' y1='%.0f' ", x, y)
printf("x2='%.0f' ", x += r*cos(theta))
printf("y2='%.0f' ", y += r*sin(theta))
printf("style='stroke:rgb(0,0,0);stroke-width:1'/>\n")
}
when ('+') { theta += halfpi }
when ('-') { theta -= halfpi }
}
}
print '</svg>';
print '</svg>'

View file

@ -0,0 +1,25 @@
println(0'|<?xml version='1.0' encoding='utf-8' standalone='no'?>|"\n"
0'|<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN'|"\n"
0'|'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>|"\n"
0'|<svg width='100%' height='100%' version='1.1'|"\n"
0'|xmlns='http://www.w3.org/2000/svg'>|);
order:=13.0; # akin to number of recursion steps
d_size:=1000.0; # size in pixels
pi:=(1.0).pi;
turn_angle:=pi/2; # turn angle of each segment, 90 degrees for the canonical dragon
angle:=pi - (order * (pi/4)); # starting angle
len:=(d_size/1.5) / (2.0).sqrt().pow(order); # size of each segment
x:=d_size*5/6; y:=d_size*1/3; # starting point
foreach i in ([0 .. (2.0).pow(order-1)]){
# find which side to turn based on the iteration
angle += i.bitAnd(-i).shiftLeft(1).bitAnd(i) and -turn_angle or turn_angle;
dx:=x + len * angle.sin(); dy:=y - len * angle.cos();
println("<line x1='",x,"' y1='",y,"' x2='",dx,"' y2='",dy,
"' style='stroke:rgb(0,0,0);stroke-width:1'/>");
x=dx; y=dy;
}
println("</svg>");