Flocon de Van Koch

Tout ce qui concerne le langage Asymptote. Ce langage est supporté sur le forum via les balises asy.

Modérateur : gdm_asy

Règles du forum
Merci de soigner la rédaction de vos messages et de consulter ce sujet avant de poster. Pensez également à utiliser la fonction recherche du forum.
Achille

[Résolu] Flocon de Van Koch

Message par Achille »

Je découvre Asymptote depuis une journée et essaie d'emblée des choses difficiles! Comme je connais déjà bien pstricks, je tente de réaliser ce qui me semble impossible avec pstricks.

C'est ainsi que j'ai entrepris de réaliser le flocon de Van Koch. Mon code fonctionne presque, mais il y a néanmoins un problème que je ne parviens pas à résoudre tout seul. Lorsque n=0 ou n=1, tout va bien, mais dès que n>=2, il y a un problème que je ne comprends pas. Voici mon code:

Code : Tout sélectionner

unitsize(10cm);
pair A,B,C,P,Q;
A=(0,0);
B=(1,0);
C=rotate(60)*B;
int n=2;

picture Koch(int n, pair P, pair Q) {
	picture pic;
	draw(pic,P--Q);
	if(n == 0) return pic;
	draw(pic,P--Q,white);
	picture subpic=Koch(n-1,P,Q);
	add(pic,shift(P)*scale(1/3)*shift(-P)*subpic);
	add(pic,shift((1/3)*(Q-P))*shift(P)*rotate(60)*scale(1/3)*shift(-P)*subpic);
	add(pic,shift((2/3)*(Q-P))*shift(P)*rotate(120)*scale(1/3)*shift(-P)*subpic);
	add(pic,shift((2/3)*(Q-P))*shift(P)*scale(1/3)*shift(-P)*subpic);
	return pic;
}

add(Koch(n,B,A));
add(Koch(n,A,C));
add(Koch(n,C,B));
Merci pour votre aide!
Dernière modification par Achille le jeudi 05 juillet 2007, 14:30, modifié 2 fois.
guiguiche
Modérateur général
Modérateur général
Messages : 8100
Inscription : vendredi 06 janvier 2006, 15:32
Statut actuel : Enseignant
Localisation : Le Mans

Message par guiguiche »

Edite ton message et mes des balises 'code' autour du code, cela améliore la lisibilité de ton message.
Pas d'aide par MP : les questions sont publiques, les réponses aussi.
Tu as apprécié l'aide qui t'a été fournie ? Alors n'hésite pas à rendre la pareille à quelqu'un d'autre.
Un peu d'autopromotion.
OG
Modérateur
Modérateur
Messages : 2293
Inscription : lundi 12 mars 2007, 11:20
Localisation : Rouen

Message par OG »

Bonjour

J'ai fait par hasard des modifications

Code : Tout sélectionner

unitsize(10cm);
pair A,B,C,P,Q;
A=(0,0);
B=(1,0);
C=rotate(60)*B;
int n=5;

picture Koch(int n, pair P, pair Q) {
picture pic;
draw(pic,P--Q);
if(n == 0) return pic;
draw(pic,P--Q,white);
picture subpic=Koch(n-1,P,Q);
picture subpic1=Koch(n-1,Q,P);
add(pic,shift(P)*scale(1/3)*shift(-P)*subpic);
add(pic,shift((1/3)*(Q-P))*shift(P)*rotate(60)*scale(1/3)*shift(-P)*subpic);
add(pic,shift((2/3)*(Q-P))*shift(P)*rotate(120)*scale(1/3)*shift(-P)*subpic1);
add(pic,shift((2/3)*(Q-P))*shift(P)*scale(1/3)*shift(-P)*subpic);
return pic;
}

add(Koch(n,B,A));
add(Koch(n,A,C));
add(Koch(n,C,B)); 
Il y a certainement mieux à faire !

Cordialement
O.G.
Dernière modification par OG le jeudi 05 juillet 2007, 14:36, modifié 1 fois.
Achille

Message par Achille »

Au vu du résultat, le problème semble déjà résolu. Merci beaucoup OG!
OG
Modérateur
Modérateur
Messages : 2293
Inscription : lundi 12 mars 2007, 11:20
Localisation : Rouen

Message par OG »

Je ne sais pas si ce que j'ai donné donne la mention [Résolu]. Je ne veux pas m'attirer les foudres de la part des informaticiens. En effet, du point de vue de la complexité c'est bof-bof

Deux appels récursifs ... donnent tout de même une mauvaise image.
Voici une autre version :

Code : Tout sélectionner

unitsize(10cm);
pair A,B,C,P,Q;
A=(0,0);
B=(1,0);
C=rotate(60)*B;
int n=6;

picture Koch(int n, pair P, pair Q) {
picture pic;
draw(pic,P--Q);
if(n == 0) return pic;
draw(pic,P--Q,white);
picture subpic=Koch(n-1,P,Q);
picture subpic1=reflect(P,Q)*subpic;
add(pic,shift(P)*scale(1/3)*shift(-P)*subpic);
add(pic,shift((1/3)*(Q-P))*shift(P)*rotate(60)*scale(1/3)*shift(-P)*subpic);
add(pic,shift((2/3)*(Q-P))*shift(P)*rotate(120)*scale(1/3)*shift(-P)*subpic1);
add(pic,shift((2/3)*(Q-P))*shift(P)*scale(1/3)*shift(-P)*subpic);
return pic;
}


picture kn=Koch(n,B,A);
picture kn1=reflect(A,C)*rotate(60)*kn;
picture kn2=rotate(-60,B)*reflect(A,B)*kn;
add(kn);
add(kn1);
add(kn2);

//add(Koch(n,B,A));
//add(Koch(n,A,C));
//add(Koch(n,C,B));
Cordialement
O.G.
Achille

Message par Achille »

Je ne vois guère d'amélioration dans la seconde version.

Par contre, j'ai apporté à présent une autre correction qui évite d'avoir à effacer le segment en le traçant en blanc. Le code semble bien meilleur, au vu de la diminution de la taille des fichiers .pdf produits.

Code : Tout sélectionner

unitsize(10cm);
pair A,B,C,P,Q;
A=(0,0);
B=(1,0);
C=rotate(60)*B;
int n=6;

picture Koch(int n, pair P, pair Q) {
	picture pic;

	if(n == 0) {
		draw(pic,P--Q);
		return pic;
	}

	picture subpic=Koch(n-1,P,Q);
	picture subpic1=Koch(n-1,Q,P);

	add(pic,shift(P)*scale(1/3)*shift(-P)*subpic);
	add(pic,shift((1/3)*(Q-P))*shift(P)*rotate(60)*scale(1/3)*shift(-P)*subpic);
	add(pic,shift((2/3)*(Q-P))*shift(P)*rotate(120)*scale(1/3)*shift(-P)*subpic1);
	add(pic,shift((2/3)*(Q-P))*shift(P)*scale(1/3)*shift(-P)*subpic);

	return pic;
}

add(Koch(n,B,A));
add(Koch(n,A,C));
add(Koch(n,C,B));
OG
Modérateur
Modérateur
Messages : 2293
Inscription : lundi 12 mars 2007, 11:20
Localisation : Rouen

Message par OG »

Bonjour

Le rendu est bien sûr le même, c'était juste la question d'image, de style de programmation. En théorie la deuxième version est plus rapide, mais dans les faits, pour l'exécution ça ne change rien, c'est tout aussi rapide et pur $n=8$ c'est inutilisable.

Cordialement
O.G.
Achille

Message par Achille »

Dans la foulée, je me suis attaqué au triangle de Sierpinski:

Code : Tout sélectionner

unitsize(10cm);
pair A,B,C;
A=(0,0);
B=(1,0);
C=rotate(60)*B;
int n=10;

void Sierpinski(int n, pair A, pair B, pair C) {

	pair P,Q,R;

	if(n == 0) {
		fill(A--B--C--cycle);
		return;
	}

	transform ta=shift(A)*scale(1/2)*shift(-A);	
	transform tb=shift((1/2)*(B-A))*shift(A)*scale(1/2)*shift(-A);
	transform tc=shift((1/2)*(C-A))*shift(A)*scale(1/2)*shift(-A);

	P=ta*A;
	Q=ta*B;
	R=ta*C;
	Sierpinski(n-1,P,Q,R);

	P=tb*A;
	Q=tb*B;
	R=tb*C;
	Sierpinski(n-1,P,Q,R);

	P=tc*A;
	Q=tc*B;
	R=tc*C;
	Sierpinski(n-1,P,Q,R);

	return;

}

Sierpinski(n,A,B,C);
Ce qui m'a permis de recoder beaucoup plus simplement le flocon de Van Koch:

Code : Tout sélectionner

unitsize(10cm);
pair A,B,C;
A=(0,0);
B=(1,0);
C=rotate(60)*B;
int n=6;

void Koch(int n, pair A, pair B) {

	pair P,Q;

	if(n == 0) {
		draw(A--B);
		return;
	}

	transform ta=shift(A)*scale(1/3)*shift(-A);	
	transform tb=shift((1/3)*(B-A))*shift(A)*rotate(60)*scale(1/3)*shift(-A);
	transform tc=shift((2/3)*(B-A))*shift(A)*rotate(120)*scale(1/3)*shift(-A);
	transform td=shift((2/3)*(B-A))*shift(A)*scale(1/3)*shift(-A);

	P=ta*A;
	Q=ta*B;
	Koch(n-1,P,Q);

	P=tb*A;
	Q=tb*B;
	Koch(n-1,P,Q);

	P=tc*A;
	Q=tc*B;
	Koch(n-1,Q,P);

	P=td*A;
	Q=td*B;
	Koch(n-1,P,Q);	

	return;

}

Koch(n,B,A);
Koch(n,A,C);
Koch(n,C,B);
OG
Modérateur
Modérateur
Messages : 2293
Inscription : lundi 12 mars 2007, 11:20
Localisation : Rouen

Message par OG »

Bonjour

J'avais oublié que sur la page de Philippe cela existait forcément !
Voir ici : figures 157 et 158 !

Cordialement
O.G.