Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
97
Task/Dragon-curve/JavaScript/dragon-curve-1.js
Normal file
97
Task/Dragon-curve/JavaScript/dragon-curve-1.js
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
var DRAGON = (function () {
|
||||
// MATRIX MATH
|
||||
// -----------
|
||||
|
||||
var matrix = {
|
||||
mult: function ( m, v ) {
|
||||
return [ m[0][0] * v[0] + m[0][1] * v[1],
|
||||
m[1][0] * v[0] + m[1][1] * v[1] ];
|
||||
},
|
||||
|
||||
minus: function ( a, b ) {
|
||||
return [ a[0]-b[0], a[1]-b[1] ];
|
||||
},
|
||||
|
||||
plus: function ( a, b ) {
|
||||
return [ a[0]+b[0], a[1]+b[1] ];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// SVG STUFF
|
||||
// ---------
|
||||
|
||||
// Turn a pair of points into an SVG path like "M1 1L2 2".
|
||||
var toSVGpath = function (a, b) { // type system fail
|
||||
return "M" + a[0] + " " + a[1] + "L" + b[0] + " " + b[1];
|
||||
};
|
||||
|
||||
|
||||
// DRAGON MAKING
|
||||
// -------------
|
||||
|
||||
// Make a dragon with a better fractal algorithm
|
||||
var fractalMakeDragon = function (svgid, ptA, ptC, state, lr, interval) {
|
||||
|
||||
// make a new <path>
|
||||
var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||||
path.setAttribute( "class", "dragon");
|
||||
path.setAttribute( "d", toSVGpath(ptA, ptC) );
|
||||
|
||||
// append the new path to the existing <svg>
|
||||
var svg = document.getElementById(svgid); // call could be eliminated
|
||||
svg.appendChild(path);
|
||||
|
||||
// if we have more iterations to go...
|
||||
if (state > 1) {
|
||||
|
||||
// make a new point, either to the left or right
|
||||
var growNewPoint = function (ptA, ptC, lr) {
|
||||
var left = [[ 1/2,-1/2 ],
|
||||
[ 1/2, 1/2 ]];
|
||||
|
||||
var right = [[ 1/2, 1/2 ],
|
||||
[-1/2, 1/2 ]];
|
||||
|
||||
return matrix.plus(ptA, matrix.mult( lr ? left : right,
|
||||
matrix.minus(ptC, ptA) ));
|
||||
};
|
||||
|
||||
var ptB = growNewPoint(ptA, ptC, lr, state);
|
||||
|
||||
// then recurse using each new line, one left, one right
|
||||
var recurse = function () {
|
||||
// when recursing deeper, delete this svg path
|
||||
svg.removeChild(path);
|
||||
|
||||
// then invoke again for new pair, decrementing the state
|
||||
fractalMakeDragon(svgid, ptB, ptA, state-1, lr, interval);
|
||||
fractalMakeDragon(svgid, ptB, ptC, state-1, lr, interval);
|
||||
};
|
||||
|
||||
window.setTimeout(recurse, interval);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Export these functions
|
||||
// ----------------------
|
||||
return {
|
||||
fractal: fractalMakeDragon
|
||||
|
||||
// ARGUMENTS
|
||||
// ---------
|
||||
// svgid id of <svg> element
|
||||
// ptA first point [x,y] (from top left)
|
||||
// ptC second point [x,y]
|
||||
// state number indicating how many steps to recurse
|
||||
// lr true/false to make new point on left or right
|
||||
|
||||
// CONFIG
|
||||
// ------
|
||||
// CSS rules should be made for the following
|
||||
// svg#fractal
|
||||
// svg path.dragon
|
||||
};
|
||||
|
||||
}());
|
||||
10
Task/Dragon-curve/JavaScript/dragon-curve-2.js
Normal file
10
Task/Dragon-curve/JavaScript/dragon-curve-2.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
...
|
||||
<script src='./dragon.js'></script>
|
||||
...
|
||||
<div>
|
||||
<svg xmlns='http://www.w3.org/2000/svg' id='fractal'></svg>
|
||||
</div>
|
||||
<script>
|
||||
DRAGON.fractal('fractal', [100,300], [500,300], 15, false, 700);
|
||||
</script>
|
||||
...
|
||||
42
Task/Dragon-curve/JavaScript/dragon-curve-3.js
Normal file
42
Task/Dragon-curve/JavaScript/dragon-curve-3.js
Normal 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>
|
||||
348
Task/Dragon-curve/JavaScript/dragon-curve-4.js
Normal file
348
Task/Dragon-curve/JavaScript/dragon-curve-4.js
Normal file
|
|
@ -0,0 +1,348 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// ------------------ DRAGON CURVE -------------------
|
||||
|
||||
// dragonCurve :: [[Int]] -> [[Int]]
|
||||
const dragonCurve = xs => {
|
||||
const
|
||||
pivot = op => map(
|
||||
zipWith(op)(last(xs))
|
||||
),
|
||||
r90 = [
|
||||
[0, 1],
|
||||
[-1, 0]
|
||||
];
|
||||
return compose(
|
||||
append(xs),
|
||||
pivot(add),
|
||||
flip(matrixMultiply)(r90),
|
||||
pivot(subtract),
|
||||
reverse,
|
||||
init
|
||||
)(xs);
|
||||
};
|
||||
|
||||
|
||||
// ---------------------- TEST -----------------------
|
||||
// main :: IO ()
|
||||
const main = () =>
|
||||
// SVG of 12th iteration.
|
||||
console.log(
|
||||
svgFromPointLists(512)(512)(
|
||||
index(iterate(dragonCurve)([
|
||||
[0, 0],
|
||||
[0, -1]
|
||||
]))(12)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
// ----------------------- SVG -----------------------
|
||||
|
||||
// svgFromPointLists :: Int -> Int ->
|
||||
// [[(Int, Int)]] -> String
|
||||
const svgFromPointLists = cw => ch =>
|
||||
xyss => {
|
||||
const
|
||||
polyline = xs =>
|
||||
`<polyline points="${unwords(concat(xs).map(showJSON))}"/>`,
|
||||
[x, y, mx, my] = ap([minimum, maximum])(
|
||||
Array.from(unzip(concat(xyss)))
|
||||
),
|
||||
[wd, hd] = map(x => Math.floor(x / 10))([
|
||||
mx - x, my - y
|
||||
]);
|
||||
return unlines([
|
||||
'<?xml version="1.0" encoding="UTF-8"?>',
|
||||
unwords([
|
||||
'<svg',
|
||||
`width="${cw}" height="${ch}"`,
|
||||
`viewBox="${x - wd} ${y - hd} ${12 * wd} ${12 * hd}"`,
|
||||
'xmlns="http://www.w3.org/2000/svg">'
|
||||
]),
|
||||
'<g stroke-width="0.2" stroke="red" fill="none">',
|
||||
unlines(map(polyline)(xyss)),
|
||||
'</g>',
|
||||
'</svg>'
|
||||
]);
|
||||
};
|
||||
|
||||
|
||||
// ---------------- GENERIC FUNCTIONS ----------------
|
||||
|
||||
// Just :: a -> Maybe a
|
||||
const Just = x => ({
|
||||
type: 'Maybe',
|
||||
Nothing: false,
|
||||
Just: x
|
||||
});
|
||||
|
||||
|
||||
// Nothing :: Maybe a
|
||||
const Nothing = () => ({
|
||||
type: 'Maybe',
|
||||
Nothing: true,
|
||||
});
|
||||
|
||||
|
||||
// Tuple (,) :: a -> b -> (a, b)
|
||||
const Tuple = a =>
|
||||
b => ({
|
||||
type: 'Tuple',
|
||||
'0': a,
|
||||
'1': b,
|
||||
length: 2
|
||||
});
|
||||
|
||||
|
||||
// add (+) :: Num a => a -> a -> a
|
||||
const add = a =>
|
||||
// Curried addition.
|
||||
b => a + b;
|
||||
|
||||
|
||||
// ap (<*>) :: [(a -> b)] -> [a] -> [b]
|
||||
const ap = fs =>
|
||||
// The sequential application of each of a list
|
||||
// of functions to each of a list of values.
|
||||
xs => fs.flatMap(
|
||||
f => xs.map(f)
|
||||
);
|
||||
|
||||
// append (++) :: [a] -> [a] -> [a]
|
||||
// append (++) :: String -> String -> String
|
||||
const append = xs =>
|
||||
// A list or string composed by
|
||||
// the concatenation of two others.
|
||||
ys => xs.concat(ys);
|
||||
|
||||
|
||||
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
|
||||
const compose = (...fs) =>
|
||||
fs.reduce(
|
||||
(f, g) => x => f(g(x)),
|
||||
x => x
|
||||
);
|
||||
|
||||
|
||||
// concat :: [[a]] -> [a]
|
||||
const concat = xs => [].concat(...xs);
|
||||
|
||||
|
||||
// dotProduct :: Num a => [[a]] -> [[a]] -> [[a]]
|
||||
const dotProduct = xs =>
|
||||
compose(sum, zipWith(mul)(xs));
|
||||
|
||||
|
||||
// enumFromTo :: Int -> Int -> [Int]
|
||||
const enumFromTo = m =>
|
||||
n => Array.from({
|
||||
length: 1 + n - m
|
||||
}, (_, i) => m + i);
|
||||
|
||||
|
||||
// flip :: (a -> b -> c) -> b -> a -> c
|
||||
const flip = f =>
|
||||
x => y => f(y)(x);
|
||||
|
||||
|
||||
// index (!!) :: [a] -> Int -> Maybe a
|
||||
// index (!!) :: Generator (a) -> Int -> Maybe a
|
||||
// index (!!) :: String -> Int -> Maybe Char
|
||||
const index = xs =>
|
||||
i => (
|
||||
drop(i)(xs),
|
||||
take(1)(xs)
|
||||
);
|
||||
|
||||
|
||||
// drop :: Int -> [a] -> [a]
|
||||
// drop :: Int -> Generator [a] -> Generator [a]
|
||||
// drop :: Int -> String -> String
|
||||
const drop = n =>
|
||||
xs => Infinity > length(xs) ? (
|
||||
xs.slice(n)
|
||||
) : (take(n)(xs), xs);
|
||||
|
||||
|
||||
// init :: [a] -> [a]
|
||||
const init = xs =>
|
||||
// All elements of a list except the last.
|
||||
0 < xs.length ? (
|
||||
xs.slice(0, -1)
|
||||
) : undefined;
|
||||
|
||||
|
||||
// iterate :: (a -> a) -> a -> Gen [a]
|
||||
const iterate = f =>
|
||||
function* (x) {
|
||||
let v = x;
|
||||
while (true) {
|
||||
yield(v);
|
||||
v = f(v);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// last :: [a] -> a
|
||||
const last = xs =>
|
||||
// The last item of a list.
|
||||
0 < xs.length ? xs.slice(-1)[0] : undefined;
|
||||
|
||||
|
||||
// length :: [a] -> Int
|
||||
const length = xs =>
|
||||
// Returns Infinity over objects without finite
|
||||
// length. This enables zip and zipWith to choose
|
||||
// the shorter argument when one is non-finite,
|
||||
// like cycle, repeat etc
|
||||
(Array.isArray(xs) || 'string' === typeof xs) ? (
|
||||
xs.length
|
||||
) : Infinity;
|
||||
|
||||
|
||||
// map :: (a -> b) -> [a] -> [b]
|
||||
const map = f =>
|
||||
// The list obtained by applying f
|
||||
// to each element of xs.
|
||||
// (The image of xs under f).
|
||||
xs => xs.map(f);
|
||||
|
||||
|
||||
// matrixMultiply :: Num a => [[a]] -> [[a]] -> [[a]]
|
||||
const matrixMultiply = a =>
|
||||
b => {
|
||||
const cols = transpose(b);
|
||||
return map(
|
||||
compose(
|
||||
flip(map)(cols),
|
||||
dotProduct
|
||||
)
|
||||
)(a);
|
||||
};
|
||||
|
||||
// minimum :: Ord a => [a] -> a
|
||||
const minimum = xs =>
|
||||
0 < xs.length ? (
|
||||
xs.slice(1)
|
||||
.reduce((a, x) => x < a ? x : a, xs[0])
|
||||
) : undefined;
|
||||
|
||||
|
||||
// maximum :: Ord a => [a] -> a
|
||||
const maximum = xs =>
|
||||
// The largest value in a non-empty list.
|
||||
0 < xs.length ? (
|
||||
xs.slice(1).reduce(
|
||||
(a, x) => x > a ? (
|
||||
x
|
||||
) : a, xs[0]
|
||||
)
|
||||
) : undefined;
|
||||
|
||||
|
||||
// mul (*) :: Num a => a -> a -> a
|
||||
const mul = a =>
|
||||
b => a * b;
|
||||
|
||||
|
||||
// reverse :: [a] -> [a]
|
||||
const reverse = xs =>
|
||||
xs.slice(0).reverse();
|
||||
|
||||
|
||||
// showJSON :: a -> String
|
||||
const showJSON = x =>
|
||||
// Indented JSON representation of the value x.
|
||||
JSON.stringify(x, null, 2);
|
||||
|
||||
|
||||
// subtract :: Num -> Num -> Num
|
||||
const subtract = x =>
|
||||
y => y - x;
|
||||
|
||||
|
||||
// sum :: [Num] -> Num
|
||||
const sum = xs =>
|
||||
// The numeric sum of all values in xs.
|
||||
xs.reduce((a, x) => a + x, 0);
|
||||
|
||||
|
||||
// take :: Int -> [a] -> [a]
|
||||
// take :: Int -> String -> String
|
||||
const take = n =>
|
||||
// The first n elements of a list,
|
||||
// string of characters, or stream.
|
||||
xs => 'GeneratorFunction' !== xs
|
||||
.constructor.constructor.name ? (
|
||||
xs.slice(0, n)
|
||||
) : [].concat.apply([], Array.from({
|
||||
length: n
|
||||
}, () => {
|
||||
const x = xs.next();
|
||||
return x.done ? [] : [x.value];
|
||||
}));
|
||||
|
||||
|
||||
// transpose :: [[a]] -> [[a]]
|
||||
const transpose = rows =>
|
||||
// The columns of the input transposed
|
||||
// into new rows.
|
||||
// Simpler version of transpose, assuming input
|
||||
// rows of even length.
|
||||
0 < rows.length ? rows[0].map(
|
||||
(x, i) => rows.flatMap(
|
||||
x => x[i]
|
||||
)
|
||||
) : [];
|
||||
|
||||
|
||||
// unlines :: [String] -> String
|
||||
const unlines = xs =>
|
||||
// A single string formed by the intercalation
|
||||
// of a list of strings with the newline character.
|
||||
xs.join('\n');
|
||||
|
||||
|
||||
// until :: (a -> Bool) -> (a -> a) -> a -> a
|
||||
const until = p => f => x => {
|
||||
let v = x;
|
||||
while (!p(v)) v = f(v);
|
||||
return v;
|
||||
};
|
||||
|
||||
|
||||
// unwords :: [String] -> String
|
||||
const unwords = xs =>
|
||||
// A space-separated string derived
|
||||
// from a list of words.
|
||||
xs.join(' ');
|
||||
|
||||
|
||||
// unzip :: [(a,b)] -> ([a],[b])
|
||||
const unzip = xys =>
|
||||
xys.reduce(
|
||||
(ab, xy) => Tuple(ab[0].concat(xy[0]))(
|
||||
ab[1].concat(xy[1])
|
||||
),
|
||||
Tuple([])([])
|
||||
);
|
||||
|
||||
|
||||
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
|
||||
const zipWith = f =>
|
||||
// A list constructed by zipping with a
|
||||
// custom function, rather than with the
|
||||
// default tuple constructor.
|
||||
xs => ys => {
|
||||
const
|
||||
lng = Math.min(length(xs), length(ys)),
|
||||
vs = take(lng)(ys);
|
||||
return take(lng)(xs)
|
||||
.map((x, i) => f(x)(vs[i]));
|
||||
};
|
||||
|
||||
// MAIN ---
|
||||
return main();
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue