Page 1 sur 2

Intersection Sphère Cône oblique

Posté : lun. 29 mars 2010, 11:27
par GM
Un petit délire personnel

intersection_sphere_coneoblique.png
intersection_sphere_coneoblique.png (64.48 Kio) Vu 14394 fois


Code : Tout sélectionner

size(250);
import graph3;
currentprojection=orthographic((20,17,6),up=Z);
currentlight=Viewport;

real lx=4, ly=2, thmin=.25, thmax=1, hmin=2, hmax=11;
triple S=(0,5,8);
path3 p=(lx,0,0)..(0,ly,0)..(-lx,0,0)..(0,-ly,0)..cycle;

triple f(pair t) {
  real theta=t.x;
  real k=t.y/S.z;
  real x=relpoint(p,theta).x*(1-k)+S.x*k;
  real y=relpoint(p,theta).y*(1-k)+S.y*k;
  real z=t.y;
  return (x,y,z);
}
surface s=surface(f,(thmin,hmin),(thmax,hmax),36,36,Spline),
        sph=shift(0,0,S.z*.75)*scale3(3)*unitsphere;

draw(s,red);
draw(sph,orange);

limits((0,0,0),(lx+1,ly+1,S.z+2));
xaxis3("$x$",Arrow3);
yaxis3("$y$",Arrow3);
zaxis3("$z$",Arrow3);
draw(p,green);
dot(p^^S,2bp+blue);
for(int i=0; i<size(p);++i) draw(point(p,i)--S,dashed);

/////// INTERSECTION
triple[][] in;
guide3 ch;
int n=50;
for(int i=0; i<n; ++i){
    path3 p=S--f((thmin+i*(thmax-thmin)/n,0));
    in.push(intersectionpoints(p,sph));
}
for(int i=0; i<in.length; ++i){
  if(in[i].length!=0){
    ch=ch..in[i][0];
    if(in[i].length==2) ch=in[i][1]..ch;
      dot(in[i],2bp+green);
    }
}
draw(ch..cycle,1bp+blue);

Re: Intersection Sphère Cône oblique

Posté : mar. 30 mars 2010, 12:54
par GM
Avec une base circulaire, un sommet différent, des changements de couleur et un angle de vue différent.
intersection_cone_plan_1.png
intersection_cone_plan_1.png (46.57 Kio) Vu 14372 fois

Re: Intersection Sphère Cône oblique

Posté : mar. 30 mars 2010, 23:26
par DK
Un délire personnel ? Non pas du tout, c'est plutôt génial car c'est ce que je souhaitais voir sous asymptote. Bravo !

Re: Intersection Sphère Cône oblique

Posté : mer. 31 mars 2010, 00:26
par GM
Avec un paramétrage différent.

intersection_sphere_coneoblique_3.png
intersection_sphere_coneoblique_3.png (64.19 Kio) Vu 14358 fois


Code : Tout sélectionner

size(250);
import graph3;
currentprojection=orthographic((10,8,6),up=Z);
currentlight=Viewport;

real lx=3.2, lyz=2, thmin=0, thmax=1, hmin=0, hmax=lx;
triple S=(0,0,4);
path3 p=(lx,lyz,0)..(lx,0,lyz)..(lx,-lyz,0)..(lx,0,-lyz)..cycle;

triple f(pair t) {
  real th=t.x;
  real k=t.y/lx;
  real x=t.y;
  real y=relpoint(p,th).y*k+S.y*(1-k);
  real z=relpoint(p,th).z*k+S.z*(1-k);
  return (x,y,z);
}
surface s=surface(f,(thmin,hmin),(thmax,hmax),36,36,Spline);
surface sph=shift(0,0,0)*scale3(2)*unitsphere;

draw(s,paleblue+opacity(.5));
draw(sph,blue);

limits((0,0,0),(lx+1,lyz+2,S.z+.5));
xaxis3("$x$",Arrow3);
yaxis3("$y$",Arrow3);
zaxis3("$z$",Arrow3);
draw(p,red);
//dot(p^^S,2bp+blue);
//for(int i=0; i<size(p);++i) draw(point(p,i)--S,dashed);

///// INTERSECTION
triple[][] in;
guide3 ch;
int n=100;
thmin=0.5;
thmax=1;
for(int i=0; i<n; ++i){
    path3 p=S--f((thmin+i*(thmax-thmin)/n,lx));
    in.push(intersectionpoints(p,sph));
}
for(int i=0; i<in.length; ++i){
  if(in[i].length!=0){
    ch=ch..in[i][0];
    if(in[i].length==2) ch=in[i][1]..ch;
      dot(in[i],2bp+green);
    }
}
draw(ch..cycle,1bp+.5green);

Re: Intersection Sphère Cône oblique

Posté : mer. 31 mars 2010, 08:00
par pivaldi
À partir du moment où l'on peut obtenir une équation implicite de l'intersection, on peut utiliser la routine contour comme dans l'exemple Impact de la documentation.
L'inconvénient est qu'il faut trouver une équation de l'intersection.

Re: Intersection Sphère Cône oblique

Posté : mer. 31 mars 2010, 19:21
par DK
Bonsoir,
J'ai regardé votre code. Je n'ai pas encore tout compris, mais cela ne m'empêche pas de comprendre l'idée sur les intersections ! Ce que je n'ai pas compris c'est le rôle de "triple f(pair t) {
real th=t.x;
real k=t.y/lx;
real x=t.y;
real y=relpoint(p,th).y*k+S.y*(1-k);
real z=relpoint(p,th).z*k+S.z*(1-k);
return (x,y,z);
}"...

C'est vrai que cela restreint au cône.
J'ai tenté de modifier quelque peu le cône, mais je n'y suis pas vraiment arrivé et je n'ai en rien modifié justement le "triple f(pair t) ...". Lorsque l'intersection du cône avec la sphère engendre deux courbes, voilà de ce que cela donne. Je pense que l'on y est presque. La boucle en jaune que l'on peut voir est seulement le passage d'un point à l'autre sur le path intersection, parce qu'il n'a pas été prévu de gérer deux intersections différentes.
Voici le code que j'ai modifié (je n'ai fait que translater la sphère et centrer l'axe du cône...

Code : Tout sélectionner

size(250);
import graph3;
currentprojection=orthographic((20,20,20),up=Z);
currentlight=Viewport;

triple S=(0,0,8), C=(0,0,-1) ;
real lx=4, ly=4, thmin=0, thmax=1, hmin=-1, hmax=S.z;
//path3 p=(lx,0,0)..(0,ly,0)..(-lx,0,0)..(0,-ly,0)..cycle;
path3 p=circle( C , 3.5 , Z);

triple f(pair t) {
  real theta=t.x;
  real k=t.y/S.z;
  real x=relpoint(p,theta).x*(1-k)+S.x*k;
  real y=relpoint(p,theta).y*(1-k)+S.y*k;
  real z=t.y;
  return (x,y,z);
}
surface s=surface(f,(thmin,hmin),(thmax,hmax),36,36,Spline),
        sph=shift(0,-3/2,4)*scale3(3)*unitsphere;

draw(s,red+opacity(0.8));
draw(sph,orange+opacity(0.8));

limits((0,0,0),(lx+1,ly+1,S.z+2));
xaxis3("$x$",Arrow3);
yaxis3("$y$",Arrow3);
zaxis3("$z$",Arrow3);

draw(p,red);
dot(p^^S,2bp+blue);
for(int i=0; i<size(p);++i) draw(point(p,i)--S,dashed);

/////// INTERSECTION
triple[][] inter;
guide3 ch;
int n=50;
for(int i=0; i<n; ++i){
    path3 p=S--f( (thmin+i*(thmax-thmin)/n,hmin) );
    inter.push(intersectionpoints(p,sph));
}
for(int i=0; i<inter.length; ++i){
  if(inter[i].length!=0){
    ch=ch..inter[i][0];
    if(inter[i].length==2) ch=inter[i][1]..ch;
      dot(inter[i],2bp+green);
    }
}
draw(ch..cycle,1bp+yellow);

ce qui donne :
intersectionSphereCone.tiff
collision cône-sphère
intersectionSphereCone.tiff (98.99 Kio) Vu 14338 fois
.

Re: Intersection Sphère Cône oblique

Posté : mer. 31 mars 2010, 21:03
par GM
DK a écrit :Bonsoir,
J'ai regardé votre code. Je n'ai pas encore tout compris, mais cela ne m'empêche pas de comprendre l'idée sur les intersections ! Ce que je n'ai pas compris c'est le rôle de "triple f(pair t) {
real th=t.x;
real k=t.y/lx;
real x=t.y;
real y=relpoint(p,th).y*k+S.y*(1-k);
real z=relpoint(p,th).z*k+S.z*(1-k);
return (x,y,z);
}"...

Pour tracer un simple cône de révolution, on peut faire plus simple mais je voulais pouvoir :
  • tracer un cône quelconque (pas nécessairement droit) et à base quelconque ;
  • restreindre le cône à un tronc de cône, voire au contraire tracer un bicône : cela dépend des valeurs données à hmin, hmax ;
  • pouvoir "ouvrir" le cône, et voir une intersection à l'intérieur du cône (sans mettre de transparence qui pose des problèmes du type artefact) : cela dépend de thmin et thmax (avec les valeurs respectives 0 (theta=0) et 1 (theta=360°), on a un tour complet.

DK a écrit :C'est vrai que cela restreint au cône.
J'ai tenté de modifier quelque peu le cône, mais je n'y suis pas vraiment arrivé et je n'ai en rien modifié justement le "triple f(pair t) ...".

On peut supprimer ces facilités... si on est sûr de vouloir un cône classique de révolution d'une hauteur donnée et non ouvert.

DK a écrit :Lorsque l'intersection du cône avec la sphère engendre deux courbes, voilà de ce que cela donne. Je pense que l'on y est presque. La boucle en jaune que l'on peut voir est seulement le passage d'un point à l'autre sur le path intersection, parce qu'il n'a pas été prévu de gérer deux intersections différentes.

Effectivement, ce n'était pas prévu.
Avec ceci, on sera plus proche du résultat :

Code : Tout sélectionner

/////// INTERSECTION
triple[][] inter;
path3 ch1,ch2;
int n=100;
for(int i=0; i<n; ++i){
path3 p=S--f( (thmin+i*(thmax-thmin)/n,hmin) );
inter.push(intersectionpoints(p,sph));
}
for(int i=0; i<inter.length; ++i){
  ch1=ch1..inter[i][0]; dot(inter[i][0],2bp+green);
  if(inter[i].length==2){
  ch2=ch2..inter[i][1]; dot(inter[i][1],2bp+green);}
}
draw(ch1..cycle,1bp+yellow);
draw(ch2..cycle,1bp+blue);


Mais il va rester des problèmes liés au fait que l'on a le cône presque tangent à la sphère.
Je ne sais pas si c'était voulu...
... mais je signale que le rendu est bon si on augmente un peu le rayon de la sphère.

Si le cône doit être tangent à la sphère... je pense qu'il faudra revoir la façon de faire pour avoir quelque chose de satisfaisant à la jonction.

Je n'aurai personnellement pas le temps de chercher comment mieux faire avant vendredi soir, voire samedi matin.

Re: Intersection Sphère Cône oblique

Posté : mer. 31 mars 2010, 22:10
par GM
pivaldi a écrit :À partir du moment où l'on peut obtenir une équation implicite de l'intersection, on peut utiliser la routine contour comme dans l'exemple Impact de la documentation.
L'inconvénient est qu'il faut trouver une équation de l'intersection.

Je n'ai pas encore eu le temps de réfléchir à la faisabilité de cette méthode pour le problème de DK mais merci pour la piste. :)

Même si c'est sympa de réfléchir à comment faire telle ou telle intersection... j'espère tout de même que l'intersection surface-surface sera implémentée en 2010. :D

Re: Intersection Sphère Cône oblique

Posté : mer. 31 mars 2010, 23:22
par GM
GM a écrit :Mais il va rester des problèmes liés au fait que l'on a le cône presque tangent à la sphère.
Je ne sais pas si c'était voulu...


Si j'ai bien reporté les points et longueurs... il ne serait pas si tangent que cela : http://asy.gmaths.net/ggb/sphere_cone.html

Mais il y a un problème dans le nombre d'intersection que je ne m'explique pas encore :

intersection_sphere_cone_pb.png
intersection_sphere_cone_pb.png (56.12 Kio) Vu 14322 fois


Code : Tout sélectionner

size(250);
import graph3;
currentprojection=orthographic((20,20,20),up=Z);
currentlight=Viewport;

triple S=(0,0,8), C=(0,0,-1) ;
real lx=4, ly=4, thmin=0, thmax=1, hmin=-1, hmax=S.z;
//path3 p=(lx,0,0)..(0,ly,0)..(-lx,0,0)..(0,-ly,0)..cycle;
path3 p=circle(C,3.5,Z);

triple f(pair t) {
  real theta=t.x;
  real k=t.y/S.z;
  real x=relpoint(p,theta).x*(1-k)+S.x*k;
  real y=relpoint(p,theta).y*(1-k)+S.y*k;
  real z=t.y;
  return (x,y,z);
}
surface s=surface(f,(thmin,hmin),(thmax,hmax),36,36,Spline),
sph=shift(0,-3/2,4)*scale3(3)*unitsphere;

draw(s,red+opacity(0.8));
draw(sph,orange+opacity(0.8));

limits((0,0,0),(lx+1,ly+1,S.z+2));
xaxis3("$x$",Arrow3);
yaxis3("$y$",Arrow3);
zaxis3("$z$",Arrow3);

draw(p,red);
dot(p^^S,2bp+blue);
for(int i=0; i<size(p);++i) draw(point(p,i)--S,dashed);

/////// INTERSECTION
triple[][] inter;
path3 ch1,ch2;
int n=360;
for(int i=0; i<n; ++i){
path3 p=S--f( (thmin+i*(thmax-thmin)/n,hmin) );
inter.push(intersectionpoints(p,sph));
}
for(int i=0; i<inter.length; ++i){
  ch1=ch1..inter[i][0]; dot(inter[i][0],2bp+green);
  if(inter[i].length>=2){ // J'avais mis ==2......... mais il manquait des points... et là, ce que j'obtiens est bizarre.
  ch2=ch2..inter[i][1]; dot(inter[i][1],2bp+green);}
}
draw(ch1..cycle,1bp+yellow);
draw(ch2..cycle,1bp+blue);


L'issue sera probablement : un changement de façon de faire.

Re: Intersection Sphère Cône oblique

Posté : jeu. 1 avr. 2010, 00:13
par GM
En constatant la différence entre la version geogebra et la version asymptote... du point de vue des distances, je me suis dit qu'il devait y avoir un problème et cela m'a convaincu de recommencer.
Mais avec un simple cône de révolution, cette fois :

intersection_sphere_conedroit.png
intersection_sphere_conedroit.png (58.72 Kio) Vu 14318 fois


Code : Tout sélectionner

size(250);
import solids;
currentprojection=orthographic((20,20,20),up=Z);
currentlight=Viewport;

triple pS=(0,0,8), pC=(0,0,-1) ;
real rbase=3.5, h=pS.z-pC.z;
path3 base=circle(pC,rbase,Z);
revolution CoRev=cone(pC,rbase,h,axis=Z,n=1);

surface co=surface(CoRev),
        sph=shift(0,-3/2,4)*scale3(3)*unitsphere;

draw(co,red+opacity(0.98));
draw(sph,blue);

limits((0,0,0),(rbase+1,rbase+1,pS.z+1));
xaxis3("$x$",Arrow3);
yaxis3("$y$",Arrow3);
zaxis3("$z$",Arrow3);

for(int i=0; i<size(base);++i) draw(point(base,i)--pS,dashed);

/////// INTERSECTION
triple[][] inter;
path3 ch1,ch2;
int n=360;
for(int i=0; i<n; ++i){
path3 p=pS--relpoint(base,i/n);
inter.push(intersectionpoints(p,sph));
}
for(int i=0; i<inter.length; ++i){
  ch1=ch1..inter[i][0]; dot(inter[i][0],2bp+green);
  if(inter[i].length==2){
  ch2=ch2..inter[i][1]; dot(inter[i][1],2bp+green);}
}
draw(ch1..cycle,1bp+yellow);
draw(ch2..cycle,1bp+blue);


Cela va mieux.
Je chercherai une prochaine fois l'erreur dans l'autre version.