Update
If there is no equivalent to silhouette
could you comment on my following ideas:
I can get the projection of my surface using the planeproject
transformation. This is still a three dimension surface but maybe it is easier to extract the outline path or paths from this simpler surface? If this isn't possible neither maybe the following algorithm could work:
planeproject
the surface- extract a dense mesh of points lying on this transformed surface (these points should ly within the same plane); or maybe it is even possible to extract the border points of the flat surface somehow (maybe via their slope being different from the other points on flat part of the surface)
- use some concave hull algorithm (that would have to be implemented first, of course) to find the concave hull of the aforementioned points.
- use the path along the concave hull as outline
Here I'm particularly uncertain if there is an easy way to do step 2. And I will have to think about what to do when the concave hull consists of several paths, e.g. like for a torus where you get the outer outline and the hole in the middle. Do you think this would be possible?
Original Question
The solids
package defines revolution
objects whose outlines can be accessed via silhouette
. Example:
size(200);
import solids;
settings.render=0;
settings.prc=false;
currentprojection=perspective(4,4,3);
revolution hyperboloid=revolution(new real(real x) {return sqrt(1+x*x);},
-2,2,20,operator..,X);
draw(hyperboloid.silhouette(64),blue);
Is there an equivalent way to get the outline path of a surface
? For example the outline of such a surface
(I know that the object in this example is spherically symmetric and so I could define a revolution
that describes it but I would like to know if there is a general way to get the outline of a surface
):
import graph3;
import palette;
size(200);
currentprojection=orthographic(6,8,2);
viewportmargin=(1cm,0);
real c0=0.1;
real f(real r) {return r*(1-r/6)*exp(-r/3);}
triple f(pair t) {
real r=t.x;
real phi=t.y;
real f=f(r);
real s=max(min(c0/f,1),-1);
real R=r*sqrt(1-s^2);
return (R*cos(phi),R*sin(phi),r*s);
}
bool cond(pair t) {return f(t.x) != 0;}
real R=abs((20,20,20));
surface s=surface(f,(0,0),(R,2pi),100,8,Spline,cond);
s.colors(palette(s.map(abs),Gradient(palegreen,heavyblue)));
render render=render(compression=Low,merge=true);
draw(s,render);
draw(zscale3(-1)*s);
solids
package would not need to define a specialsilhouette
function for objects of typerevolution
. In fact, even the function insolids
is not bug-free; you might check and see if it can handle your surface. The dimple may prove especially challenging.path3[]
tracing out all the points at which the projection vector is tangent to the surface, together with all the "edge paths" of the surface (excluding those at which two edges are meeting to form a smooth surface). Then, add in the surface drawn with e.g.surfacepen=emissive(white)
,...white
with whatever your background color is.) The purpose of this is to hide from view the 3d paths that are behind the surface. The most difficult part of this will probably be to form paths tracing out all the points at which the surface is tangent to the projection vector (or equivalently, the normal to the surface is normal to the projection vector). Good luck!struct patch
andstruct surface
to see what information is actually available to you. (Just google "three_surface.asy" to find the file. Use a search tool to find all three occurrences ofstruct
in the file.)