Commit 227272c7 authored by Nicaudie Charlotte's avatar Nicaudie Charlotte

c'était fun merci pascalou <3 /-\_/

parent fbdbbe56
......@@ -6,8 +6,8 @@
type init = float * float * float * float
type stmt =
| Translation of float * float
| Rotation of float * float * float
| Translation of float
| Rotation of float
| StmtList of stmt list
| Or of stmt * stmt * float (* Float is the left-member's random weightening *)
| Iter of stmt * int * int (* Min and max number of iteration *)
......
......@@ -39,8 +39,12 @@ let () =
exit 1
end;
(* Modification de l'extension pour le fichier de sortie *)
ofile := (Filename.chop_extension !ifile) ^ ".html";
(* Ouverture du fichier source en lecture *)
let f = open_in !ifile in
let out = open_out !ofile in
(* Création d'un tampon d'analyse lexicale *)
let buf = Lexing.from_channel f in
......@@ -54,15 +58,15 @@ let () =
let p = Parser.program Lexer.get_token buf in
(*Print_tokens.print stdout buf;*)
close_in f;
(* On s'arrête ici si on ne veut faire que le parsing *)
if !parse_only then exit 0;
(*Interp.prog p*)
(* () = void *)
Print_ast.program2js out p;
Turtle2js.program2js out p;
close_out out;
exit 0
with
| Lexer.Lexing_error c ->
......
......@@ -57,11 +57,11 @@ program:
}
stmt:
| TRANSLATION LPAREN x = FLOAT COMMA y = FLOAT RPAREN SEMICOLON
{ Translation (x, y) }
| ROTATION LPAREN x = FLOAT COMMA y = FLOAT COMMA theta = FLOAT RPAREN SEMICOLON
{ Rotation (x, y, theta) }
| s1 = stmt OR weight = FLOAT s2 = stmt
| TRANSLATION LPAREN x = FLOAT RPAREN SEMICOLON
{ Translation x }
| ROTATION LPAREN theta = FLOAT RPAREN SEMICOLON
{ Rotation theta }
| s1 = stmt OR LPAREN weight = FLOAT RPAREN s2 = stmt
{ Or (s1, s2, weight) }
| ITER LPAREN it1 = INT COMMA it2 = INT RPAREN s = stmt %prec ITER
{ Iter (s, it1, it2) }
......
open Printf
open Ast
let init2js init =
match init with
| (xmin, xmax, ymin, ymax) -> Printf.sprintf "init(%f, %f, %f, %f);\n\ " xmin xmax ymin ymax
let rec stmt2jsToString stmt =
let rec stmtListToString list accStr =
match list with
| head::tail -> let newStr = accStr ^ (stmt2jsToString head) in (stmtListToString tail newStr)
| [] -> accStr
in
match stmt with
| Translation length -> Printf.sprintf "Translation(%f)\n" length
| Rotation angle -> Printf.sprintf "Rotation(%f)\n" angle
| StmtList stmtList -> Printf.sprintf "Stmt list : %s\n" (stmtListToString stmtList "")
| Or (stmt1, stmt2, proba) -> Printf.sprintf
"Or(%f) : %s, %s\n" proba (stmt2jsToString stmt1) (stmt2jsToString stmt2)
| Iter (s, minNbIterations, maxNbIterations) -> Printf.sprintf
"Iter(%d, %d) : %s\n" minNbIterations maxNbIterations (stmt2jsToString s)
let program2js out program =
match program with
| (init, stmt) -> Printf.printf "Program(%s,\n\ %s);\n\ "(init2js init) (stmt2jsToString stmt)
(*| _ -> Printf.printf "C\'est caca"*)
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TrucTurtle</title>
<style type="text/css">
html, body {
margin: 0;
}
html {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
height: 100;
}
body {
overflow: hidden;
height: inherit;
}
h1 {
font-size: 2rem;
letter-spacing: -1px;
position: absolute;
margin: 0;
top: -4px;
right: 5px;
color: transparent;
text-shadow: 0 0 4px white;
}
</style>
</head>
<body>
<h1>Truc</h1>
<canvas></canvas>
<script>
// =========== CANVAS SETUP =========== //
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
// =========== CONSTANTS AND VARIABLES =========== //
const width = canvas.width = window.innerWidth;
const height = canvas.height = window.innerHeight;
let START_POSITION_X = 0;
let START_POSITION_Y = 0;
let BASE_ORIENTATION_X = 1;
let BASE_ORIENTATION_Y = 0;
// =========== PEN DEFINITION =========== //
// Pen constuctor
function Pen(xPosition, yPosition, xOrientation, yOrientation) {
this.position = [xPosition, yPosition];
this.orientation = [xOrientation, yOrientation];
}
Pen.prototype.translate = function (distance) {
let newDirection = [this.orientation[0] * distance, this.orientation[1] * distance];
this.position[0] += newDirection[0];
this.position[1] += newDirection[1];
ctx.lineTo(this.position[0], this.position[1]);
}
Pen.prototype.rotate = function (angle) {
// Cast angle from degrees to radians
let angleRadians = (angle * Math.PI) / 180;
// Compute new orientation vector
let newOrientationX = (this.orientation[0] * Math.cos(angleRadians)) - (this.orientation[1] * Math.sin(angleRadians));
let newOrientationY = (this.orientation[0] * Math.sin(angleRadians)) + (this.orientation[1] * Math.cos(angleRadians));
// Normalize orientation
let normalizedOrientationX = newOrientationX / (Math.sqrt((newOrientationX ** 2) + (newOrientationY ** 2)));
let normalizedOrientationY = newOrientationY / (Math.sqrt((newOrientationX ** 2) + (newOrientationY ** 2)));
// Set the orientation vector to the new normalized one
this.orientation = [+(normalizedOrientationX.toFixed(2)), +(normalizedOrientationY.toFixed(2))];
}
// =========== UTILS FUNCTIONS =========== //
/**
* Builds a random value between min and max values
*
* @param {*} minValue minimum bound
* @param {*} maxValue maximum bound
* @returns A float between minValue and maxValue
*/
function random (minValue, maxValue) {
return Math.floor(Math.random() * (maxValue - minValue)) + minValue;
}
/**
* Initialize the starting position of the Pen.
*
* Float range for XY coordinates
* X between x1 and x2
* Y between y1 and y2
*
* @param {*} x1 X min
* @param {*} x2 X max
* @param {*} y1 Y min
* @param {*} y2 Y max
*/
function init (x1, x2, y1, y2) {
let xMin = Math.min(x1, x2);
let xMax = Math.max(x1, x2);
let yMin = Math.min(y1, y2);
let yMax = Math.max(y1, y2);
// Apply value correction if necessary
if ((xMin > width) || (xMin < 0))
{
xMin = random(0, width / 2);
}
else if ((xMax > width) || (xMax < 0))
{
xMax = random(width / 2, width);
}
else if ((yMin > height) || (yMin < 0))
{
yMin = random(0, height / 2);
}
else if ((yMax > height) || (yMax < 0))
{
yMax = random(height / 2, height);
}
// Apply starting position
START_POSITION_X = random(xMin, xMax);
START_POSITION_Y = random(yMin, yMax);
}
// =========== MAIN DRAWING =========== //
// Init start positions
init(0.000000, 300.000000, 0.000000, 300.000000);
// Create a pen
let pen = new Pen(START_POSITION_X, START_POSITION_Y, BASE_ORIENTATION_X, BASE_ORIENTATION_Y);
// BEGIN OF THE DRAWING
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(pen.position[0], pen.position[1]); // Go to init coordinates
// === BEGIN OF CHANGING PART
for (let i = 0 ; i < random(10, 100); i++) {
if (Math.random() < 0.500000) {
pen.translate(50.000000)
}
else
{
pen.rotate(45.000000)
}
}
// === END OF CHANGING PART
// END OF THE DRAWING
ctx.stroke();
ctx.closePath();
</script>
</body>
</html>
......@@ -3,11 +3,12 @@ Sample code provided by Pascal the Mr. Cooder
Thank you Pascal <3
*)
init(0,1,0,1) # Starting position (x,y) in [0,1]*[0,1]
iter(10,100) {
init(0.0,300.0,0.0,300.0) # Starting position (x,y) in [0,1]*[0,1]
{
iter(10,100)
{
translation(1, 0);
or(0.5)
rotation(0.05, 0.5, 0.5);
translation(50.0);
or(0.5)
rotation(45.0);
}
}
\ No newline at end of file
......@@ -140,4 +140,173 @@ else
// END OF THE DRAWING
ctx.stroke();
ctx.closePath();
\ No newline at end of file
ctx.closePath();
"<!DOCTYPE html>\n\
<html>\n\
<head>\n\
<meta charset=\"utf-8\">\n\
<title>%a</title>\n\
<style type=\"text/css\">\n\
html, body {\n\
margin: 0;\n\
}\n\
\n\
html {\n\
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;\n\
height: 100%;\n\
}\n\
\n\
body {\n\
overflow: hidden;\n\
height: inherit;\n\
}\n\
\n\
h1 {\n\
font-size: 2rem;\n\
letter-spacing: -1px;\n\
position: absolute;\n\
margin: 0;\n\
top: -4px;\n\
right: 5px;\n\
\n\
color: transparent;\n\
text-shadow: 0 0 4px white;\n\
}\n\
</style>\n\
</head>\n\
\n\
<body>\n\
<h1>%a</h1>\n\
<canvas></canvas>\n\
<script>\n\
// =========== CANVAS SETUP =========== //\n\
\n\
const canvas = document.querySelector('canvas');\n\
const ctx = canvas.getContext('2d');\n\
\n\
// =========== CONSTANTS AND VARIABLES =========== //\n\
\n\
const width = canvas.width = window.innerWidth;\n\
const height = canvas.height = window.innerHeight;\n\
\n\
let START_POSITION_X = 0;\n\
let START_POSITION_Y = 0;\n\
\n\
let BASE_ORIENTATION_X = 1;\n\
let BASE_ORIENTATION_Y = 0;\n\
\n\
// =========== PEN DEFINITION =========== //\n\
\n\
// Pen constuctor\n\
function Pen(xPosition, yPosition, xOrientation, yOrientation) {\n\
this.position = [xPosition, yPosition];\n\
this.orientation = [xOrientation, yOrientation];\n\
}\n\
\n\
Pen.prototype.translate = function (distance) {\n\
let newDirection = [this.orientation[0] * distance, this.orientation[1] * distance];\n\
this.position[0] += newDirection[0];\n\
this.position[1] += newDirection[1];\n\
ctx.lineTo(this.position[0], this.position[1]);\n\
}\n\
\n\
Pen.prototype.rotate = function (angle) {\n\
// Cast angle from degrees to radians\n\
let angleRadians = (angle * Math.PI) / 180;\n\
\n\
// Compute new orientation vector\n\
let newOrientationX = (this.orientation[0] * Math.cos(angleRadians)) - (this.orientation[1] * Math.sin(angleRadians)); \n\
let newOrientationY = (this.orientation[0] * Math.sin(angleRadians)) + (this.orientation[1] * Math.cos(angleRadians)); \n\
\n\
// Normalize orientation\n\
let normalizedOrientationX = newOrientationX / (Math.sqrt((newOrientationX ** 2) + (newOrientationY ** 2)));\n\
let normalizedOrientationY = newOrientationY / (Math.sqrt((newOrientationX ** 2) + (newOrientationY ** 2)));\n\
\n\
// Set the orientation vector to the new normalized one\n\
this.orientation = [+(normalizedOrientationX.toFixed(2)), +(normalizedOrientationY.toFixed(2))];\n\
}\n\
\n\
// =========== UTILS FUNCTIONS =========== //\n\
\n\
/**\n\
* Builds a random value between min and max values\n\
* \n\
* @param {*} minValue minimum bound\n\
* @param {*} maxValue maximum bound\n\
* @returns A float between minValue and maxValue\n\
*/\n\
function random (minValue, maxValue) {\n\
return Math.floor(Math.random() * (maxValue - minValue)) + minValue;\n\
}\n\
\n\
/**\n\
* Initialize the starting position of the Pen.\n\
* \n\
* Float range for XY coordinates\n\
* X between x1 and x2\n\
* Y between y1 and y2\n\
* \n\
* @param {*} x1 X min\n\
* @param {*} x2 X max\n\
* @param {*} y1 Y min\n\
* @param {*} y2 Y max\n\
*/\n\
function init (x1, x2, y1, y2) {\n\
let xMin = Math.min(x1, x2);\n\
let xMax = Math.max(x1, x2);\n\
let yMin = Math.min(y1, y2);\n\
let yMax = Math.max(y1, y2);\n\
\n\
// Apply value correction if necessary\n\
if ((xMin > width) || (xMin < 0)) \n\
{\n\
xMin = random(0, width / 2);\n\
}\n\
else if ((xMax > width) || (xMax < 0)) \n\
{\n\
xMax = random(width / 2, width);\n\
}\n\
else if ((yMin > height) || (yMin < 0)) \n\
{\n\
yMin = random(0, height / 2);\
}\n\
else if ((yMax > height) || (yMax < 0)) \n\
{\n\
yMax = random(height / 2, height);\n\
}\n\
\n\
// Apply starting position\n\
START_POSITION_X = random(xMin, xMax);\n\
START_POSITION_Y = random(yMin, yMax);\n\
}\n\
\n\
// =========== MAIN DRAWING =========== //\n\
\n\
// Init start positions\n\
%a\n\
\n\
// Create a pen\n\
let pen = new Pen(START_POSITION_X, START_POSITION_Y, BASE_ORIENTATION_X, BASE_ORIENTATION_Y);\n\
\n\
// BEGIN OF THE DRAWING\n\
ctx.lineWidth = 6;\n\
\n\
ctx.beginPath();\n\
ctx.moveTo(pen.position[0], pen.position[1]); // Go to init coordinates\n\
\n\
// === BEGIN OF CHANGING PART\n\
\n\
%a\n\
\n\
// === END OF CHANGING PART\n\
\n\
// END OF THE DRAWING\n\
ctx.stroke();\n\
ctx.closePath();\n\
\n\
</script>\n\
</body>\n\
</html>\n\
"
\ No newline at end of file
let program2c out (p : MJ.program) : unit =
fprintf out
open Printf
open Ast
let init2js init =
match init with
| (xmin, xmax, ymin, ymax) -> Printf.sprintf "init(%f, %f, %f, %f);\n" xmin xmax ymin ymax
let rec stmt2jsToString stmt =
let rec stmtListToString list accStr =
match list with
| head::tail -> let newStr = accStr ^ (stmt2jsToString head) in (stmtListToString tail newStr)
| [] -> accStr
in
match stmt with
| Translation length -> Printf.sprintf "pen.translate(%f)\n" length
| Rotation angle -> Printf.sprintf "pen.rotate(%f)\n" angle
| StmtList stmtList -> Printf.sprintf "%s" (stmtListToString stmtList "")
| Or (stmt1, stmt2, proba) -> Printf.sprintf
"if (Math.random() < %f) {\n\ %s\ }\n\ else\n\ {\n\ %s\ }\n" proba (stmt2jsToString stmt1) (stmt2jsToString stmt2)
| Iter (s, minNbIterations, maxNbIterations) -> Printf.sprintf
"for (let i = 0 ; i < random(%d, %d); i++) {\n\ %s\ }\n" minNbIterations maxNbIterations (stmt2jsToString s)
let program2js out program =
match program with
| (init, stmt) ->
fprintf out
"<!DOCTYPE html>\n\
<html>\n\
<head>\n\
<meta charset=\"utf-8\">\n\
<title>%a</title>\n\
<title>TrucTurtle</title>\n\
<style type=\"text/css\">\n\
html, body {\n\
margin: 0;\n\
......@@ -12,7 +40,7 @@ let program2c out (p : MJ.program) : unit =
\n\
html {\n\
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;\n\
height: 100%;\n\
height: 100;\n\
}\n\
\n\
body {\n\
......@@ -35,36 +63,137 @@ let program2c out (p : MJ.program) : unit =
</head>\n\
\n\
<body>\n\
<h1>%a</h1>\n\
<h1>Truc</h1>\n\
<canvas></canvas>\n\
<script>\n\
// Canvas setup\n\
const canvas = document.querySelector('canvas');\n\
const ctx = canvas.getContext('2d');\n\
\n\
const width = canvas.width = window.innerWidth;\n\
const height = canvas.height = window.innerHeight;\n\
\n\
// Function to generate a random number\n\
\n\
function random(min,max) {\n\
const num = Math.floor(Math.random()*(max-min)) + min;\n\
return num;\n\
}\n\
\n\
// Variables\n\
%a\
\n\
// Methods\n\
%a\
\n\
// Animation\n\
function loop() {\n\
%a\n\
requestAnimationFrame(loop);\n\
}\n\
loop();\n\
// =========== CANVAS SETUP =========== //\n\
\n\
const canvas = document.querySelector('canvas');\n\
const ctx = canvas.getContext('2d');\n\
\n\
// =========== CONSTANTS AND VARIABLES =========== //\n\
\n\
const width = canvas.width = window.innerWidth;\n\
const height = canvas.height = window.innerHeight;\n\
\n\
let START_POSITION_X = 0;\n\
let START_POSITION_Y = 0;\n\
\n\
let BASE_ORIENTATION_X = 1;\n\
let BASE_ORIENTATION_Y = 0;\n\
\n\
// =========== PEN DEFINITION =========== //\n\
\n\
// Pen constuctor\n\
function Pen(xPosition, yPosition, xOrientation, yOrientation) {\n\
this.position = [xPosition, yPosition];\n\
this.orientation = [xOrientation, yOrientation];\n\
}\n\
\n\
Pen.prototype.translate = function (distance) {\n\
let newDirection = [this.orientation[0] * distance, this.orientation[1] * distance];\n\
this.position[0] += newDirection[0];\n\
this.position[1] += newDirection[1];\n\
ctx.lineTo(this.position[0], this.position[1]);\n\
}\n\
\n\
Pen.prototype.rotate = function (angle) {\n\
// Cast angle from degrees to radians\n\
let angleRadians = (angle * Math.PI) / 180;\n\
\n\
// Compute new orientation vector\n\
let newOrientationX = (this.orientation[0] * Math.cos(angleRadians)) - (this.orientation[1] * Math.sin(angleRadians)); \n\
let newOrientationY = (this.orientation[0] * Math.sin(angleRadians)) + (this.orientation[1] * Math.cos(angleRadians)); \n\
\n\
// Normalize orientation\n\
let normalizedOrientationX = newOrientationX / (Math.sqrt((newOrientationX ** 2) + (newOrientationY ** 2)));\n\
let normalizedOrientationY = newOrientationY / (Math.sqrt((newOrientationX ** 2) + (newOrientationY ** 2)));\n\
\n\
// Set the orientation vector to the new normalized one\n\
this.orientation = [+(normalizedOrientationX.toFixed(2)), +(normalizedOrientationY.toFixed(2))];\n\
}\n\
\n\
// =========== UTILS FUNCTIONS =========== //\n\
\n\
/**\n\
* Builds a random value between min and max values\n\
* \n\
* @param {*} minValue minimum bound\n\
* @param {*} maxValue maximum bound\n\
* @returns A float between minValue and maxValue\n\
*/\n\
function random (minValue, maxValue) {\n\
return Math.floor(Math.random() * (maxValue - minValue)) + minValue;\n\
}\n\
\n\
/**\n\
* Initialize the starting position of the Pen.\n\
* \n\
* Float range for XY coordinates\n\
* X between x1 and x2\n\
* Y between y1 and y2\n\
* \n\
* @param {*} x1 X min\n\
* @param {*} x2 X max\n\
* @param {*} y1 Y min\n\
* @param {*} y2 Y max\n\
*/\n\
function init (x1, x2, y1, y2) {\n\
let xMin = Math.min(x1, x2);\n\