Page 1 sur 1

Colorier l'intersection d'un plan avec un solide

MessagePosté: Mardi 29 Mars 2011, 12:29
par Romain Janvier
Bonjour,
J'aimerai bien utiliser le module solids pour refaire les figures de mon cours de 3e. Je l'avais fait en pstricks en trichant un peu (en fait je traçais des ellipses). J'ai bien regardé les exemples et les quelques docs mais je ne trouve pas comment ne colorier que la surface correspondant à l'intersection, comme sur cette image :
intersection-sphere.jpg
intersection-sphere.jpg (13.15 Kio) Vu 1071 fois


Au pire, on doit pouvoir le faire en calculant le rayon du disque que l'on veut colorier, mais il doit bien y avoir plus simple. Dans les exemples, on passe par un skeleton, mais je n'arrive pas à le transformer en surface.

Merci.

Re: Colorier l'intersection d'un plan avec un solide

MessagePosté: Mardi 29 Mars 2011, 18:17
par maurice
Bonjour,

Romain Janvier a écrit:Au pire, on doit pouvoir le faire en calculant le rayon du disque que l'on veut colorier, mais il doit bien y avoir plus simple.
Merci.


Je n'ai pas grand chose à proposer de mieux !
C'est un premier jet qui doit être peaufiné !

[asy unknown error.]

Code: Tout sélectionner
import solids;
currentprojection = perspective(10,100,25);
size(6cm);


void colorer_section_sphere(triple pO=O, real a, real[] plan={0,0,1,-1}, pen p=green+opacity(0.75)) {
real dist=abs(plan[0]*pO.x+plan[1]*pO.y+plan[2]*pO.z+plan[3])/sqrt(plan[0]^2+plan[1]^2+plan[2]^2);
real rayon=sqrt(a^2-dist^2);
triple normal=(plan[0], plan[1], plan[2])/sqrt(plan[0]^2+plan[1]^2+plan[2]^2);
triple pOprime=pO+dist*normal;
revolution r=sphere(pO, a);
draw(r.silhouette());
skeleton s;
r.transverse(s,reltime(r.g, 0.5));
draw(s.transverse.front, solid+black);
draw(s.transverse.back, dashed+black);
draw(surface(circle(pOprime, rayon, normal)), p);
draw(circle(pOprime, rayon, normal));
}

/* \'Equation du plan ax+by+cz+d=0
real[] plan={a,b,c,d}; */

real[] plan={0,0,1,-3};
colorer_section_sphere(O, 5, plan);


Maurice

Edit : orthographe

Re: Colorier l'intersection d'un plan avec un solide

MessagePosté: Mardi 29 Mars 2011, 18:34
par Romain Janvier
J'ai reussi à faire plus simple il me semble. Mais par contre je n'arrive pas à mettre la partie de la sphere sous le plan en pointillés. J'ai bien peur de devoir afficher d'abord la partie de la sphere sous le plan, afficher la surface du plan, reafficher la silhouette du bas avec des pointillets et rajouter la parie haute de la sphère...

6b68e37767a98f5516db1cdbb226d132.png

Code: Tout sélectionner
import solids;
unitsize(1cm);

settings.render=0;
settings.prc=false;
currentlight = nolight;
currentprojection=orthographic(2,5,2);
dotfactor=3.5;

real a=3;
triple p0=(0,0,0);
real h=2;
real rb=sqrt(a*a-h*h);
real k=(90+aSin(h/a))/180;
pen backpen=defaultbackpen;

real largplan=7;
path3 p=rotate(45,Z)*shift((-largplan/2,-largplan/2,h))*(scale3(largplan)*unitsquare3);

draw(p);
revolution b=sphere(p0,a);

triple H=(0,0,h);
triple A=rotate(110,Z)*(rb,0,h);
draw(surface(circle((0,0,h),rb,Z)),lightblue);

draw(A--H--p0--cycle,backpen);

skeleton s;
b.transverse(s,reltime(b.g,k));
draw(s.transverse.back,backpen);
draw(s.transverse.front);
draw(b,1,longitudinalpen=nullpen);
draw(b.silhouette(),black);
dot(p0);
dot(H);
dot(A);
label("$O$",p0,W);
label("$H$",H,NW);
label("$A$",A,SE);


Du coup je me demande si je ne vais pas repasser en 2D avec des ellipses. Cela sera peut-etre plus simple de calculer les intersections.

Edit:

Après un peu de bidouilles, voici le résultat :

[asy unknown error.]

Code: Tout sélectionner
import solids;

unitsize(1cm);
settings.render=0;
settings.prc=false;
currentlight = nolight;
currentprojection=orthographic(2,5,2);
dotfactor=3.5;

void drawrightangle(picture pic=currentpicture,
triple M, triple A, triple B,
real radius=0,
pen p=currentpen,
pen fillpen=nullpen,
projection P=currentprojection)
{
p=linejoin(0)+linecap(0)+p;
if (radius==0) radius=arrowfactor*sqrt(2);
transform3 T=shift(-M);
triple OA=radius/sqrt(2)*unit(T*A),
OB=radius/sqrt(2)*unit(T*B),
OC=OA+OB;
path3 tp=OA--OC--OB;
picture tpic;
draw(tpic, tp, p=p);
if (fillpen!=nullpen) draw(tpic, surface(O--tp--cycle), fillpen);
add(pic,tpic,M);
}


real a=3;
triple p0=(0,0,0);
real h=2;
real rb=sqrt(a*a-h*h);
real k=(90+aSin(h/a))/180;
pen backpen=defaultbackpen;

real largplan=7;
path3 p=rotate(45,Z)*shift((-largplan/2,-largplan/2,h))*(scale3(largplan)*unitsquare3);

revolution b=sphere(p0,a);

triple H=(0,0,h);
triple A=rotate(110,Z)*(rb,0,h);


path3 genhaut=arc(p0,a,0,10,aCos(h/a),10);
path3 genbas=arc(p0,a,aCos(h/a),10,180,10);

revolution bas=revolution(p0,genbas,Z,0,360);
revolution haut=revolution(p0,genhaut,Z,0,360);


skeleton s;
b.transverse(s,reltime(b.g,k));


//draw(b,1,longitudinalpen=nullpen);
draw(b.silhouette(),black);
draw(surface(p),white);
draw(b.silhouette(),backpen);
draw(haut.silhouette());
draw(p);


draw(surface(circle((0,0,h),rb,Z)),lightblue);
draw(A--H--p0--cycle,backpen);
draw(s.transverse.back,backpen);
draw(s.transverse.front);

dot(p0);
dot(H);
dot(A);
label("$O$",p0,W);
label("$H$",H,NW);
label("$A$",A,SE);
drawrightangle(H,p0,A);


Tiens, c'est marrant, l'espece de petit cercle en haut n'apparait pas lorsque je compile chez moi... Et puis il y a pas mal de code mort dans tout ca, comme la partie bas que je n'utilise finalement pas.

Re: Colorier l'intersection d'un plan avec un solide

MessagePosté: Mardi 29 Mars 2011, 21:54
par GMaths
Romain Janvier a écrit:Tiens, c'est marrant, l'espece de petit cercle en haut n'apparait pas lorsque je compile chez moi... Et puis il y a pas mal de code mort dans tout ca, comme la partie bas que je n'utilise finalement pas.


Il est connu que bon nombre de figures 3D ne peuvent pas passer correctement sur le forum.

Il est conseillé de tester la figure avant de poster... en demandant un aperçu, et donc de ne pas la mettre si cela ne rend pas bien.

On fait la promotion d'Asymptote... donc il me semble qu'il faut utiliser la possibilité de mettre directement des figures asymptote sur le forum que lorsque le rendu est fidèle...
... et si ce n'est pas le cas, il faut joindre une copie d'écran.

--------

Ce message ne s'adresse pas qu'à toi Romain : je donne simplement mon modeste avis, à tous ceux qui sont tentés de mettre des figures 3D directement sur le forum... et qui ont le souci de promouvoir le mieux possible Asymptote.

Re: Colorier l'intersection d'un plan avec un solide

MessagePosté: Mardi 29 Mars 2011, 22:02
par Romain Janvier
Pas de problème. Je suis en train de faire une animation avec tout cela et je mettrai je gif.

Edit :
Le voici :
animation-coupe-sphere.gif
animation-coupe-sphere.gif (399.64 Kio) Vu 1020 fois


Et le code :
Code: Tout sélectionner
import solids;
import graph3;
import animate;
unitsize(1cm);

settings.tex="pdflatex";
settings.outformat="pdf";

settings.render=0;
settings.prc=false;
currentlight = nolight;
currentprojection=orthographic(10,0,2);
dotfactor=3.5;

void drawrightangle(picture pic=currentpicture,
                    triple M, triple A, triple B,
                    real radius=0,
                    pen p=currentpen,
                    pen fillpen=nullpen,
                    projection P=currentprojection)
{
  p=linejoin(0)+linecap(0)+p;
  if (radius==0) radius=arrowfactor*sqrt(2);
  transform3 T=shift(-M);
  triple OA=radius/sqrt(2)*unit(T*A),
    OB=radius/sqrt(2)*unit(T*B),
    OC=OA+OB;
  path3 tp=OA--OC--OB;
  picture tpic;
  draw(tpic, tp, p=p);
  if (fillpen!=nullpen) draw(tpic, surface(O--tp--cycle), fillpen);
  add(pic,tpic,M);
}

animation Anim;
for(real h=5;h>-5;h-=0.1)
{
save();
write("on passe a h="+(string)h);
real a=3;
triple p0=(0,0,0);
//real h=3.4;
pen backpen=defaultbackpen;

real largplan=9;
path3 p=rotate(20,Z)*shift((-largplan/2,-largplan/2,h))*(scale3(largplan)*unitsquare3);

revolution b=sphere(p0,a);

triple H=(0,0,h);

if((h>-a)&&(h<a)){
real rb=sqrt(a*a-h*h);
real k=(90+aSin(h/a))/180;
triple A=rotate(40,Z)*(rb,0,h);

path3 genhaut=arc(p0,a,0,0,aCos(h/a),0);
path3 genbas=arc(p0,a,aCos(h/a),0,180,0);

revolution bas=revolution(p0,genbas,Z,0,360);
revolution haut=revolution(p0,genhaut,-Z,0,360);
skeleton s;
b.transverse(s,reltime(b.g,k));
draw(b.silhouette(),black);
draw(surface(p),white);
draw(b.silhouette(),backpen);
draw(p);
draw(surface(haut),white);
draw(haut.silhouette());
draw(bas.silhouette(),backpen);
draw(surface(circle((0,0,h),rb,Z)),lightblue);
draw(p,backpen);
//draw(A--H--p0--cycle,backpen);
draw(s.transverse.back,backpen);
draw(s.transverse.front);

//dot(p0);
//dot(H);
//dot(A);
//label("$O$",p0,W);
//label("$H$",H,NW);
//label("$A$",A,SE);
//drawrightangle(H,p0,A);
}

if(h>=a){
draw(b.silhouette());
draw(surface(p),white);
draw(b.silhouette(),backpen);
draw(p);
}

if(h<=-a){
draw(p);
draw(surface(b),white);
draw(p,backpen);
draw(b.silhouette());
}
Anim.add();
restore();
};
Anim.movie();