88 std::function<
double(
const RealPoint3D&)> input_function,
89 std::function<
double(
const RealPoint3D&)> target_function,
90 int argc,
char** argv)
97 digitizer.attach(shape);
103 trace.
beginBlock(
"Construct the Khalimsky space from the image domain." );
109 trace.
error() <<
"Error in the Khamisky space construction."<<std::endl;
117 MySurfelAdjacency surfAdj(
true );
122 MySetOfSurfels theSetOfSurfels( kspace, surfAdj );
128 trace.
info() <<
"Digital surface has " << digSurf.
size() <<
" surfels."
135 typedef std::map< MyDigitalSurface::Vertex, TriMesh::Index > VertexMap;
141 ( digSurf, canonicCellembedder, trimesh, vmap );
143 trace.
info() <<
"Triangulated surface is " << trimesh << std::endl;
151 for(
auto v : vertices)
153 trimesh.position( v ) *= options.h;
154 if(options.smooth == 1)
155 trimesh.position( v ) /= trimesh.position( v ).norm();
158 std::ofstream error_out(options.error_output, std::ofstream::app);
159 std::ofstream function_out(
"function.dat");
161 Eigen::VectorXd laplacian_result( trimesh.nbVertices() );
162 Eigen::VectorXd error( trimesh.nbVertices() );
163 Eigen::VectorXd error_faces( trimesh.nbFaces() );
165 double total_area = 0.;
168 for(
auto v : vertices)
175 for(
auto a : out_arcs)
178 const RealPoint3D p_j = trimesh.position( trimesh.head(a) );
185 const RealPoint3D p2 = trimesh.position( trimesh.head( next_left_arc ) );
190 const RealPoint3D pp2 = trimesh.position(trimesh.head( next_right_arc ));
199 const double alpha = acos( v1.dot(v2) );
200 const double beta = acos( vv1.
dot(vv2) );
203 accum += (tan(M_PI_2 - alpha) + tan(M_PI_2 - beta)) * (input_function(p_j) - input_function(p_i));
206 double accum_area = 0.;
208 for(
auto f : faces_around)
216 const double faceArea = .5 * cross.
norm();
218 accum_area += faceArea / 3.;
221 total_area += accum_area;
223 (options.smooth == 1)
224 ? laplacian_result(i) = (1 / (2. * accum_area)) * accum
225 : laplacian_result(i) = .5 * accum;
228 const double real_laplacian_value = target_function(w_projected);
232 function_out << w_s[1] <<
" "
234 << laplacian_result(i) <<
" "
235 << real_laplacian_value <<
" "
236 << input_function(p_i) << std::endl;
238 error(i) = laplacian_result(i) - real_laplacian_value;
239 for(
auto f : faces_around)
240 error_faces( f ) += error(i) / faces_around.size();
247 trace.
info() <<
"Computed Area / Real Area : " << total_area <<
" " << 4 * M_PI << std::endl;
248 trace.
info() <<
"Mean Error / Max Error : "
249 << error.array().abs().mean() <<
" / " << error.array().abs().maxCoeff(&max_index) << std::endl;
250 error_out << options.h <<
" "
251 << error.array().abs().mean() <<
" "
252 << error.array().abs().maxCoeff() << std::endl;
259 trace.
info() <<
"Mesh has " << viewmesh.nbVertex()
260 <<
" vertices and " << viewmesh.nbFaces() <<
" faces." << std::endl;
263 for(
unsigned int k = 0; k < viewmesh.nbFaces(); k++)
264 viewmesh.setFaceColor(k, colormap_error( error_faces(k) ));
266 QApplication application(argc,argv);
270 viewer << Viewer3D<>::updateDisplay;
280 options.function = 0;
282 options.error_output =
"error_out.dat";
285 Ball ball(
Point(0.0,0.0,0.0), 1.0);
291 return 2 * cos(p_s[1]) * cos(p_s[1]) * (2 * cos(p_s[2]) * cos(p_s[2]) - sin(p_s[2]) * sin(p_s[2]))
292 + 2 * (sin(p_s[1]) * sin(p_s[1]) - cos(p_s[1]) * cos(p_s[1]));
299 return - 2 * cos(p_s[2]);
305 return exp(p_sphere[0]);
312 if(p_s[1] == 0 && p_s[2] == 0)
return 1.;
314 const double theta_derivative = (sin(p_s[1]) * sin(p_s[1]) * sin(p_s[2])
315 - cos(p_s[1])) * (1 / sin(p_s[2])) * exp(p_sphere[0]);
316 const double phi_derivative = ( cos(p_s[1]) * cos(p_s[2]) * cos(p_s[2])
318 + cos(p_s[2]) * cos(p_s[2]) / sin(p_s[2])) * cos(p_s[1]) * exp(p_sphere[0]);
320 return theta_derivative + phi_derivative;
323 std::function<double(
const RealPoint3D&)> input_function
324 = ( options.function == 0 ) ? xx_function : ( (options.function == 1) ? cos_function : exp_function );
325 std::function<double(
const RealPoint3D&)> target_function
326 = ( options.function == 0 ) ? xx_result : ( (options.function == 1) ? cos_result : exp_result );
328 laplacian<Ball>(ball, options, input_function, target_function, argc, argv);
const Point & lowerBound() const
const Point & upperBound() const
auto crossProduct(PointVector< 3, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< 3, RightEuclideanRing, RightContainer > const &rhs) -> decltype(DGtal::constructFromArithmeticConversion(lhs, rhs))
Cross product of two 3D Points/Vectors.