Librairie plotter.r
François22-Mar-2011/22:58:16+1:00
Bonsoir,

Ce message pour vous inviter à découvrir un petit projet sur lequel je passe bcp de temps actuellement: le développement d'une librairie permettant de transformer tout face vid supportant l'effect draw en plotter de fonction mathématique.

Une démo (non encore finalisée mais déjà bien représentative) est disponible ici: http://rebol.x10.mx/scripts/plotterdemo.r

Le plus simple, c'est d'y accéder via le desktop view!!

A bientôt.

François
jocko23-Mar-2011/7:26:02+1:00
Bonjour, François,

Bravo, joli travail !
Pendant que tu y es, prévois une sauvegarde de ton plot sous forme de fichier image.

Jocko
coccinelle23-Mar-2011/7:42:36+1:00
Joli librairie, bravo François.

Petite astuce pour accélérer l'affichage lors du resize, c'est d'utiliser scale et translate au lieu de recalculer tous les points. C'est ce que je fais dans le quetzal et cela marche bien.

Le principe est assez simple. Tu calcules une fois pour toute les points de tes fonctions dans leur propre repère et ensuite tu calcules les facteurs de mise à l'échelle (sale) et de dépacement (translate) en fonction de la taille de la zone à afficher pour obtenir un dessin à la bonne dimension et bien centré.

C'est beaucoup plus rapide car c'est AGG qui fait la transformation. Ainsi lors du resize, tu ne dois recalculer que quatre valeurs (scale x et y, et translate x et y) alors que si tu le fais toi même, tu dois recalculer tous les points de tes fonctions.

Et si tu appliques aussi cela au calcul de la grille, ce sera encore plus rapide.

Marco.
ldci23-Mar-2011/9:22:23+1:00
Salut d'un François à un autre François
Joli
Regarde aussi ce code de Phil que tu trouveras sur rebol.org


Title: "Graph a function"
File: %graph.r
Author: "Phil Bevan"
Date: 21-Oct-2001/12:00:00
Version: 1.1.0
Email: %philb--upnaway--com
Category: [math]
Purpose: {
Graph a function
rounding function by Ladislav Mecir
Usage ....
Type in your function of x into the input field
Some pretty functions to get you started .....
3 * sin (0.5 * pi * x)
3 * sin (x * x)
exp(0.1 * x) * (sin(4 * pi * x))
4 * sin (4 * pi / x)
0.2 * exp(- x) * sin (0.5 * pi * x)
10 / ((3 * x * x) + (4 * x) - 3)
}
François23-Mar-2011/9:35:48+1:00
Merci pour vos encouragements.

Marco, ton conseil est vraiment super! Par contre, j'avoue ne pas trop savoir comment l'implémenter. En effet, à chaque redimensionnement, je recalcule pour chaque pixel de x le pixel y correspondant. Si je ne le fais pas, en passant d'une zone de dessin de 100 pixels de larges à 1000 pixels de larges, j'ai un effet d'escalier, puisque seulement 1 pixel sur dix à son ordonnée calculée...

Je vais regarder ton code pour essayer de comprendre.

Merci
coccinelle23-Mar-2011/10:22:19+1:00
Plusieurs solutions sont possibles. Soit utiliser spline à la place de line, soit avoir un repère initial très grand, par exemple de 10'000 sur 10'000 comme ça, tu ne va pas perdre en qualité lorsque tu passes de 100 pixels à 1000.

J'emploie en fait les deux solutions dans le quetzal. Par exemple, les coordonnées des profils varient entre 0 et 1 alors je les multiplie par 1e5 au chargement pour avoir une bonne précision (fonction exec-xfoil dans le source quetzal-foil.r) C'est ensuite scale qui me réduit le dessin à la dimension nécessaire.

Si j'utilise spline, c'est que le nombre de point des profiles est fini et qu'il faut extrapoler les points intermédiaires. J'ai bien une fonction dans les tiroirs qui pourrait le faire mais à quoi bon se casser la tête si draw le fait déjà.
François23-Mar-2011/13:25:10+1:00
Marco

Voilà, j'ai compris l'usage de scale et reset-matrix J'ai adapté le code de plotter.r et effectivement, c'est le jour et la nuit!! un tout grand merci Marco!

Maintenant, lors d'un changement de taille de la zone de traçage, le script se contente d'un scaling! Par défaut, la taille de référence est initialisée à la taille de l'écran, dans la mesure où la zone de traçage n'est pas censée être plus grande que l'écran. Néanmoins, l'application appelante a tout loisir d'agrandir cette taille de référence.

Par contre, lors d'un changement de règle sur les axes (dans le cas par exemple d'un zoom in/out), là le script recalcule tout. Dans l'optique de pouvoir se déplacer dans le graphe, il faudrait éviter le recalcule en cas de "translation". Et là, je coince encore... Aurais-tu une suggestion? Y-a-t-il une fonction de draw qui facilite cela?

J'ai également constaté que le scaling a aussi un impact sur l'épaisser du dessin J'ai été obligé de compenser le scaling lors de l'appel à 'line-width pour maintenir l'épaisseur du trait. Mais celà a quand même tendance à déformer le trait. C'est pourquoi, pour l'affichage des axes, des libellés et de la grille, j'ai maintenu le recalcul complet qui n'est vraiment pas gourmand en ressources. Mais je ferai un test sur mon vieux pentium 133Mhz ce soir

REM: il faudra attendre ce soir avant d'avoir une nouvelle version sur http:://rebol.x10.mx
coccinelle23-Mar-2011/14:55:47+1:00
C'est juste pour l'impact sur l'épaisseur du dessin. Pour la translation, c'est "translate".

Faudrait que l'on fasse une fonction qui fasse le boulot car c'est toujours pareil, ça nous serait pratique à tous les deux et c'est une chose que je voulais faire de toute manière pour le quetzal.
Didec23-Mar-2011/16:26:02+1:00
Pour l'épaisseur des lignes R3 prévoit le paramètre 'fixed sur 'line-width pour palier à cela, mais il n'existe malheureusement pas dans R2 :

http://www.rebol.net/wiki/Line-Width
http://www.rebol.com/docs/draw-ref.html
François23-Mar-2011/16:52:35+1:00
Pour compenser, je fais simplement

	repend plot-area [
		'pen p_expression/color 
		'line-width to-integer multiply p_expression/thickness min  divide p_prop/reference-size/x p_prop/display-size/x
																	divide p_prop/reference-size/y p_prop/display-size/y
		'scale	divide p_prop/display-size/x p_prop/reference-size/x
				divide p_prop/display-size/y p_prop/reference-size/y
	]
François23-Mar-2011/16:54:57+1:00
en plus lisible

repend plot-area [
  'pen p_expression/color 
  'line-width to-integer multiply p_expression/thickness 
    min divide p_prop/reference-size/x p_prop/display-size/x
        divide p_prop/reference-size/y p_prop/display-size/y
  'scale divide p_prop/display-size/x p_prop/reference-size/x
         divide p_prop/display-size/y p_prop/reference-size/y
]
coccinelle23-Mar-2011/20:52:49+1:00
Hello François,

Tu n'es pas obligé de réduire le block à chaque exécution. Voici un petit exemple qui illustre la chose:
mon-text: "Bonjour ..."
ma-couleur: ivory
ma-police: make face/font [size: 32]


view layout [across
	btn "bleu" [ma-couleur: navy show ma-boite]
	btn "vert" [ma-couleur: green show ma-boite] return
	ma-boite: box 200x100 effect [draw [font ma-police pen ma-couleur text mon-text]]
]
coccinelle23-Mar-2011/22:12:29+1:00
Un autre exemple qui illustre comment je procède dans le quetzal.
rebol []

my-draw: my-draw-1: [
	polygon -1000x-1000 -1000x1000 0x0 1000x1000 1000x-1000
]
my-draw-2: [
	polygon -1000x-1000 1000x-1000 0x0 -1000x1000 1000x1000 
]

my-offset: -1010x-1010 ; point le plus en haut à gauche 
my-size: 2020x2020 ; taille du dessin
my-line-width: 4 ; largeur du trait

translate-offset: 0x0 
scale-x: 1
scale-y: 1
scale-line-width: 1

my-layout: layout [
	across
	btn "draw 1" [my-draw: my-draw-1 resize]
	btn "draw 2" [my-draw: my-draw-2 resize]
	return
	my-box: box 400x300 edge [size: 3] effect [draw [
		translate translate-offset
		scale scale-x scale-y
		line-width scale-line-width
		push my-draw
		
	]]
]

insert-event-func [
    unless event/face = my-layout [return event]
    switch event/type [resize [resize]]
    event
]

do resize: does [
	my-box/size: my-layout/size - 20 - my-box/offset - edge-size? my-layout
	scale-x: my-box/size/x / my-size/x
	scale-y: my-box/size/y / my-size/y
	translate-offset: negate to-pair reduce [
		round my-offset/x * scale-x
		round my-offset/y * scale-y
	]
	scale-line-width: my-line-width / square-root  (scale-x ** 2) + (scale-y ** 2)
	show my-box
]

view/options my-layout [resize]
François23-Mar-2011/23:49:54+1:00
Voili, voilou

Une version optimisée est maintenant en ligne.

Le plus simple est de la tester avec Desktop/View http://rebol.x10.mx/scripts/plotterdemo.r

Attention: veillez à supprimer au préalable le contenu du dossier public/rebol.x10.mx Sinon, suite à un bug dans la version présente dans ce dossier, aucune des librairies externes ne sera mise-à-jour. Ce bug est corrigé dans la nouvelle version.
coccinelle24-Mar-2011/8:36:52+1:00
Super, ça marche bien et le resize est clairement beaucoup plus rapide.

Bravo.

Bonne journée, Marco.
François24-Mar-2011/10:24:25+1:00
Merci pour ton aide Marco

En ce qui concerne ta dernière remarque, je ne vois pas trop comment je pourrais éviter d'évaluer le block à chaque fois :(
François24-Mar-2011/20:08:38+1:00
Je viens de tester sur mon vieux coucou (toshiba satellite 220CS - pentium 133Mhz avec 144MB de ram)... Et bien, c'est très acceptable comme performance... Je vais faire des mesures plus précise dès que j'ai le temps
François26-Mar-2011/16:24:25+1:00
Bonjour,

Ce message pour annoncer qu'une nouvelle version de la librairie plotter.r et de l'application démo plotterdemo.r sont disponibles.

ATTENTION: le chemin vers la librairie et la démo a changé: http://rebol.x10.mx/stable/plotterdemo.r

notez le dossier "stable" en lieu et place du dossier "scripts". Je vous suggère également de supprimer le dossier rebol.x10.mx/scripts/ pour éviter tout confusion.

Pour les changements... tout est écrit dans les headers des différents fichiers constituants.

Bon WE et à très bientôt

Login required to Post.


Powered by RebelBB and REBOL 2.7.8.4.2