diff --git a/.gradebook.db b/.gradebook.db index d6d2109f19e0816f026e2148fb689d56f33ff532..411a3a6152bf69f0c4cbc8e6d4ab9f26c7931425 100644 Binary files a/.gradebook.db and b/.gradebook.db differ diff --git a/premier-dessin.md b/premier-dessin.md index 22ce57311b6ddb9b19eddb40ee514bd66d5d35ce..1f8fbfebaa407f9a93457ebe6f1dc8407df6e130 100644 --- a/premier-dessin.md +++ b/premier-dessin.md @@ -14,6 +14,15 @@ kernelspec: # Premiers graphiques avec Jupyter ++++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "f43a760bd6125e25df23a9ab2628c3e9", "grade": false, "grade_id": "cell-db040b06c5a92100", "locked": true, "schema_version": 3, "solution": false, "task": false}} + +Dans cette feuille, nous allons reprendre l'exercice 2 du TD et +effectuer un premier dessin. + ++++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "f4cbf5563a6542f5c409f308fdca30a3", "grade": false, "grade_id": "cell-db040b06c5a92101", "locked": true, "schema_version": 3, "solution": false, "task": false}} + +Commençons par créer un canvas vert de taille 640 x 480 : + ```{code-cell} --- deletable: false @@ -37,35 +46,44 @@ deletable: false editable: false nbgrader: cell_type: code - checksum: bca96fdfc7023d461b707c8ae74b0caa + checksum: 9d359d2bf83f09dfcd9eb723473a197f grade: false grade_id: cell-c2afd88f340f46f4 locked: true schema_version: 3 solution: false task: false +tags: [] --- -RenderWindow window(VideoMode(900, 480), "Ma super fenêtre"); +RenderWindow window(VideoMode(640, 480), "Ma super fenêtre"); +window.canvas ``` -<canvas id='primitives_canvas'></canvas> - ```{code-cell} window.clear(Color::Green); ``` ++++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "7df12946868397e5fbe4bc994fb8d19c", "grade": false, "grade_id": "cell-db040b06c5a92102", "locked": true, "schema_version": 3, "solution": false, "task": false}} + +puis dessinons un point noir de coordonnées (418, 143). Ce point est +tout petit, vous aurez peut-être un peu de mal à le distinguer : + ```{code-cell} -// Dessine un point noir de coordonnées (418, 143) draw_point(window, {418, 143}, Color::Black ); window.display(); ``` ++++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "d8948ac8886182d90df0fb2bce302b52", "grade": false, "grade_id": "cell-db040b06c5a92103", "locked": true, "schema_version": 3, "solution": false, "task": false}} + +1. Dessinez un segment blanc entre les points de coordonnées + respsectives (100,200) et (200,200) : + ```{code-cell} --- deletable: false nbgrader: cell_type: code - checksum: b956b1c98520d602fab742ceb67096ed + checksum: ce1d6a0deeef3221d1ea8d9afbd40bce grade: true grade_id: cell-e77db2d9ed7265ac locked: false @@ -74,17 +92,31 @@ nbgrader: solution: true task: false --- -// Dessine un segment blanc entre les points (100,200) et (200,200) // REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE window.display(); ``` ++++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "2be96f003c2555d67d32213924f40a59", "grade": false, "grade_id": "cell-db040b06c5a92104", "locked": true, "schema_version": 3, "solution": false, "task": false}} + +:::{tip} Astuce + +Pour éviter de monter et descendre constamment dans cette feuille, +faites un clic droit sur le canvas et cliquez sur «Create new view for +output». Puis disposez la copie obtenue du canvas sur votre espace de +travail de sorte à voir simultanément votre code et le canvas. + +::: + ++++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "fea5730c56d940cd6a18b432d9069629", "grade": false, "grade_id": "cell-db040b06c5a92105", "locked": true, "schema_version": 3, "solution": false, "task": false}} + +2. Dessinez un segment rouge entre les points (200,300) et (200,400) : + ```{code-cell} --- deletable: false nbgrader: cell_type: code - checksum: 85bdbd533e19a61d9a8a460522c51477 + checksum: 90954d14f326667b7a51643cd5d83bc0 grade: true grade_id: cell-03b3d3f225c29d1d locked: false @@ -93,17 +125,21 @@ nbgrader: solution: true task: false --- -// Dessine un segment rouge entre les points (200,300) et (200,400) // REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE window.display(); ``` ++++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "0791571f18f4df2c2bfecb5a3ba9c0ff", "grade": false, "grade_id": "cell-db040b06c5a92106", "locked": true, "schema_version": 3, "solution": false, "task": false}} + +3. Dessinez un rectangle horizontal vide de sommets diagonaux + (200,200) et (400,300) et de contour rouge : + ```{code-cell} --- deletable: false nbgrader: cell_type: code - checksum: dea1bd15783375ceace4d093b9200ec4 + checksum: 4c65f8e4cec21af229e5a44dd7063a03 grade: true grade_id: cell-3606e0158c83309d locked: false @@ -112,17 +148,21 @@ nbgrader: solution: true task: false --- -// Dessine un rectangle horizontal vide de sommets diagonaux (200,200) et (400,300) et de contour rouge // REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE window.display() ``` ++++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "4eda0a34767a781e0fd3c186999331e2", "grade": false, "grade_id": "cell-db040b06c5a92107", "locked": true, "schema_version": 3, "solution": false, "task": false}} + +4. Dessinez un rectangle horizontal plein noir de sommets diagonaux + (400,150) et (500,200) : + ```{code-cell} --- deletable: false nbgrader: cell_type: code - checksum: 8d1e034e1cda25ee20a1c154f6f26185 + checksum: f66e8172c61aca3cb946861a95326520 grade: true grade_id: cell-25abe8a7c6c8c617 locked: false @@ -131,17 +171,21 @@ nbgrader: solution: true task: false --- -// Dessine un rectangle horizontal plein noir de sommets diagonaux (400,150) et (500,200) // REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE window.display() ``` ++++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "2f11cf73501e6fcc67b66d7ced218656", "grade": false, "grade_id": "cell-db040b06c5a92108", "locked": true, "schema_version": 3, "solution": false, "task": false}} + +5. Dessinez un segment rouge entre les points (400,300) et + (500,400) : + ```{code-cell} --- deletable: false nbgrader: cell_type: code - checksum: 196d46fbc53bc7393b523ace887864ab + checksum: 49650230393c3fc8d743c211525de50c grade: true grade_id: cell-c6d75131df2bea6d locked: false @@ -150,17 +194,42 @@ nbgrader: solution: true task: false --- -// Dessine un segment rouge entre les points (400,300) et (500,400) // REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE window.display() ``` ++++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "34955bd551a86d7f66e34edca2617cab", "grade": false, "grade_id": "cell-db040b06c5a92109", "locked": true, "schema_version": 3, "solution": false, "task": false}} + +6. ♣ Dessinez un triangle bleu entre les (0,0), (640,0) et (0,160) : + +```{code-cell} +--- +deletable: false +nbgrader: + cell_type: code + checksum: de3439e6f2af1c2ebadec5e92840b900 + grade: true + grade_id: cell-c6d75131df2bea6e + locked: false + points: 1 + schema_version: 3 + solution: true + task: false +--- +// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE +window.display() +``` + ++++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "16aaa6f47064b571ba75a417797361e4", "grade": false, "grade_id": "cell-db040b06c5a92110", "locked": true, "schema_version": 3, "solution": false, "task": false}} + +7. Dessinez un cercle noir de centre (415,145) et de rayon 10 : + ```{code-cell} --- deletable: false nbgrader: cell_type: code - checksum: 783c0f2dd02e54533dd5243b34fe2ccd + checksum: e56a4a8d478945ff8d1ef1c4497dcf05 grade: true grade_id: cell-63406c09d76b868b locked: false @@ -169,17 +238,20 @@ nbgrader: solution: true task: false --- -// Dessine un cercle noir de centre (415,145) et de rayon 10 // REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE window.display() ``` ++++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "92e964b26520043007e0fe1972b38638", "grade": false, "grade_id": "cell-db040b06c5a92111", "locked": true, "schema_version": 3, "solution": false, "task": false}} + +8. Dessinez un disque jaune de centre (550, 75) et de rayon 50 : + ```{code-cell} --- deletable: false nbgrader: cell_type: code - checksum: cfc9ac790998bab53ad2de41b30f2f6d + checksum: 6419729d5f34a928308cdd11942a3f1a grade: true grade_id: cell-4f7332edb4646cbf locked: false @@ -188,8 +260,25 @@ nbgrader: solution: true task: false --- -// Dessine un disque jaune de centre (700, 100) et de rayon 50 // REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE window.display() ``` ++++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "ef878f93df33be50d5262273cefbc00a", "grade": false, "grade_id": "cell-db040b06c5a92112", "locked": true, "schema_version": 3, "solution": false, "task": false}} + +:::{attention} + +Comme vous l'avez constaté, les performances sont lamentables. C'est +parce que nous avons abusé des canvas de HTML : alors que ceux-ci sont +conçus pour du dessin vectoriel, nous approximons les figures +vectorielles (lignes, triangles, ...) par des accumulations d'un très +grand nombre de pixels (combien pour le triangle bleu?), sachant que +chacun de ces pixels est en fait représenté en interne par un petit +rectangle. + +En dehors de ce premier dessin -- dont l'objectif pédagogique était de +faire un peu d'algorithmique -- il faut au contraire utiliser les +primitives vectorielles fournies. + +::: + diff --git a/primitives_jupyter.hpp b/primitives_jupyter.hpp index 99679abfc266fde9bd3123eae6e1e7f4d19c6cb2..a097185092e1dc8b197d7c5d65ea5346f03d1493 100644 --- a/primitives_jupyter.hpp +++ b/primitives_jupyter.hpp @@ -1,3 +1,6 @@ +#ifndef PRIMITIVES_JUPYTER_H +#define PRIMITIVES_JUPYTER_H + /** Variante de primitives.h pour dessiner dans Jupyter, sans la SFML @@ -11,48 +14,16 @@ NE PRENNEZ PAS EXEMPLE DESSUS! **/ -#include <iostream> -#include <sstream> -#include <xwidgets/xhtml.hpp> - -/** Execute javascript code in the Jupyter window - **/ -void execute_javascript(std::string js) { - nl::json mime_bundle; - mime_bundle["application/javascript"] = js; - ::xeus::get_interpreter().display_data(mime_bundle, - nl::json::object(), - nl::json::object()); -} - -void load_javascript_library() { - execute_javascript(R"js( -document.primitives_get_context = function() { - return document.primitives_canvas.getContext('2d'); -} -document.primitives_draw_rectangle = function(x, y, width, height, color) { - var ctx = document.primitives_get_context(); - ctx.strokeStyle = color; - ctx.strokeRect(x, y, width, height); -} -document.primitives_draw_filled_rectangle = function(x, y, width, height, color) { - var ctx = document.primitives_get_context(); - ctx.fillStyle = color; - ctx.fillRect(x, y, width, height); -} -document.primitives_draw_point = function(x, y, color) { - document.primitives_draw_rectangle(x, y, 1, 1, color); -} -)js"); -} +#include <xcanvas/xcanvas.hpp> namespace Color { using Color = std::string; - Color White = "white"; - Color Red = "red"; - Color Yellow = "yellow"; - Color Green = "#00FF00"; - Color Black = "black"; + Color White = "White"; + Color Blue = "Blue"; + Color Red = "Red"; + Color Yellow = "Yellow"; + Color Green = "#00CC00"; + Color Black = "Black"; } class Point { @@ -70,49 +41,43 @@ class VideoMode { VideoMode(int w, int h): width(w), height(h) {} }; +using Canvas = xw::xmaterialize<xc::xcanvas>; + class RenderWindow { - xw::html html; VideoMode vm; public: - // A buffer of javascript commands to execute - std::ostringstream buffer; + Canvas canvas; + RenderWindow(VideoMode _vm, std::string s) : vm(_vm) { - std::ostringstream canvas; - // canvas << "<canvas id='primitives_canvas'" - // << " width=" << vm.width << " height=" << vm.height - // << " style='border:1px solid #000000;'></canvas>"; - load_javascript_library(); - buffer << "document.primitives_canvas = document.getElementById('primitives_canvas');"; - buffer << "document.primitives_canvas.height = " << vm.height << ";"; - buffer << "document.primitives_canvas.width = " << vm.width << ";"; - buffer << "document.primitives_canvas.style = 'border:1px solid #000000';"; - display(); - // Disabled until xwidgets is functional again - // For now, the canvas needs to be created in a markdown cell of the notebook - // html.value = canvas.str(); - // html.display(); + vm = _vm; + canvas = xc::canvas().initialize() + .width(vm.width) + .height(vm.height) + .finalize(); + canvas.cache(); } - // Update the canvas by executing all javascript commands in the buffer - void display() { - execute_javascript(buffer.str()); - buffer = std::ostringstream(); + Canvas& get_canvas() { + return canvas; } // Clear the canvas with the given color void clear(Color::Color color) { - buffer << "document.primitives_draw_filled_rectangle(0, 0, " - << vm.width << ", " - << vm.height << ", '" - << color << "');"; - display(); + canvas.fill_style = color; + canvas.fill_rect(0, 0, vm.width, vm.height); + display(); + } + + void display() { + canvas.flush(); + canvas.cache(); } }; void draw_point(RenderWindow &window, Point p, Color::Color color) { - window.buffer << "document.primitives_draw_point(" - << p.x << ", " - << p.y << ", '" - << color << "');"; + window.canvas.fill_style = color; + window.canvas.fill_rect(p.x, p.y, 1, 1); } + +#endif