Please find another solution. Sorry for late, I had another tasks...
Since the data are very well organized it is possible to construct a parametrized Bézier patches surface in the same spirit as the surface parametrized
asymptote routine. In fact the surface described by a real function over a box(a,b)
(only on a grid, f
defined from the box to R) is an adaptation of a Scilab function.
For a surface described by a parametric function f
over box(a,b)
the process is the following (f
takes value in 3D): if f
depends on (t,s)
variable, Dt
a uniform subdivision in t
with nu
points, Ds
a uniform subdivision in s
with nv
points. F
the value of f
on the grid, Fx
, Fy
, Fz
the x
, y
, z
values. Using the previous routine we construct 3 Bézier parametrized surfaces; (Fx,{1,...,nu},{1,...,nv})
, (Fy,{1,...,nu},{1,...,nv})
, (Fz,{1,...,nu},{1,...,nv})
. At last we obtain the Bézier parametrized surface (Fx,Fy,Fz)
. It is a very naive method and in 2D it is well known that you can have some inappropriate behavior (see De Boor).
If someone has a better parametrized choice (instead of uniform) please let me know.
It is not very difficult to adapt this to your case.
// Global Asymptote definitions can be put here.
import three;
import grid3;
usepackage("mathptmx");
// One can globally override the default toolbar settings here:
// settings.toolbar=true;
import graph3;
real xmin=-2, xmax=2;
real ymin=-2, ymax=1.5;
real zmin=-2.5, zmax=2.5;
limits((xmin,ymin,zmin),(xmax,ymax,zmax));
currentprojection=perspective(camera=(1.5,2,2.5));
unitsize(3cm,3cm,2cm);
real linewidth=1.1;
real linewidthprojections=.15;
string filebasename="./data/ForASY_mnl2ippGridBranche3T1_";
bool renderPRC = false;
if(renderPRC) {
// PRC TRUE
settings.prc=true;
settings.embed=true;
}
else {
// RASTERIZE
settings.outformat="png";
settings.prc=false;
settings.render=3;
}
/////// ORBITS IN 3D, SMOOTH ////////
for (int i=1; i<=50; i=i+2)
{
string filename1 = filebasename + string(i) + "PartI.dat";
file in1=input(filename1).line().csv();
real[][] a1=in1.dimension(0,0); // 0 pour dire jusqu'à la fin du fichier
a1=transpose(a1);
real[] x1=a1[0];
real[] y1=a1[1];
real[] z1=a1[3];
pen orbitpen=.7bp+red*(1-sqrt(1-i/50))+rgb(0,62/255,91/255)*(sqrt(1-i/50));
pen projpen=.3bp+red*(1-sqrt(1-i/50))+rgb(0,62/255,91/255)*(sqrt(1-i/50))+opacity(0.3);
path3 thepath1 = graph(x1, y1, z1, operator..);
draw(thepath1,orbitpen,currentlight);
}
//////// SURFACE PART I ////////
triple[][] v=new triple[50][21];
int increment=1;
for (int i=1; i<52-increment; i=i+increment)
{
string filename1 = filebasename + string(i) + "PartI.dat";
file in1=input(filename1).line().csv();
real[][] a1=in1.dimension(0,0); // 0 pour dire jusqu'à la fin du fichier
a1=transpose(a1);
real[] x=a1[0];
real[] y=a1[1];
real[] z=a1[3];
int step=1;
for (int j=0; j<22-step; j=j+step)
{
v[i-1][j]=(x[j],y[j],z[j]);
}
}
int nu=50-1;
int nv=21-1;
real[] ipt=sequence(nu+1);
real[] jpt=sequence(nv+1);
real[][] fx=new real[nu+1][nv+1];
real[][] fy=new real[nu+1][nv+1];
real[][] fz=new real[nu+1][nv+1];
splinetype[] usplinetype=Spline;
splinetype[] vsplinetype=Spline;
for(int i=0; i <nu+1; ++i) {
real ui=i;
real[] fxi=fx[i];
real[] fyi=fy[i];
real[] fzi=fz[i];
for(int j=0; j < nv+1; ++j) {
pair z=(ui,j);
fxi[j]=v[i][j].x;
fyi[j]=v[i][j].y;
fzi[j]=v[i][j].z;
}
}
real[][][] sx=bispline(fx,ipt,jpt);//,usplinetype[0],vsplinetype[0]);
real[][][] sy=bispline(fy,ipt,jpt);//,usplinetype[1],vsplinetype[1]);
real[][][] sz=bispline(fz,ipt,jpt);//,usplinetype[2],vsplinetype[2]);
surface s=surface(sx.length);
s.index=new int[nu][nv];
int k=-1;
for(int i=0; i < nu; ++i) {
int[] indexi=s.index[i];
for(int j=0; j < nv; ++j)
indexi[j]=++k;
}
for(int k=0; k < sx.length; ++k) {
triple[][] Q=new triple[4][];
real[][] Px=sx[k];
real[][] Py=sy[k];
real[][] Pz=sz[k];
for(int i=0; i < 4 ; ++i) {
real[] Pxi=Px[i];
real[] Pyi=Py[i];
real[] Pzi=Pz[i];
Q[i]=new triple[] {(Pxi[0],Pyi[0],Pzi[0]),
(Pxi[1],Pyi[1],Pzi[1]),
(Pxi[2],Pyi[2],Pzi[2]),
(Pxi[3],Pyi[3],Pzi[3])};
}
s.s[k]=patch(Q);
}
draw(s,red);
////// CONTOUR OPENING //////
string fileImpactData = "./data/impactData.dat";
file in1=input(fileImpactData).line().csv();
real[][] a1=in1.dimension(0,0); // 0 pour dire jusqu'à la fin du fichier
a1=transpose(a1);
real[] x1=a1[0];
real[] y1=a1[1];
real[] z1=a1[3];
pen contourpen=green+1.5bp;
draw(graph(x1,y1,z1,operator--),contourpen,currentlight);
////// PLANES ///////
pen bg=gray(0.9)+opacity(0.2);
draw(surface((xmax,ymin,zmin)--(xmax,ymin,zmax)--(xmin,ymin,zmax)--(xmin,ymin,zmin)--cycle),bg);
draw(surface((xmin,ymax,zmin)--(xmin,ymax,zmax)--(xmin,ymin,zmax)--(xmin,ymin,zmin)--cycle),bg);
draw(surface((xmax,ymax,zmin)--(xmax,ymin,zmin)--(xmin,ymin,zmin)--(xmin,ymax,zmin)--cycle),bg);
////// GRID LINES ///////
pen gridpen=.2bp+gray(0.7);
grid3(XYgrid,Step=1,gridpen);
grid3(YXgrid,Step=.5,gridpen);
grid3(XZgrid,Step=1,gridpen);
grid3(ZXgrid,Step=2,gridpen);
grid3(YZgrid,Step=.5,gridpen);
grid3(ZYgrid,Step=2,gridpen);
// No-go zone
draw((xmax,1,zmin)--(xmin,1,zmin)--(xmin,1,zmax),black+1bp);
xaxis3(Label("$x_1$",MidPoint,align=Y-Z),Bounds(Both,Min),InTicks(Step=1),p=black);
yaxis3(Label("$x_2$",MidPoint,align=X-Z),Bounds(Both,Min),InTicks(Step=.5),p=black);
zaxis3(Label("$\dot x_2$",MidPoint,align=X-Y),Bounds(Both,Min),InTicks(Step=2),p=black);
The code is not optimized. You obtain the picture. I do not manage the color palette.
It is possible to have a very short solution (but not very readable).
The "Bézier parametrized" process (50 lines) is replaced by 5 lines.
// Global Asymptote definitions can be put here.
import three;
import grid3;
import palette;
usepackage("mathptmx");
// One can globally override the default toolbar settings here:
// settings.toolbar=true;
import graph3;
real xmin=-2, xmax=2;
real ymin=-2, ymax=1.5;
real zmin=-2.5, zmax=2.5;
limits((xmin,ymin,zmin),(xmax,ymax,zmax));
currentprojection=perspective(camera=(1.5,2,2.5));
unitsize(3cm,3cm,2cm);
real linewidth=1.1;
real linewidthprojections=.15;
string filebasename="./data/ForASY_mnl2ippGridBranche3T1_";
bool renderPRC = false;
if(renderPRC) {
// PRC TRUE
settings.prc=true;
settings.embed=true;
}
else {
// RASTERIZE
settings.outformat="png";
settings.prc=false;
settings.render=3;
}
/////// ORBITS IN 3D, SMOOTH ////////
for (int i=1; i<=50; i=i+2)
{
string filename1 = filebasename + string(i) + "PartI.dat";
file in1=input(filename1).line().csv();
real[][] a1=in1.dimension(0,0); // 0 pour dire jusqu'à la fin du fichier
a1=transpose(a1);
real[] x1=a1[0];
real[] y1=a1[1];
real[] z1=a1[3];
pen orbitpen=.7bp+red*(1-sqrt(1-i/50))+rgb(0,62/255,91/255)*(sqrt(1-i/50));
pen projpen=.3bp+red*(1-sqrt(1-i/50))+rgb(0,62/255,91/255)*(sqrt(1-i/50))+opacity(0.3);
path3 thepath1 = graph(x1, y1, z1, operator..);
draw(thepath1,orbitpen,currentlight);
}
//////// SURFACE PART I ////////
triple[][] v=new triple[50][21];
int increment=1;
for (int i=1; i<52-increment; i=i+increment)
{
string filename1 = filebasename + string(i) + "PartI.dat";
file in1=input(filename1).line().csv();
real[][] a1=in1.dimension(0,0); // 0 pour dire jusqu'à la fin du fichier
a1=transpose(a1);
real[] x=a1[0];
real[] y=a1[1];
real[] z=a1[3];
int step=1;
for (int j=0; j<22-step; j=j+step)
{
v[i-1][j]=(x[j],y[j],z[j]);
}
}
triple f (pair t) {
return(v[round(t.x)][round(t.y)]);
}
surface ns=surface(f,(0,0),(49,20),49,20,Spline);
ns.colors(palette(ns.map(zpart),Rainbow()));
draw(ns,render(merge=true));
////// CONTOUR OPENING //////
string fileImpactData = "./data/impactData.dat";
file in1=input(fileImpactData).line().csv();
real[][] a1=in1.dimension(0,0); // 0 pour dire jusqu'à la fin du fichier
a1=transpose(a1);
real[] x1=a1[0];
real[] y1=a1[1];
real[] z1=a1[3];
pen contourpen=green+1.5bp;
draw(graph(x1,y1,z1,operator--),contourpen,currentlight);
////// PLANES ///////
pen bg=gray(0.9)+opacity(0.2);
draw(surface((xmax,ymin,zmin)--(xmax,ymin,zmax)--(xmin,ymin,zmax)--(xmin,ymin,zmin)--cycle),bg);
draw(surface((xmin,ymax,zmin)--(xmin,ymax,zmax)--(xmin,ymin,zmax)--(xmin,ymin,zmin)--cycle),bg);
draw(surface((xmax,ymax,zmin)--(xmax,ymin,zmin)--(xmin,ymin,zmin)--(xmin,ymax,zmin)--cycle),bg);
////// GRID LINES ///////
pen gridpen=.2bp+gray(0.7);
grid3(XYgrid,Step=1,gridpen);
grid3(YXgrid,Step=.5,gridpen);
grid3(XZgrid,Step=1,gridpen);
grid3(ZXgrid,Step=2,gridpen);
grid3(YZgrid,Step=.5,gridpen);
grid3(ZYgrid,Step=2,gridpen);
// No-go zone
draw((xmax,1,zmin)--(xmin,1,zmin)--(xmin,1,zmax),black+1bp);
xaxis3(Label("$x_1$",MidPoint,align=Y-Z),Bounds(Both,Min),InTicks(Step=1),p=black);
yaxis3(Label("$x_2$",MidPoint,align=X-Z),Bounds(Both,Min),InTicks(Step=.5),p=black);
zaxis3(Label("$\dot x_2$",MidPoint,align=X-Y),Bounds(Both,Min),InTicks(Step=2),p=black);
A similar picture with a color palette.
s
was a surface created by graphing a function or a parametric function, thens.point
gives a parametrization of the surface. For instance,s.point((0,0))
should give one of the four corners; and if the patches form (say) an8 x 8
grid, then the opposite corner is given (roughly) bys.point((7.9999, 7.9999))
. However, if the surface is constructed by some means other than graphing function(s), thens.point
returns nonsense.