Commit c8b78c34 authored by Nicaudie Charlotte's avatar Nicaudie Charlotte

Merge branch 'modifsPascal' into develop

parents 48262cd3 227272c7
......@@ -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 ->
......
......@@ -10,12 +10,12 @@
%token INIT ITER
%token TRANSLATION ROTATION
%token COMMA SEMICOLON
%token BEGIN END
%token BEGIN END
%token OR
%token LPAREN RPAREN
%token EOF
(*
%token DEF IF ELSE
%token DEF IF ELSE
%token PLUS MINUS TIMES DIV
%token REPEAT PENUP PENDOWN FORWARD TURNLEFT TURNRIGHT
%token COLOR BLACK WHITE RED GREEN BLUE
......@@ -25,6 +25,9 @@
Tokens priorities and associativities
*/
%nonassoc OR
%nonassoc ITER
%nonassoc FLOAT
(*
%left MINUS PLUS
%left TIMES DIV
......@@ -33,13 +36,13 @@
%nonassoc ELSE
*)
/*
Grammar entry point
/*
Grammar entry point
*/
%start program
/*
/*
Value types returned by the parser
*/
......@@ -48,19 +51,19 @@
%%
program:
| INIT LPAREN xmin = FLOAT COMMA xmax = FLOAT COMMA ymin = FLOAT COMMA ymax = FLOAT RPAREN s = stmt EOF
| INIT LPAREN xmin = FLOAT COMMA xmax = FLOAT COMMA ymin = FLOAT COMMA ymax = FLOAT RPAREN s = stmt EOF
{
((xmin, xmax, ymin, ymax), s)
}
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) }
| BEGIN s1 = stmt OR LPAREN weight = FLOAT RPAREN s2 = stmt END
| 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 BEGIN s = stmt END
| ITER LPAREN it1 = INT COMMA it2 = INT RPAREN s = stmt %prec ITER
{ Iter (s, it1, it2) }
| BEGIN stmtList = stmt* END
{ StmtList stmtList }
......
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
// setup canvas
// =========== 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;
// function to generate random number
function random(min,max) {
const num = Math.floor(Math.random()*(max-min)) + min;
return num;
}
let STARTING_POSITION_X = random(0, 1 * width); // random(%f,%f) avec les 2 premiers floats du INIT
let STARTING_POSITION_Y = random(0, 1 * height); // random(%f,%f) avec les 2 derniers floats du INIT
let START_POSITION_X = 0;
let START_POSITION_Y = 0;
let alpha = 0.0; // TODO rendre ceci paramétrable avec un %f
let MIN_SIZE = 10; // TODO rendre ceci paramétrable avec un %f
let MAX_SIZE = 20; // TODO rendre ceci paramétrable avec un %f
let MIN_SPEED = -7; // TODO rendre ceci paramétrable avec un %f
let MAX_SPEED = 7; // TODO rendre ceci paramétrable avec un %f
let BASE_ORIENTATION_X = 1;
let BASE_ORIENTATION_Y = 0;
let ORIENTATION_X = 0;
let ORIENTATION_Y = 0;
// =========== PEN DEFINITION =========== //
// Ball constuctor
function Ball(xPosition, yPosition, xOrientation, yOrientation, xVelocity, yVelocity, color, size) {
// Pen constuctor
function Pen(xPosition, yPosition, xOrientation, yOrientation) {
this.position = [xPosition, yPosition];
this.orientation = [xOrientation, yOrientation];
this.velocity = [xVelocity, yVelocity];
this.color = color;
this.size = size;
}
// Ball methods
Ball.prototype.draw = function () {
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.arc(this.position[0], this.position[1], this.size, 0, 2*Math.PI);
ctx.fill();
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]);
}
Ball.prototype.update = function () {
if((this.position[0] + this.size) >= width){
this.velocity[0] = -(this.velocity[0]);
}
if((this.position[1] + this.size) >= height){
this.velocity[1] = -(this.velocity[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))];
}
if((this.position[0] - this.size) <= 0){
this.velocity[0] = -(this.velocity[0]);
}
if((this.position[1] - this.size) <= 0){
this.velocity[1] = -(this.velocity[1]);
}
// =========== UTILS FUNCTIONS =========== //
this.position[0] += this.velocity[0];
this.position[1] += this.velocity[1];
/**
* 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;
}
Ball.prototype.translate = function (dx, dy) {
// TODO : Voir s'il faut faire une incrémentation
// progressive pour mieux observer le tracé de la ligne
this.position[0] += dx;
this.position[1] += dy;
if (this.position[0] > width) {
this.position[0] = width;
}
else if (this.position[0] < 0) {
this.position[0] = 0;
}
else if (this.position[1] > height) {
this.position[1] = height;
/**
* 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))
{
console.warn("Choosen x1 is out of the screen !");
xMin = random(0, width / 2);
}
else if (this.position[1] < 0) {
this.position[1] = 0;
else if ((xMax > width) || (xMax < 0))
{
console.warn("Choosen x2 is out of the screen !");
xMax = random(width / 2, width);
}
else if ((yMin > height) || (yMin < 0))
{
console.warn("Choosen y1 is out of the screen !");
yMin = random(0, height / 2);
}
else if ((yMax > height) || (yMax < 0))
{
console.warn("Choosen y2 is out of the screen !");
yMax = random(height / 2, height);
}
// Apply starting position
START_POSITION_X = random(xMin, xMax);
START_POSITION_Y = random(yMin, yMax);
}
Ball.prototype.rotate = function (angle) {
let angleRadians = angle * Mathis.PI / 180;
// =========== MAIN DRAWING =========== //
let rotationMatrix = [[Math.cos(angleRadians), -Math.sin(angleRadians)],
[Math.sin(angleRadians), Math.cos(angleRadians)]];
// Init start positions
init(0.0, 300.0, 0.0, 300.0); // TODO : replace with %f
//this.orientation[0] =
}
// Create a pen
let pen = new Pen(START_POSITION_X, START_POSITION_Y, BASE_ORIENTATION_X, BASE_ORIENTATION_Y);
// Ball creation
let ball = new Ball(
// ball position always drawn at least one ball width away from the edge of the canvas
// to avoid drawing errors
// random(0 + size, width - size),
// random(0 + size, height - size),
STARTING_POSITION_X,
STARTING_POSITION_Y,
ORIENTATION_X,
ORIENTATION_Y,
random(MIN_SPEED,MAX_SPEED),
random(MIN_SPEED,MAX_SPEED),
'rgb(' + random(0,255) + ',' + random(0,255) + ',' + random(0,255) + ')',
random(MIN_SIZE,MAX_SIZE)
);
// Animation
function loop() {
ctx.fillStyle = 'rgba(0,0,0,'+alpha+')';
ctx.fillRect(0,0,width, height);
ball.draw();
ball.update();
requestAnimationFrame(loop);
}
// BEGIN OF THE DRAWING
ctx.lineWidth = 6;
// Iter
function iter(minIter, maxIter) {
let nbIterations = random(minIter, maxIter);
ctx.beginPath();
ctx.moveTo(pen.position[0], pen.position[1]); // Go to init coordinates
for (let i = 0 ; i < nbIterations ; i++) {
// %a sur la stmt qui est dans Iter
}
// === BEGIN OF CHANGING PART
for (let i = 0 ; i < random(0, 10); i++) { // TODO ITER : replace 0 and 10 nb of iteration with %f
// Stmt list to inject
pen.rotate(45);
pen.translate(10);
}
// Or
function Or()
if (Math.random() < 0.5) // TODO OR : replace 0.5 proba with %f
{
let orProbability = 0.5; // TODO : mettre % (this is the left-member's random weightening)a
let randomNb = random(0, 1);
if (randomNb < orProbability)
{
// Apply stmt1
}
else
{
// Apply stmt2
}
// Inject Stmt List 1
pen.translate(100);
}
else
{
// Inject Stmt List 2
pen.translate(10);
}
// === END OF CHANGING PART
ctx.fillStyle = 'rgba(0,0,0,'+alpha+')';
ctx.fillRect(0,0,width, height);
ball.draw();
ball.update();
requestAnimationFrame(loop);
// END OF THE DRAWING
ctx.stroke();
ctx.closePath();
loop();
\ No newline at end of file
"<!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\