Browse Source

- cleaned up polyvector field example
- cleaned up itnerface of n_polyvector


Former-commit-id: 6a02bc37147c08d20e53d618f4f4964338b52df4

Daniele Panozzo 11 years ago
parent
commit
81238fbfd2

+ 6 - 4
include/igl/conjugate_frame_fields.h

@@ -15,8 +15,10 @@
 
 namespace igl {
   //todo
+  // TODO: isConstrained should become a list of indices for consistency with
+  //       n_polyvector
   /// Given 2 vectors centered on origin calculate the rotation matrix from first to the second
-  
+
   // Inputs:
   //   v0, v1         the two #3 by 1 vectors
   //   normalized     boolean, if false, then the vectors are normalized prior to the calculation
@@ -25,7 +27,7 @@ namespace igl {
   //
   template <typename DerivedV, typename DerivedF>
   class ConjugateFFSolverData;
-  
+
   template <typename DerivedV, typename DerivedF, typename DerivedO>
   IGL_INLINE void conjugate_frame_fields(const Eigen::PlainObjectBase<DerivedV> &V,
                                          const Eigen::PlainObjectBase<DerivedF> &F,
@@ -37,7 +39,7 @@ namespace igl {
                                          const typename DerivedV::Scalar &_lambdaInit = 100,
                                          const typename DerivedV::Scalar &_lambdaMultFactor = 1.01,
                                          bool _doHardConstraints = true);
-  
+
   template <typename DerivedV, typename DerivedF, typename DerivedO>
   IGL_INLINE void conjugate_frame_fields(const ConjugateFFSolverData<DerivedV, DerivedF> &csdata,
                                          const Eigen::VectorXi &isConstrained,
@@ -49,7 +51,7 @@ namespace igl {
                                          const typename DerivedV::Scalar &_lambdaMultFactor = 1.01,
                                          bool _doHardConstraints = true,
                                          typename DerivedV::Scalar *lambdaOut = NULL);
-  
+
 };
 
 

+ 15 - 8
include/igl/n_polyvector.cpp

@@ -479,20 +479,27 @@ IGL_INLINE void igl::PolyVectorFieldFinder<DerivedV, DerivedF>::computek()
 }
 
 
-template <typename DerivedV, typename DerivedF>
-IGL_INLINE void igl::n_polyvector(const Eigen::PlainObjectBase<DerivedV> &V,
-                             const Eigen::PlainObjectBase<DerivedF> &F,
-                             const Eigen::VectorXi &isConstrained,
-                             const Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> &cfW,
-                             Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> &output)
+IGL_INLINE void igl::n_polyvector(const Eigen::MatrixXd &V,
+                             const Eigen::MatrixXi &F,
+                             const Eigen::VectorXi& b,
+                             const Eigen::MatrixXd& bc,
+                             Eigen::MatrixXd &output)
 {
+  Eigen::VectorXi isConstrained = Eigen::VectorXi::Constant(F.rows(),0);
+  Eigen::MatrixXd cfW = Eigen::MatrixXd::Constant(F.rows(),bc.cols(),0);
+
+  for(unsigned i=0; i<b.size();++i)
+  {
+    isConstrained(b(i)) = 1;
+    cfW.row(b(i)) << bc.row(i);
+  }
+
   int n = cfW.cols()/3;
-  igl::PolyVectorFieldFinder<DerivedV, DerivedF> pvff(V,F,n);
+  igl::PolyVectorFieldFinder<Eigen::MatrixXd, Eigen::MatrixXi> pvff(V,F,n);
   pvff.solve(isConstrained, cfW, output);
 }
 
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
-template void igl::n_polyvector<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::Matrix<Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar, -1, -1, 0, -1, -1> const&, Eigen::Matrix<Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar, -1, -1, 0, -1, -1>&);
 #endif

+ 6 - 6
include/igl/n_polyvector.h

@@ -23,12 +23,12 @@ namespace igl {
   // Output:
   //                  3 by 3 rotation matrix that takes v0 to v1
   //
-  template <typename DerivedV, typename DerivedF>
-  IGL_INLINE void n_polyvector(const Eigen::PlainObjectBase<DerivedV> &V,
-                               const Eigen::PlainObjectBase<DerivedF> &F,
-                               const Eigen::VectorXi &isConstrained,
-                               const Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> &cfW,
-                               Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> &output);
+
+  IGL_INLINE void n_polyvector(const Eigen::MatrixXd& V,
+                               const Eigen::MatrixXi& F,
+                               const Eigen::VectorXi& b,
+                               const Eigen::MatrixXd& bc,
+                               Eigen::MatrixXd &output);
 
 };
 

+ 54 - 48
tutorial/507_PolyVectorField/main.cpp

@@ -5,66 +5,84 @@
 #include <igl/avg_edge_length.h>
 #include <vector>
 #include <igl/n_polyvector.h>
+#include <igl/local_basis.h>
 #include <stdlib.h>
+#include <igl/jet.h>
 
 // Input mesh
 Eigen::MatrixXd V;
 Eigen::MatrixXi F;
 
+// Per face bases
+Eigen::MatrixXd B1,B2,B3;
+
 // Face barycenters
 Eigen::MatrixXd B;
 
 // Scale for visualizing the fields
 double global_scale;
 
-// Input constraints
-Eigen::VectorXi isConstrained;
-std::vector<Eigen::MatrixXd> constraints;
+// Random length factor
+double rand_factor = 5;
+
+// Create a random set of tangent vectors
+Eigen::VectorXd random_constraints(const
+                                   Eigen::VectorXd& b1, const
+                                   Eigen::VectorXd& b2, int n)
+{
+  Eigen::VectorXd r(n*3);
+  for (unsigned i=0; i<n;++i)
+  {
+    double a = (double(rand())/RAND_MAX)*2*M_PI;
+    double s = 1 + ((double(rand())/RAND_MAX)) * rand_factor;
+    Eigen::Vector3d t = s * (cos(a) * b1 + sin(a) * b2);
+    r.block(i*3,0,3,1) = t;
+  }
+  return r;
+}
 
 bool key_down(igl::Viewer& viewer, unsigned char key, int modifier)
 {
   using namespace std;
   using namespace Eigen;
 
-  if (key <'1' || key >'4')
+  if (key <'1' || key >'8')
     return false;
 
-  viewer.clear();
-  viewer.set_mesh(V, F);
-  viewer.core.show_lines = false;
-  viewer.core.show_texture = false;
+  viewer.data.lines.resize(0,9);
 
   int num = key  - '0';
 
   // Interpolate
-  cerr<<"Interpolating N-PolyVector field for N = "<<num<<"... ";
+  cerr << "Interpolating " << num * 2 << "-PolyVector field" << endl;
+
+  VectorXi b(3);
+  b << 1511, 603, 506;
+
+  MatrixXd bc(b.size(),num*3);
+  for (unsigned i=0; i<b.size(); ++i)
+  {
+    VectorXd t = random_constraints(B1.row(b(i)),B2.row(b(i)),num);
+    bc.row(i) = t;
+  }
 
   // Interpolated PolyVector field
   Eigen::MatrixXd pvf;
-  igl::n_polyvector(V, F, isConstrained, constraints[num-1], pvf);
+  igl::n_polyvector(V, F, b, bc, pvf);
 
   // Highlight in red the constrained faces
   MatrixXd C = MatrixXd::Constant(F.rows(),3,1);
-  for (unsigned i=0; i<F.rows();++i)
-    if (isConstrained[i])
-    C.row(i) << 1, 0, 0;
+  for (unsigned i=0; i<b.size();++i)
+    C.row(b(i)) << 1, 0, 0;
   viewer.set_colors(C);
 
   for (int n=0; n<num; ++n)
   {
-    // Frame field constraints
-    MatrixXd F_t = MatrixXd::Zero(F.rows(),3);
-    for (unsigned i=0; i<F.rows();++i)
-      if (isConstrained[i])
-        F_t.row(i) = constraints[num-1].block(i,n*3,1,3);
-    viewer.add_edges (B, B + global_scale*F_t , Eigen::RowVector3d(0,0,1));
-
-    const Eigen::MatrixXd &pvf_t = pvf.block(0,n*3,F.rows(),3);
-    for (unsigned i=0; i<F.rows();++i)
-      if (isConstrained[i])
-        F_t.row(i) *= 0;
-
-    viewer.add_edges (B, B + global_scale*pvf_t , Eigen::RowVector3d(0,0,1));
+    const MatrixXd &VF = pvf.block(0,n*3,F.rows(),3);
+    VectorXd c = VF.rowwise().norm();
+    MatrixXd C2;
+    igl::jet(c,1,1+rand_factor,C2);
+    viewer.add_edges (B - global_scale*VF, B + global_scale*VF , C2);
   }
 
 
@@ -78,34 +96,22 @@ int main(int argc, char *argv[])
   // Load a mesh in OBJ format
   igl::readOBJ("../shared/snail.obj", V, F);
 
+  // Compute local basis for faces
+  igl::local_basis(V,F,B1,B2,B3);
+
   // Compute face barycenters
   igl::barycenter(V, F, B);
 
   // Compute scale for visualizing fields
-  global_scale =  .2*igl::avg_edge_length(V, F);
-
-  // Allocate constraints and polyvector field
-  constraints.resize(4);
-
-  // Load constraints
-  MatrixXd temp;
-  for (int n =0; n<=3; ++n)
-  {
-    char cfile[1024]; sprintf(cfile, "../shared/snail%d.dmat",n+1);
-
-    igl::readDMAT(cfile,temp);
-    if (n == 0)
-      isConstrained = temp.block(0,0,temp.rows(),1).cast<int>();
-
-    constraints[n] = temp.block(0,1,temp.rows(),temp.cols()-1);
-  }
-
+  global_scale =  .1*igl::avg_edge_length(V, F);
 
+  // Make the example deterministic
+  srand(0);
+  
   igl::Viewer viewer;
-
-  key_down(viewer,'5',0);
-
-  // Launch the viewer
+  viewer.set_mesh(V, F);
   viewer.callback_key_down = &key_down;
+  viewer.core.show_lines = false;
+  key_down(viewer,'3',0);
   viewer.launch();
 }

+ 17 - 17
tutorial/508_ConjugateField/main.cpp

@@ -1,6 +1,7 @@
 #undef IGL_STATIC_LIBRARY
 #include <igl/readOBJ.h>
 #include <igl/readDMAT.h>
+#include <igl/writeDMAT.h>
 #include <igl/viewer/Viewer.h>
 #include <igl/barycenter.h>
 #include <igl/avg_edge_length.h>
@@ -39,8 +40,8 @@ Eigen::MatrixXd PQCp0, PQCp1, PQCp2, PQCp3;
 double global_scale;
 
 // Input constraints
-Eigen::VectorXi isConstrained;
-Eigen::MatrixXd constraints;
+Eigen::VectorXi b;
+Eigen::MatrixXd bc;
 
 Eigen::MatrixXd smooth_pvf;
 Eigen::MatrixXd conjugate_pvf;
@@ -58,9 +59,8 @@ bool key_down(igl::Viewer& viewer, unsigned char key, int modifier)
   viewer.data.lines.resize(0,9);
   // Highlight in red the constrained faces
   MatrixXd C = MatrixXd::Constant(F.rows(),3,1);
-  for (unsigned i=0; i<F.rows();++i)
-    if (isConstrained[i])
-      C.row(i) << 1, 0, 0;
+  for (unsigned i=0; i<b.size();++i)
+      C.row(b(i)) << 1, 0, 0;
   viewer.set_colors(C);
 
   if (key == '1')
@@ -69,12 +69,11 @@ bool key_down(igl::Viewer& viewer, unsigned char key, int modifier)
     MatrixXd F1_t = MatrixXd::Zero(F.rows(),3);
     MatrixXd F2_t = MatrixXd::Zero(F.rows(),3);
 
-    for (unsigned i=0; i<F.rows();++i)
-      if (isConstrained[i])
-      {
-        F1_t.row(i) = constraints.block(i,0,1,3);
-        F2_t.row(i) = constraints.block(i,3,1,3);
-      }
+    for (unsigned i=0; i<b.size();++i)
+    {
+      F1_t.row(b(i)) = bc.block(i,0,1,3);
+      F2_t.row(b(i)) = bc.block(i,3,1,3);
+    }
 
     viewer.add_edges (B - global_scale*F1_t, B + global_scale*F1_t , Eigen::RowVector3d(0,0,1));
     viewer.add_edges (B - global_scale*F2_t, B + global_scale*F2_t , Eigen::RowVector3d(0,0,1));
@@ -120,13 +119,11 @@ int main(int argc, char *argv[])
   global_scale =  .4*igl::avg_edge_length(V, F);
 
   // Load constraints
-  MatrixXd temp;
-  igl::readDMAT("../shared/inspired_mesh.dmat",temp);
-  isConstrained = temp.block(0,0,temp.rows(),1).cast<int>();
-  constraints = temp.block(0,1,temp.rows(),temp.cols()-1);
+  igl::readDMAT("../shared/inspired_mesh_b.dmat",b);
+  igl::readDMAT("../shared/inspired_mesh_bc.dmat",bc);
 
   // Interpolate to get a smooth field
-  igl::n_polyvector(V, F, isConstrained, constraints, smooth_pvf);
+  igl::n_polyvector(V, F, b, bc, smooth_pvf);
 
   // Initialize conjugate field with smooth field
   csdata = new igl::ConjugateFFSolverData<Eigen::MatrixXd,Eigen::MatrixXi>(V,F);
@@ -134,12 +131,15 @@ int main(int argc, char *argv[])
 
   // Optimize the field
   int conjIter = 20;
-  int totalConjIter = 0;
   double lambdaOrtho = .1;
   double lambdaInit = 100;
   double lambdaMultFactor = 1.01;
   bool doHardConstraints = true;
   double lambdaOut;
+  VectorXi isConstrained = VectorXi::Constant(F.rows(),0);
+  for (unsigned i=0; i<b.size(); ++i)
+    isConstrained(b(i)) = 1;
+  
   igl::conjugate_frame_fields(*csdata, isConstrained, conjugate_pvf, conjugate_pvf, conjIter, lambdaOrtho, lambdaInit, lambdaMultFactor, doHardConstraints,
                               &lambdaOut);
 

+ 85 - 0
tutorial/shared/inspired_mesh_b.dmat

@@ -0,0 +1,85 @@
+1 84
+26
+27
+28
+29
+30
+31
+32
+33
+34
+94
+95
+96
+97
+98
+99
+100
+101
+163
+164
+165
+166
+167
+232
+233
+1974
+1975
+1976
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2239
+2240
+2241
+2242
+2243
+2244
+2245
+2308
+2309
+2310
+2311
+4118
+4119
+4120
+4121
+4122
+4184
+4185
+4186
+4187
+4188
+4189
+4190
+4191
+4251
+4252
+4253
+4254
+4255
+4256
+4257
+4258
+4259

+ 505 - 0
tutorial/shared/inspired_mesh_bc.dmat

@@ -0,0 +1,505 @@
+6 84
+-0.35349288582801819
+-0.3813517689704895
+0.7788470983505249
+-0.744842529296875
+0.47427588701248169
+0.67033940553665161
+0.62965637445449829
+-0.58722084760665894
+-0.62760895490646362
+0.81848102807998657
+-0.45324945449829102
+0.76021295785903931
+0.72717535495758057
+-0.54792094230651855
+0.65510499477386475
+0.61564821004867554
+0.65522176027297974
+-0.77775400876998901
+-0.74818402528762817
+0.71684420108795166
+-0.60136663913726807
+-0.64588922262191772
+0.73761826753616333
+-0.6149299144744873
+-0.57098591327667236
+-0.60427707433700562
+-0.68069422245025635
+-0.51061797142028809
+-0.54587322473526001
+-0.7010352611541748
+-0.61777430772781372
+-0.62765330076217651
+-0.59036928415298462
+0.72055935859680176
+-0.78870397806167603
+-0.47657808661460876
+0.71752166748046875
+0.6782868504524231
+-0.59586054086685181
+0.63514095544815063
+-0.5586656928062439
+0.70995509624481201
+-0.48370689153671265
+-0.38943728804588318
+-0.81332337856292725
+0.44922548532485962
+0.48171544075012207
+-0.51672583818435669
+0.5525173544883728
+0.5913538932800293
+0.63185042142868042
+0.82150381803512573
+-0.79593157768249512
+-0.76744270324707031
+0.73602473735809326
+-0.57768625020980835
+-0.66558927297592163
+0.62663638591766357
+-0.78284817934036255
+0.56231123208999634
+-0.72416442632675171
+0.62678784132003784
+-0.7533223032951355
+0.72106426954269409
+0.68651920557022095
+-0.62743765115737915
+-0.66253823041915894
+0.77172678709030151
+-0.48659807443618774
+0.52337509393692017
+0.56156182289123535
+0.60050344467163086
+0.59159553050994873
+-0.55461359024047852
+-0.51789486408233643
+0.4090455174446106
+0.71415841579437256
+0.67563140392303467
+0.63541758060455322
+0.59514933824539185
+0.55588448047637939
+-0.65945702791213989
+0.48101454973220825
+0.44661587476730347
+-0.7943570613861084
+-0.79425632953643799
+-0.56136071681976318
+0.58586859703063965
+0.78737145662307739
+-0.62523496150970459
+-0.64140981435775757
+0.65631842613220215
+-0.72420001029968262
+-0.53916913270950317
+-0.79632323980331421
+-0.59142404794692993
+-0.61309421062469482
+-0.77428638935089111
+-0.64929050207138062
+-0.6646379828453064
+0.71631318330764771
+0.58516007661819458
+0.60752654075622559
+-0.62769037485122681
+-0.76208615303039551
+0.66276472806930542
+-0.62344080209732056
+-0.76465469598770142
+0.79210847616195679
+0.77452665567398071
+-0.64831310510635376
+0.81103414297103882
+0.79801183938980103
+-0.62232542037963867
+0.76139330863952637
+-0.65360605716705322
+-0.6659163236618042
+-0.68151766061782837
+-0.54498875141143799
+0.81397217512130737
+0.5962633490562439
+0.61695128679275513
+0.76600515842437744
+-0.74206608533859253
+-0.65974521636962891
+-0.6841731071472168
+-0.67748314142227173
+-0.78935432434082031
+0.54631167650222778
+0.78644305467605591
+0.78280985355377197
+-0.77588522434234619
+0.76451981067657471
+0.7480008602142334
+0.72560358047485352
+-0.54667192697525024
+0.57365614175796509
+0.59865254163742065
+-0.62163716554641724
+-0.76586246490478516
+0.66167920827865601
+-0.67893046140670776
+0.5923888087272644
+0.78494584560394287
+0.63742935657501221
+0.75198596715927124
+-0.59575927257537842
+0.61808007955551147
+0.63782942295074463
+0.74847245216369629
+0.72432559728622437
+0.56374651193618774
+0.80341094732284546
+-0.7917705774307251
+-0.77675896883010864
+-0.75748783349990845
+0.65965640544891357
+-0.67197728157043457
+-0.68262088298797607
+-0.80810147523880005
+0.58669739961624146
+0.60890376567840576
+0.62761294841766357
+0.64352279901504517
+0.65701061487197876
+0.70951837301254272
+0.67740911245346069
+0.68606787919998169
+0.49400371313095093
+0.47299858927726746
+-0.27977007627487183
+0.31932356953620911
+-0.39383819699287415
+-0.39965778589248657
+-0.43832212686538696
+0.47372758388519287
+0.28572943806648254
+-0.19845768809318542
+0.40054243803024292
+-0.26887524127960205
+-0.30875799059867859
+0.31664362549781799
+-0.38634088635444641
+-0.42335990071296692
+-0.23995810747146606
+0.22953499853610992
+0.26670607924461365
+-0.3035443127155304
+0.23996424674987793
+0.37890636920928955
+-0.25930845737457275
+0.19278071820735931
+0.2157297283411026
+0.1869698166847229
+0.34109458327293396
+0.28546968102455139
+0.25534206628799438
+0.34822496771812439
+0.19655825197696686
+0.42290714383125305
+0.45609167218208313
+-0.1277807205915451
+0.28448781371116638
+0.33214855194091797
+-0.36004537343978882
+-0.39912155270576477
+0.24121852219104767
+-0.21432188153266907
+0.50262200832366943
+-0.16694590449333191
+0.55411571264266968
+0.47461384534835815
+0.20012149214744568
+-0.42391479015350342
+-0.39390230178833008
+0.36193442344665527
+-0.33201512694358826
+-0.30132254958152771
+-0.27251520752906799
+-0.16211526095867157
+0.19342054426670074
+0.22944889962673187
+-0.26802012324333191
+0.28237080574035645
+0.34521234035491943
+-0.38259676098823547
+0.19032660126686096
+-0.26012721657752991
+0.26319146156311035
+-0.20409354567527771
+0.27852544188499451
+-0.31311878561973572
+-0.34909161925315857
+0.21473453938961029
+0.19077596068382263
+-0.29432576894760132
+0.3431517481803894
+-0.31492507457733154
+-0.28512081503868103
+-0.25614029169082642
+-0.46353873610496521
+0.4907650351524353
+0.5155712366104126
+-0.42385584115982056
+-0.38179045915603638
+-0.41564211249351501
+-0.44982942938804626
+-0.48132699728012085
+-0.50924402475357056
+0.24839507043361664
+-0.55654460191726685
+-0.574321448802948
+0.83780395984649658
+-0.80967211723327637
+-0.41006582975387573
+0.44118943810462952
+-0.70814687013626099
+0.50875502824783325
+-0.54657566547393799
+0.58651858568191528
+0.54409134387969971
+-0.42404800653457642
+-0.79078960418701172
+0.48393112421035767
+-0.51561033725738525
+-0.69269132614135742
+-0.5826566219329834
+-0.61856508255004883
+-0.57505595684051514
+0.50655931234359741
+-0.53741276264190674
+-0.56850004196166992
+0.68242424726486206
+-0.63491541147232056
+-0.58406537771224976
+0.70646977424621582
+-0.74695229530334473
+0.71469765901565552
+0.63731902837753296
+0.768440842628479
+0.73609638214111328
+0.58199715614318848
+-0.66463488340377808
+0.65301549434661865
+0.68739980459213257
+-0.5531650185585022
+0.43693715333938599
+0.75364702939987183
+-0.51525044441223145
+0.55576223134994507
+-0.63810747861862183
+-0.59812253713607788
+0.67326205968856812
+-0.51996308565139771
+0.74330544471740723
+0.839466392993927
+-0.4188886284828186
+-0.78470003604888916
+0.75270462036132812
+0.71763736009597778
+-0.68068069219589233
+-0.64020729064941406
+-0.59759795665740967
+-0.45146811008453369
+0.48096767067909241
+-0.51183754205703735
+-0.54442566633224487
+-0.70242577791213989
+0.61298829317092896
+0.64940345287322998
+0.53125792741775513
+-0.75468790531158447
+0.59378618001937866
+0.69049149751663208
+-0.52270811796188354
+0.5567401647567749
+-0.59184050559997559
+0.65062659978866577
+0.6141437292098999
+0.45014002919197083
+-0.73839503526687622
+-0.70349311828613281
+-0.66666603088378906
+-0.62909060716629028
+-0.63906764984130859
+0.67666143178939819
+0.71308565139770508
+-0.75135558843612671
+-0.44854232668876648
+-0.48896420001983643
+-0.5314146876335144
+0.57476764917373657
+-0.61767840385437012
+0.51783454418182373
+-0.69966650009155273
+-0.73643374443054199
+-0.50375008583068848
+0.53388828039169312
+-0.79325658082962036
+0.79146355390548706
+0.60697656869888306
+0.77931028604507446
+-0.76670461893081665
+0.74835824966430664
+-0.67051386833190918
+-0.79997950792312622
+0.56658565998077393
+0.79162436723709106
+-0.78476220369338989
+0.63216590881347656
+-0.75969094038009644
+-0.74044156074523926
+0.67892652750015259
+0.79970455169677734
+-0.79063767194747925
+-0.77823972702026367
+-0.64612609148025513
+-0.74192923307418823
+-0.78181236982345581
+-0.64280223846435547
+-0.61029016971588135
+0.63062667846679688
+-0.75366979837417603
+0.57941031455993652
+0.60232985019683838
+-0.78146493434906006
+-0.63916146755218506
+-0.73777186870574951
+-0.7109796404838562
+-0.6761089563369751
+-0.82245540618896484
+0.57279998064041138
+0.80219244956970215
+-0.78607004880905151
+-0.63396328687667847
+-0.64809030294418335
+-0.71464955806732178
+-0.66911762952804565
+-0.65223944187164307
+-0.51622092723846436
+-0.78855186700820923
+0.57416284084320068
+-0.59978669881820679
+-0.6230614185333252
+0.64376425743103027
+0.66267204284667969
+0.67995995283126831
+-0.79726135730743408
+0.79323685169219971
+-0.7876250147819519
+-0.77886563539505005
+0.64264160394668579
+0.74853527545928955
+0.72631806135177612
+0.79560816287994385
+0.61572021245956421
+0.77041840553283691
+-0.65741604566574097
+0.79941308498382568
+-0.78586661815643311
+0.76908838748931885
+0.65544241666793823
+0.67112231254577637
+-0.81114691495895386
+-0.58814346790313721
+-0.61004561185836792
+-0.6288456916809082
+-0.64527767896652222
+0.73420155048370361
+-0.70746886730194092
+-0.67741495370864868
+-0.56185394525527954
+0.80229586362838745
+0.79203903675079346
+0.77808386087417603
+-0.75947046279907227
+0.73644858598709106
+0.66827744245529175
+0.67913424968719482
+0.64642047882080078
+-0.21052411198616028
+0.24370957911014557
+0.45009994506835938
+-0.42300981283187866
+0.36070412397384644
+-0.36584663391113281
+0.33677741885185242
+-0.30976742506027222
+-0.50435680150985718
+0.42451867461204529
+0.23158684372901917
+-0.37301677465438843
+0.34393933415412903
+0.34719589352607727
+0.28875753283500671
+0.26291358470916748
+0.45647495985031128
+-0.32228922843933105
+0.29339325428009033
+0.26674070954322815
+-0.34178683161735535
+0.21546086668968201
+0.21825917065143585
+-0.29615160822868347
+0.26383373141288757
+-0.30251812934875488
+-0.16064336895942688
+-0.2716289758682251
+-0.30880552530288696
+-0.22492633759975433
+0.38695359230041504
+-0.17106550931930542
+-0.14828863739967346
+0.48670849204063416
+-0.36421561241149902
+-0.32236054539680481
+0.30166909098625183
+-0.27059602737426758
+0.4369317889213562
+0.47141110897064209
+-0.18972146511077881
+0.53096133470535278
+-0.14859582483768463
+-0.16974157094955444
+0.45024242997169495
+0.23362979292869568
+-0.27146202325820923
+-0.31111273169517517
+0.34963038563728333
+0.38858765363693237
+0.42488953471183777
+0.40068796277046204
+-0.37342384457588196
+0.3430294394493103
+0.31139847636222839
+0.30595716834068298
+-0.25286409258842468
+-0.22524923086166382
+-0.29115751385688782
+0.22657187283039093
+-0.23210664093494415
+-0.3017045259475708
+0.29616713523864746
+-0.26917287707328796
+0.24130441248416901
+-0.38351041078567505
+-0.41523763537406921
+-0.37338268756866455
+0.32993942499160767
+0.36461174488067627
+0.40013688802719116
+0.43343010544776917
+0.22921746969223022
+-0.20400269329547882
+-0.18060393631458282
+0.3460996150970459
+0.39386686682701111
+0.36549714207649231
+0.33493870496749878
+-0.30470764636993408
+0.27589273452758789
+-0.53409045934677124
+0.22190850973129272
+0.19951426982879639