From 87c5c0bf455d5c7d5ae177d1803991ef09267575 Mon Sep 17 00:00:00 2001 From: "christian.wuelker" Date: Wed, 22 May 2013 13:32:48 +0000 Subject: [PATCH] added DataOutBase::write_svg. GridOut::write_svg now provides a perspective view git-svn-id: https://svn.dealii.org/trunk@29549 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/doc/news/changes.h | 24 +- deal.II/include/deal.II/base/data_out_base.h | 195 +++- deal.II/include/deal.II/grid/grid_out.h | 36 +- deal.II/source/base/data_out_base.cc | 879 ++++++++++++++++++- deal.II/source/grid/grid_out.cc | 17 +- 5 files changed, 1111 insertions(+), 40 deletions(-) diff --git a/deal.II/doc/news/changes.h b/deal.II/doc/news/changes.h index 7f7d99099b..bd768a25f7 100644 --- a/deal.II/doc/news/changes.h +++ b/deal.II/doc/news/changes.h @@ -384,13 +384,17 @@ sense. (Guido Kanschat, 2013/03/21) -
  • Added GridOut::write_svg to allow for the output of two-dimensional -triangulations in two space dimensions in the SVG format (Scalable Vector -Graphics, an XML-based vector image format recommended by the World -Wide Web Consortium W3C). This function also provides cell coloring -and cell labeling for the visualization of basic cell properties. +
  • Added GridOut::write_svg() to allow for the output of +two-dimensional triangulations in two space dimensions in the SVG +format (Scalable Vector Graphics, an generic XML-based vector image +format developed and maintained by the World Wide Web Consortium W3C). +This function also provides cell coloring and cell labeling for the +visualization of basic cell properties. Pespective view is further +possible and the cell level number may be converted into altitude, +revealing the inactive cells lying below.
    (Christian Wülker, 2013/03/21) +
  • Added TimerOutput::reset to remove the collected information so far and added a new frequency TimerOutput::never to only output information if @@ -415,6 +419,16 @@ This is now fixed. (Timo Heister, 2013/03/01)
  • +
  • Added DataOutBase::write_svg() to allow for the output of a given +list of patches in two space dimensions in the SVG format (Scalable Vector +Graphics, an generic XML-based vector image format developed and maintained +by the World Wide Web Consortium W3C). An additional dimension (z-direction) +is employed for the visualization of data values taken from a data vector. +This function also provides patch coloring for the visual enhancement. +
    +(Christian Wülker, 2013/05/10) +
  • + diff --git a/deal.II/include/deal.II/base/data_out_base.h b/deal.II/include/deal.II/base/data_out_base.h index ec985fa6e0..0ce000d902 100644 --- a/deal.II/include/deal.II/base/data_out_base.h +++ b/deal.II/include/deal.II/base/data_out_base.h @@ -1269,6 +1269,75 @@ public: }; + /** + * Flags for SVG output. + */ + struct SvgFlags + { + public: + /** + * This denotes the number of the + * data vector which shall be used + * for generating the height + * information. By default, the + * first data vector is taken, + * i.e. height_vector==0, if + * there is any data vector. If there + * is no data vector, no height + * information is generated. + */ + unsigned int height_vector; + + /* + * Angles for the perspective view + */ + int azimuth_angle, polar_angle; + + unsigned int line_thickness; + + /* + * Draw a margin of 5% around the plotted area + */ + bool margin; + + /* + * Draw a colorbar encoding the cell coloring + */ + bool draw_colorbar; + + /* + * Constructor. + */ + SvgFlags(const unsigned int height_vector = 0, + const int azimuth_angle = 37, + const int polar_angle = 45, + const unsigned int line_thickness = 1, + const bool margin = true, + const bool draw_colorbar = true); + + /** + * Determine an estimate for + * the memory consumption (in + * bytes) of this + * object. Since sometimes + * the size of objects can + * not be determined exactly + * (for example: what is the + * memory consumption of an + * STL std::map type with a + * certain number of + * elements?), this is only + * an estimate. however often + * quite close to the true + * value. + */ + std::size_t memory_consumption () const; + + private: + + }; + + /** * Flags controlling the details * of output in deal.II @@ -1421,6 +1490,12 @@ public: */ vtu, + /** + * Output in + * SVG format. + */ + svg, + /** * Output in deal.II * intermediate format. @@ -1790,7 +1865,35 @@ public: const std::vector > &vector_data_ranges, const VtkFlags &flags, std::ostream &out); - + + /** + * Write the given list of patches to the output stream in SVG format. + * + * SVG (Scalable Vector Graphics) is an XML-based vector image format + * developed and maintained by the World Wide Web Consortium (W3C). + * This function conforms to the latest specification SVG 1.1, + * released on August 16, 2011. Controlling the graphic output is + * possible by setting or clearing the respective flags (see the + * SvgFlags struct). At present, this format only supports output + * for two-dimensional data, with values in the third direction + * taken from a data vector. + * + * For the output, each patch is subdivided into four triangles + * which are then written as polygons and filled with a linear + * color gradient. The arising coloring of the patches visualizes + * the data values at the vertices taken from the specified data + * vector. A colorbar can be drawn to encode the coloring. + * + * @note Yet only implemented for two dimensions with an additional + * dimension reserved for data information. + */ + template + static void write_svg (const std::vector > &patches, + const std::vector &data_names, + const std::vector > &vector_data_ranges, + const SvgFlags &flags, + std::ostream &out); + /** * Write the given list of patches to the output stream in deal.II * intermediate format. This is not a format understood by any other @@ -1939,6 +2042,7 @@ public: *
  • tecplot_binary: .plt *
  • vtk: .vtk *
  • vtu: .vtu + *
  • svg: .svg *
  • deal_II_intermediate: .d2. * */ @@ -2018,6 +2122,72 @@ private: const bool double_precision, STREAM &out); + + /** + * This function projects a three-dimensional point (Point<3> point) + * onto a two-dimensional image plane, specified by the position of + * the camera viewing system (Point<3> camera_position), camera + * direction (Point<3> camera_position), camera horizontal (Point<3> + * camera_horizontal, necessary for the correct alignment of the + * later images), and the focus of the camera (float camera_focus). + * + * For SVG output. + */ + static Point<2> svg_project_point(Point<3> point, + Point<3> camera_position, + Point<3> camera_direction, + Point<3> camera_horizontal, + float camera_focus); + /** + * Function to compute the gradient parameters for + * a triangle with given values for the vertices. + * + * Used for svg output. + */ + static Point<6> svg_get_gradient_parameters(Point<3> points[]); + + /** + * Class holding the data of one cell of a patch in two space + * dimensions for output. It is the projection of a cell in + * three-dimensional space (two coordinates, one height value) + * to the direction of sight. + */ + class SvgCell + { + public: + + // Center of the cell (three-dimensional) + Point<3> center; + + /** + * Vector of vertices of this cell (three-dimensional) + */ + Point<3> vertices[4]; + + /** + * Depth into the picture, which + * is defined as the distance from + * an observer at an the origin in + * direction of the line of sight. + */ + float depth; + + /** + * Vector of vertices of this cell (projected, two-dimensional). + */ + Point<2> projected_vertices[4]; + + // Center of the cell (projected, two-dimensional) + Point<2> projected_center; + + /** + * Comparison operator for + * sorting. + */ + bool operator < (const SvgCell &) const; + }; + + /** * Class holding the data of one * cell of a patch in two space @@ -2500,6 +2670,14 @@ public: void write_visit_record (std::ostream &out, const std::vector &piece_names) const; + /** + * Obtain data through get_patches() + * and write it to out + * in SVG format. See + * DataOutBase::write_svg. + */ + void write_svg(std::ostream &out) const; + /** * Obtain data through get_patches() * and write it to out @@ -2605,6 +2783,12 @@ public: */ void set_flags (const VtkFlags &vtk_flags); + /** + * Set the flags to be used for + * output in SVG format. + */ + void set_flags (const SvgFlags &svg_flags); + /** * Set the flags to be used for output in * deal.II intermediate format. @@ -2843,6 +3027,15 @@ private: */ VtkFlags vtk_flags; + /** + * Flags to be used upon output + * of svg data in one space + * dimension. Can be changed by + * using the set_flags + * function. + */ + SvgFlags svg_flags; + /** * Flags to be used upon output of * deal.II intermediate data in one space diff --git a/deal.II/include/deal.II/grid/grid_out.h b/deal.II/include/deal.II/grid/grid_out.h index 0382975532..0434cb74bc 100644 --- a/deal.II/include/deal.II/grid/grid_out.h +++ b/deal.II/include/deal.II/grid/grid_out.h @@ -674,13 +674,13 @@ namespace GridOutFlags /** * Constructor. */ - Svg(const unsigned int line_thickness = 3, - const unsigned int boundary_line_thickness = 7, + Svg(const unsigned int line_thickness = 2, + const unsigned int boundary_line_thickness = 4, bool margin = true, - const Background background = dealii, + const Background background = white, const int azimuth_angle = 0, const int polar_angle = 0, - const Coloring coloring = material_id, + const Coloring coloring = level_number, const bool convert_level_number_to_height = false, const bool label_level_number = true, const bool label_cell_index = true, @@ -1494,26 +1494,20 @@ private: /** - * This function projects a three-dimensional - * point (Point<3> point) onto a two-dimensional - * image plane, specified by the position of - * the camera viewing system - * (Point<3> camera_position), - * camera direction - * (Point<3> camera_position), - * camera horizontal - * (Point<3> camera_horizontal, necessary for - * the correct alignment of the later images), - * and the focus of the camera - * (float camera_focus). + * This function projects a three-dimensional point (Point<3> point) + * onto a two-dimensional image plane, specified by the position of + * the camera viewing system (Point<3> camera_position), camera + * direction (Point<3> camera_position), camera horizontal (Point<3> + * camera_horizontal, necessary for the correct alignment of the + * later images), and the focus of the camera (float camera_focus). * * For SVG output of grids. */ - Point<2> svg_project_point(Point<3> point, - Point<3> camera_position, - Point<3> camera_direction, - Point<3> camera_horizontal, - float camera_focus) const; + static Point<2> svg_project_point(Point<3> point, + Point<3> camera_position, + Point<3> camera_direction, + Point<3> camera_horizontal, + float camera_focus); /** * Return the number of faces in the triangulation which have a diff --git a/deal.II/source/base/data_out_base.cc b/deal.II/source/base/data_out_base.cc index 3791998d04..00cbfd983b 100644 --- a/deal.II/source/base/data_out_base.cc +++ b/deal.II/source/base/data_out_base.cc @@ -1838,6 +1838,15 @@ DataOutBase::GnuplotFlags::memory_consumption () const } +std::size_t +DataOutBase::SvgFlags::memory_consumption () const +{ + // only simple data elements, so + // use sizeof operator + return sizeof (*this); +} + + void DataOutBase::PovrayFlags::declare_parameters (ParameterHandler &prm) @@ -2204,6 +2213,20 @@ DataOutBase::VtkFlags::memory_consumption () const } +DataOutBase::SvgFlags::SvgFlags (const unsigned int height_vector, + const int azimuth_angle, + const int polar_angle, + const unsigned int line_thickness, + const bool margin, + const bool draw_colorbar) : +height_vector(height_vector), +azimuth_angle(azimuth_angle), +polar_angle(polar_angle), +line_thickness(line_thickness), +margin(margin), +draw_colorbar(draw_colorbar) +{} + DataOutBase::Deal_II_IntermediateFlags::Deal_II_IntermediateFlags () : @@ -2296,7 +2319,7 @@ parse_output_format (const std::string &format_name) std::string DataOutBase::get_output_format_names () { - return "none|dx|ucd|gnuplot|povray|eps|gmv|tecplot|tecplot_binary|vtk|vtu|hdf5|deal.II intermediate"; + return "none|dx|ucd|gnuplot|povray|eps|gmv|tecplot|tecplot_binary|vtk|vtu|hdf5|svg|deal.II intermediate"; } @@ -2333,6 +2356,8 @@ default_suffix (const OutputFormat output_format) return ".d2"; case hdf5: return ".h5"; + case svg: + return ".svg"; default: Assert (false, ExcNotImplemented()); return ""; @@ -2476,6 +2501,261 @@ DataOutBase::write_data ( } +Point<2> DataOutBase::svg_project_point(Point<3> point, Point<3> camera_position, Point<3> camera_direction, Point<3> camera_horizontal, float camera_focus) +{ + Point<3> camera_vertical; + camera_vertical[0] = camera_horizontal[1] * camera_direction[2] - camera_horizontal[2] * camera_direction[1]; + camera_vertical[1] = camera_horizontal[2] * camera_direction[0] - camera_horizontal[0] * camera_direction[2]; + camera_vertical[2] = camera_horizontal[0] * camera_direction[1] - camera_horizontal[1] * camera_direction[0]; + + float phi; + phi = camera_focus; + phi /= (point[0] - camera_position[0]) * camera_direction[0] + (point[1] - camera_position[1]) * camera_direction[1] + (point[2] - camera_position[2]) * camera_direction[2]; + + Point<3> projection; + projection[0] = camera_position[0] + phi * (point[0] - camera_position[0]); + projection[1] = camera_position[1] + phi * (point[1] - camera_position[1]); + projection[2] = camera_position[2] + phi * (point[2] - camera_position[2]); + + Point<2> projection_decomposition; + projection_decomposition[0] = (projection[0] - camera_position[0] - camera_focus * camera_direction[0]) * camera_horizontal[0]; + projection_decomposition[0] += (projection[1] - camera_position[1] - camera_focus * camera_direction[1]) * camera_horizontal[1]; + projection_decomposition[0] += (projection[2] - camera_position[2] - camera_focus * camera_direction[2]) * camera_horizontal[2]; + + projection_decomposition[1] = (projection[0] - camera_position[0] - camera_focus * camera_direction[0]) * camera_vertical[0]; + projection_decomposition[1] += (projection[1] - camera_position[1] - camera_focus * camera_direction[1]) * camera_vertical[1]; + projection_decomposition[1] += (projection[2] - camera_position[2] - camera_focus * camera_direction[2]) * camera_vertical[2]; + + return projection_decomposition; +} + +Point<6> DataOutBase::svg_get_gradient_parameters(Point<3> points[]) +{ + Point<3> v_min, v_max, v_inter; + + // Use the Bubblesort algorithm to sort the points with respect to the third coordinate + int i, j; + + for (i = 0; i < 2; ++i) + { + for (j = 0; j < 2-i; ++j) + { + if (points[j][2] > points[j + 1][2]) + { + Point<3> temp = points[j]; + points[j] = points[j+1]; + points[j+1] = temp; + } + } + } + + // save the related three-dimensional vectors v_min, v_inter, and v_max + v_min = points[0]; + v_inter = points[1]; + v_max = points[2]; + + Point<2> A[2]; + Point<2> b, gradient; + + // determine the plane offset c + A[0][0] = v_max[0] - v_min[0]; + A[0][1] = v_inter[0] - v_min[0]; + A[1][0] = v_max[1] - v_min[1]; + A[1][1] = v_inter[1] - v_min[1]; + + b[0] = - v_min[0]; + b[1] = - v_min[1]; + + double x, sum; + bool col_change = false; + + if (A[0][0] == 0) + { + col_change = true; + + A[0][0] = A[0][1]; + A[0][1] = 0; + + double temp = A[1][0]; + A[1][0] = A[1][1]; + A[1][1] = temp; + } + + for (unsigned int k = 0; k < 1; k++) + { + for (unsigned int i = k+1; i < 2; i++) + { + x = A[i][k] / A[k][k]; + + for (unsigned int j = k+1; j < 2; j++) A[i][j] = A[i][j] - A[k][j] * x; + + b[i] = b[i] - b[k]*x; + + } + } + + b[1] = b[1] / A[1][1]; + + for (int i = 0; i >= 0; i--) + { + sum = b[i]; + + for (unsigned int j = i+1; j < 2; j++) sum = sum - A[i][j] * b[j]; + + b[i] = sum / A[i][i]; + } + + if (col_change) + { + double temp = b[0]; + b[0] = b[1]; + b[1] = temp; + } + + double c = b[0] * (v_max[2] - v_min[2]) + b[1] * (v_inter[2] - v_min[2]) + v_min[2]; + + // Determine the first entry of the gradient (phi, cf. documentation) + A[0][0] = v_max[0] - v_min[0]; + A[0][1] = v_inter[0] - v_min[0]; + A[1][0] = v_max[1] - v_min[1]; + A[1][1] = v_inter[1] - v_min[1]; + + b[0] = 1.0 - v_min[0]; + b[1] = - v_min[1]; + + col_change = false; + + if (A[0][0] == 0) + { + col_change = true; + + A[0][0] = A[0][1]; + A[0][1] = 0; + + double temp = A[1][0]; + A[1][0] = A[1][1]; + A[1][1] = temp; + } + + for (unsigned int k = 0; k < 1; k++) + { + for (unsigned int i = k+1; i < 2; i++) + { + x = A[i][k] / A[k][k]; + + for (unsigned int j = k+1; j < 2; j++) A[i][j] = A[i][j] - A[k][j] * x; + + b[i] = b[i] - b[k] * x; + + } + } + + b[1]=b[1] / A[1][1]; + + for (int i = 0; i >= 0; i--) + { + sum = b[i]; + + for (unsigned int j = i+1; j < 2; j++) sum = sum - A[i][j]*b[j]; + + b[i] = sum / A[i][i]; + } + + if (col_change) + { + double temp = b[0]; + b[0] = b[1]; + b[1] = temp; + } + + gradient[0] = b[0] * (v_max[2] - v_min[2]) + b[1] * (v_inter[2] - v_min[2]) - c + v_min[2]; + + // determine the second entry of the gradient + A[0][0] = v_max[0] - v_min[0]; + A[0][1] = v_inter[0] - v_min[0]; + A[1][0] = v_max[1] - v_min[1]; + A[1][1] = v_inter[1] - v_min[1]; + + b[0] = - v_min[0]; + b[1] = 1.0 - v_min[1]; + + col_change = false; + + if (A[0][0] == 0) + { + col_change = true; + + A[0][0] = A[0][1]; + A[0][1] = 0; + + double temp = A[1][0]; + A[1][0] = A[1][1]; + A[1][1] = temp; + } + + for (unsigned int k = 0; k < 1; k++) + { + for (unsigned int i = k+1; i < 2; i++) + { + x = A[i][k] / A[k][k]; + + for (unsigned int j = k+1; j < 2; j++) A[i][j] = A[i][j] - A[k][j] * x; + + b[i] = b[i] - b[k] * x; + } + } + + b[1] = b[1] / A[1][1]; + + for (int i = 0; i >= 0; i--) + { + sum = b[i]; + + for (unsigned int j = i+1; j < 2; j++) sum = sum - A[i][j] * b[j]; + + b[i] = sum / A[i][i]; + } + + if (col_change) + { + double temp = b[0]; + b[0] = b[1]; + b[1] = temp; + } + + gradient[1] = b[0] * (v_max[2] - v_min[2]) + b[1] * (v_inter[2] - v_min[2]) - c + v_min[2]; + + // normalize the gradient + double gradient_norm = sqrt(pow(gradient[0], 2.0) + pow(gradient[1], 2.0)); + gradient[0] /= gradient_norm; + gradient[1] /= gradient_norm; + + double lambda = - gradient[0] * (v_min[0] - v_max[0]) - gradient[1] * (v_min[1] - v_max[1]); + + Point<6> gradient_parameters(true); + + gradient_parameters[0] = v_min[0]; + gradient_parameters[1] = v_min[1]; + + gradient_parameters[2] = v_min[0] + lambda * gradient[0]; + gradient_parameters[3] = v_min[1] + lambda * gradient[1]; + + gradient_parameters[4] = v_min[2]; + gradient_parameters[5] = v_max[2]; + + return gradient_parameters; +} + + +bool DataOutBase::SvgCell::operator < (const SvgCell &e) const +{ + // note the "wrong" order in + // which we sort the elements + return depth > e.depth; +} + + + template void DataOutBase::write_ucd (const std::vector > &patches, const std::vector &data_names, @@ -5303,6 +5583,579 @@ void DataOutBase::write_vtu_main (const std::vector > &patch } +template +void DataOutBase::write_svg (const std::vector> &patches, + const std::vector &data_names, + const std::vector> &vector_data_ranges, + const SvgFlags &flags, + std::ostream &out) +{ + // do not allow volume rendering + AssertThrow (dim==2, ExcNotImplemented()); + + const unsigned int height = 4000; + unsigned int width; + + // margin around the plotted area + unsigned int margin_in_percent = 0; + if(flags.margin) margin_in_percent = 5; + + +// determine the bounding box in the model space + double x_min, y_min, z_min; + double x_max, y_max, z_max; + double x_dimension, y_dimension, z_dimension; + + typename std::vector>::const_iterator patch = patches.begin(); + + unsigned int n_subdivisions = patch->n_subdivisions; + unsigned int n = n_subdivisions + 1; + const unsigned int d1 = 1; + const unsigned int d2 = n; + + Point projected_point; + Point projected_points[4]; + + Point<2> projection_decomposition; + Point<2> projection_decompositions[4]; + + compute_node(projected_point, &*patch, 0, 0, 0, n_subdivisions); + + Assert ((flags.height_vector < patch->data.n_rows()) || + patch->data.n_rows() == 0, + ExcIndexRange (flags.height_vector, 0, patch->data.n_rows())); + + x_min = projected_point[0]; + x_max = x_min; + y_min = projected_point[1]; + y_max = y_min; + z_min = patch->data.n_rows() != 0 ? patch->data(flags.height_vector,0) : 0; + z_max = z_min; + + // iterate over the patches + for (; patch != patches.end(); ++patch) + { + n_subdivisions = patch->n_subdivisions; + n = n_subdivisions + 1; + + for (unsigned int i2 = 0; i2 < n_subdivisions; ++i2) + { + for (unsigned int i1 = 0; i1 < n_subdivisions; ++i1) + { + compute_node(projected_points[0], &*patch, i1, i2, 0, n_subdivisions); + compute_node(projected_points[1], &*patch, i1+1, i2, 0, n_subdivisions); + compute_node(projected_points[2], &*patch, i1, i2+1, 0, n_subdivisions); + compute_node(projected_points[3], &*patch, i1+1, i2+1, 0, n_subdivisions); + + x_min = std::min(x_min, (double)projected_points[0][0]); + x_min = std::min(x_min, (double)projected_points[1][0]); + x_min = std::min(x_min, (double)projected_points[2][0]); + x_min = std::min(x_min, (double)projected_points[3][0]); + + x_max = std::max(x_max, (double)projected_points[0][0]); + x_max = std::max(x_max, (double)projected_points[1][0]); + x_max = std::max(x_max, (double)projected_points[2][0]); + x_max = std::max(x_max, (double)projected_points[3][0]); + + y_min = std::min(y_min, (double)projected_points[0][1]); + y_min = std::min(y_min, (double)projected_points[1][1]); + y_min = std::min(y_min, (double)projected_points[2][1]); + y_min = std::min(y_min, (double)projected_points[3][1]); + + y_max = std::max(y_max, (double)projected_points[0][1]); + y_max = std::max(y_max, (double)projected_points[1][1]); + y_max = std::max(y_max, (double)projected_points[2][1]); + y_max = std::max(y_max, (double)projected_points[3][1]); + + Assert ((flags.height_vector < patch->data.n_rows()) || + patch->data.n_rows() == 0, + ExcIndexRange (flags.height_vector, 0, patch->data.n_rows())); + + z_min = std::min(z_min, (double)patch->data(flags.height_vector, i1*d1 + i2*d2)); + z_min = std::min(z_min, (double)patch->data(flags.height_vector, (i1+1)*d1 + i2*d2)); + z_min = std::min(z_min, (double)patch->data(flags.height_vector, i1*d1 + (i2+1)*d2)); + z_min = std::min(z_min, (double)patch->data(flags.height_vector, (i1+1)*d1 + (i2+1)*d2)); + + z_max = std::max(z_max, (double)patch->data(flags.height_vector, i1*d1 + i2*d2)); + z_max = std::max(z_max, (double)patch->data(flags.height_vector, (i1+1)*d1 + i2*d2)); + z_max = std::max(z_max, (double)patch->data(flags.height_vector, i1*d1 + (i2+1)*d2)); + z_max = std::max(z_max, (double)patch->data(flags.height_vector, (i1+1)*d1 + (i2+1)*d2)); + } + } + } + + x_dimension = x_max - x_min; + y_dimension = y_max - y_min; + z_dimension = z_max - z_min; + + +// set initial camera position + Point<3> camera_position(true); + Point<3> camera_direction(true); + Point<3> camera_horizontal(true); + float camera_focus = 0; + + // translate camera from the origin to the initial position + camera_position[0] = 0.; + camera_position[1] = 0.; + camera_position[2] = z_min + 2. * z_dimension; + + camera_direction[0] = 0.; + camera_direction[1] = 0.; + camera_direction[2] = - 1.; + + camera_horizontal[0] = 1.; + camera_horizontal[1] = 0.; + camera_horizontal[2] = 0.; + + camera_focus = .5 * z_dimension; + + Point<3> camera_position_temp(true); + Point<3> camera_direction_temp(true); + Point<3> camera_horizontal_temp(true); + + const float angle_factor = 3.14159265 / 180.; + + // (I) rotate the camera to the chosen polar angle + camera_position_temp[1] = cos(angle_factor * flags.polar_angle) * camera_position[1] - sin(angle_factor * flags.polar_angle) * camera_position[2]; + camera_position_temp[2] = sin(angle_factor * flags.polar_angle) * camera_position[1] + cos(angle_factor * flags.polar_angle) * camera_position[2]; + + camera_direction_temp[1] = cos(angle_factor * flags.polar_angle) * camera_direction[1] - sin(angle_factor * flags.polar_angle) * camera_direction[2]; + camera_direction_temp[2] = sin(angle_factor * flags.polar_angle) * camera_direction[1] + cos(angle_factor * flags.polar_angle) * camera_direction[2]; + + camera_horizontal_temp[1] = cos(angle_factor * flags.polar_angle) * camera_horizontal[1] - sin(angle_factor * flags.polar_angle) * camera_horizontal[2]; + camera_horizontal_temp[2] = sin(angle_factor * flags.polar_angle) * camera_horizontal[1] + cos(angle_factor * flags.polar_angle) * camera_horizontal[2]; + + camera_position[1] = camera_position_temp[1]; + camera_position[2] = camera_position_temp[2]; + + camera_direction[1] = camera_direction_temp[1]; + camera_direction[2] = camera_direction_temp[2]; + + camera_horizontal[1] = camera_horizontal_temp[1]; + camera_horizontal[2] = camera_horizontal_temp[2]; + + // (II) rotate the camera to the chosen azimuth angle + camera_position_temp[0] = cos(angle_factor * flags.azimuth_angle) * camera_position[0] - sin(angle_factor * flags.azimuth_angle) * camera_position[1]; + camera_position_temp[1] = sin(angle_factor * flags.azimuth_angle) * camera_position[0] + cos(angle_factor * flags.azimuth_angle) * camera_position[1]; + + camera_direction_temp[0] = cos(angle_factor * flags.azimuth_angle) * camera_direction[0] - sin(angle_factor * flags.azimuth_angle) * camera_direction[1]; + camera_direction_temp[1] = sin(angle_factor * flags.azimuth_angle) * camera_direction[0] + cos(angle_factor * flags.azimuth_angle) * camera_direction[1]; + + camera_horizontal_temp[0] = cos(angle_factor * flags.azimuth_angle) * camera_horizontal[0] - sin(angle_factor * flags.azimuth_angle) * camera_horizontal[1]; + camera_horizontal_temp[1] = sin(angle_factor * flags.azimuth_angle) * camera_horizontal[0] + cos(angle_factor * flags.azimuth_angle) * camera_horizontal[1]; + + camera_position[0] = camera_position_temp[0]; + camera_position[1] = camera_position_temp[1]; + + camera_direction[0] = camera_direction_temp[0]; + camera_direction[1] = camera_direction_temp[1]; + + camera_horizontal[0] = camera_horizontal_temp[0]; + camera_horizontal[1] = camera_horizontal_temp[1]; + + // (III) translate the camera + camera_position[0] = x_min + .5 * x_dimension; + camera_position[1] = y_min + .5 * y_dimension; + + camera_position[0] += (z_min + 2. * z_dimension) * sin(angle_factor * flags.polar_angle) * sin(angle_factor * flags.azimuth_angle); + camera_position[1] -= (z_min + 2. * z_dimension) * sin(angle_factor * flags.polar_angle) * cos(angle_factor * flags.azimuth_angle); + + +// determine the bounding box on the projection plane + double x_min_perspective, y_min_perspective; + double x_max_perspective, y_max_perspective; + double x_dimension_perspective, y_dimension_perspective; + + patch = patches.begin(); + + n_subdivisions = patch->n_subdivisions; + n = n_subdivisions + 1; + + Point<3> point(true); + + compute_node(projected_point, &*patch, 0, 0, 0, n_subdivisions); + + Assert ((flags.height_vector < patch->data.n_rows()) || + patch->data.n_rows() == 0, + ExcIndexRange (flags.height_vector, 0, patch->data.n_rows())); + + point[0] = projected_point[0]; + point[1] = projected_point[1]; + point[2] = patch->data.n_rows() != 0 ? patch->data(flags.height_vector, 0) : 0; + + projection_decomposition = svg_project_point(point, camera_position, camera_direction, camera_horizontal, camera_focus); + + x_min_perspective = projection_decomposition[0]; + x_max_perspective = projection_decomposition[0]; + y_min_perspective = projection_decomposition[1]; + y_max_perspective = projection_decomposition[1]; + + // iterate over the patches + for (; patch != patches.end(); ++patch) + { + n_subdivisions = patch->n_subdivisions; + n = n_subdivisions + 1; + + for (unsigned int i2 = 0; i2 < n_subdivisions; ++i2) + { + for (unsigned int i1 = 0; i1 < n_subdivisions; ++i1) + { + Point projected_vertices[4]; + Point<3> vertices[4]; + + compute_node(projected_vertices[0], &*patch, i1, i2, 0, n_subdivisions); + compute_node(projected_vertices[1], &*patch, i1+1, i2, 0, n_subdivisions); + compute_node(projected_vertices[2], &*patch, i1, i2+1, 0, n_subdivisions); + compute_node(projected_vertices[3], &*patch, i1+1, i2+1, 0, n_subdivisions); + + Assert ((flags.height_vector < patch->data.n_rows()) || + patch->data.n_rows() == 0, + ExcIndexRange (flags.height_vector, 0, patch->data.n_rows())); + + vertices[0][0] = projected_vertices[0][0]; + vertices[0][1] = projected_vertices[0][1]; + vertices[0][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + i2*d2) : 0; + + vertices[1][0] = projected_vertices[1][0]; + vertices[1][1] = projected_vertices[1][1]; + vertices[1][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + i2*d2) : 0; + + vertices[2][0] = projected_vertices[2][0]; + vertices[2][1] = projected_vertices[2][1]; + vertices[2][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + (i2+1)*d2) : 0; + + vertices[3][0] = projected_vertices[3][0]; + vertices[3][1] = projected_vertices[3][1]; + vertices[3][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + (i2+1)*d2) : 0; + + projection_decompositions[0] = svg_project_point(vertices[0], camera_position, camera_direction, camera_horizontal, camera_focus); + projection_decompositions[1] = svg_project_point(vertices[1], camera_position, camera_direction, camera_horizontal, camera_focus); + projection_decompositions[2] = svg_project_point(vertices[2], camera_position, camera_direction, camera_horizontal, camera_focus); + projection_decompositions[3] = svg_project_point(vertices[3], camera_position, camera_direction, camera_horizontal, camera_focus); + + x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[0][0]); + x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[1][0]); + x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[2][0]); + x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[3][0]); + + x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[0][0]); + x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[1][0]); + x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[2][0]); + x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[3][0]); + + y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[0][1]); + y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[1][1]); + y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[2][1]); + y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[3][1]); + + y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[0][1]); + y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[1][1]); + y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[2][1]); + y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[3][1]); + } + } + } + + x_dimension_perspective = x_max_perspective - x_min_perspective; + y_dimension_perspective = y_max_perspective - y_min_perspective; + + std::multiset cells; + + // iterate over the patches + for (patch = patches.begin(); patch != patches.end(); ++patch) + { + n_subdivisions = patch->n_subdivisions; + n = n_subdivisions + 1; + + for (unsigned int i2 = 0; i2 < n_subdivisions; ++i2) + { + for (unsigned int i1 = 0; i1 < n_subdivisions; ++i1) + { + Point projected_vertices[4]; + SvgCell cell; + + compute_node(projected_vertices[0], &*patch, i1, i2, 0, n_subdivisions); + compute_node(projected_vertices[1], &*patch, i1+1, i2, 0, n_subdivisions); + compute_node(projected_vertices[2], &*patch, i1, i2+1, 0, n_subdivisions); + compute_node(projected_vertices[3], &*patch, i1+1, i2+1, 0, n_subdivisions); + + Assert ((flags.height_vector < patch->data.n_rows()) || + patch->data.n_rows() == 0, + ExcIndexRange (flags.height_vector, 0, patch->data.n_rows())); + + cell.vertices[0][0] = projected_vertices[0][0]; + cell.vertices[0][1] = projected_vertices[0][1]; + cell.vertices[0][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + i2*d2) : 0; + + cell.vertices[1][0] = projected_vertices[1][0]; + cell.vertices[1][1] = projected_vertices[1][1]; + cell.vertices[1][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + i2*d2) : 0; + + cell.vertices[2][0] = projected_vertices[2][0]; + cell.vertices[2][1] = projected_vertices[2][1]; + cell.vertices[2][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + (i2+1)*d2) : 0; + + cell.vertices[3][0] = projected_vertices[3][0]; + cell.vertices[3][1] = projected_vertices[3][1]; + cell.vertices[3][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + (i2+1)*d2) : 0; + + cell.projected_vertices[0] = svg_project_point(cell.vertices[0], camera_position, camera_direction, camera_horizontal, camera_focus); + cell.projected_vertices[1] = svg_project_point(cell.vertices[1], camera_position, camera_direction, camera_horizontal, camera_focus); + cell.projected_vertices[2] = svg_project_point(cell.vertices[2], camera_position, camera_direction, camera_horizontal, camera_focus); + cell.projected_vertices[3] = svg_project_point(cell.vertices[3], camera_position, camera_direction, camera_horizontal, camera_focus); + + cell.center = .25 * (cell.vertices[0] + cell.vertices[1] + cell.vertices[2] + cell.vertices[3]); + cell.projected_center = svg_project_point(cell.center, camera_position, camera_direction, camera_horizontal, camera_focus); + + cell.depth = cell.center.distance(camera_position); + + cells.insert(cell); + } + } + } + + +// write the svg file + width = static_cast(.5 + height * (x_dimension_perspective / y_dimension_perspective)); + unsigned int additional_width = 0; + + if(flags.draw_colorbar) additional_width = static_cast(.5 + height * .3); // additional width for colorbar + + // basic svg header and background rectangle + out << "" << '\n' + << " " << '\n' << '\n'; + + unsigned int triangle_counter = 0; + + // write the cells in the correct order + for (typename std::multiset::const_iterator cell = cells.begin(); cell != cells.end(); ++cell) + { + Point<3> points3d_triangle[3]; + + for (unsigned int triangle_index = 0; triangle_index < 4; triangle_index++) + { + switch (triangle_index) + { + case 0: points3d_triangle[0] = cell->vertices[0], points3d_triangle[1] = cell->vertices[1], points3d_triangle[2] = cell->center; break; + case 1: points3d_triangle[0] = cell->vertices[1], points3d_triangle[1] = cell->vertices[3], points3d_triangle[2] = cell->center; break; + case 2: points3d_triangle[0] = cell->vertices[3], points3d_triangle[1] = cell->vertices[2], points3d_triangle[2] = cell->center; break; + case 3: points3d_triangle[0] = cell->vertices[2], points3d_triangle[1] = cell->vertices[0], points3d_triangle[2] = cell->center; break; + default: break; + } + + Point<6> gradient_param = svg_get_gradient_parameters(points3d_triangle); + + double start_h = .667 - ((gradient_param[4] - z_min) / z_dimension) * .667; + double stop_h = .667 - ((gradient_param[5] - z_min) / z_dimension) * .667; + + unsigned int start_r = 0; + unsigned int start_g = 0; + unsigned int start_b = 0; + + unsigned int stop_r = 0; + unsigned int stop_g = 0; + unsigned int stop_b = 0; + + unsigned int start_i = static_cast(start_h * 6.); + unsigned int stop_i = static_cast(stop_h * 6.); + + double start_f = start_h * 6. - start_i; + double start_q = 1. - start_f; + + double stop_f = stop_h * 6. - stop_i; + double stop_q = 1. - stop_f; + + switch (start_i % 6) + { + case 0: start_r = 255, start_g = static_cast(.5 + 255. * start_f); break; + case 1: start_r = static_cast(.5 + 255. * start_q), start_g = 255; break; + case 2: start_g = 255, start_b = static_cast(.5 + 255. * start_f); break; + case 3: start_g = static_cast(.5 + 255. * start_q), start_b = 255; break; + case 4: start_r = static_cast(.5 + 255. * start_f), start_b = 255; break; + case 5: start_r = 255, start_b = static_cast(.5 + 255. * start_q); break; + default: break; + } + + switch (stop_i % 6) + { + case 0: stop_r = 255, stop_g = static_cast(.5 + 255. * stop_f); break; + case 1: stop_r = static_cast(.5 + 255. * stop_q), stop_g = 255; break; + case 2: stop_g = 255, stop_b = static_cast(.5 + 255. * stop_f); break; + case 3: stop_g = static_cast(.5 + 255. * stop_q), stop_b = 255; break; + case 4: stop_r = static_cast(.5 + 255. * stop_f), stop_b = 255; break; + case 5: stop_r = 255, stop_b = static_cast(.5 + 255. * stop_q); break; + default: break; + } + + Point<3> gradient_start_point_3d, gradient_stop_point_3d; + + gradient_start_point_3d[0] = gradient_param[0]; + gradient_start_point_3d[1] = gradient_param[1]; + gradient_start_point_3d[2] = gradient_param[4]; + + gradient_stop_point_3d[0] = gradient_param[2]; + gradient_stop_point_3d[1] = gradient_param[3]; + gradient_stop_point_3d[2] = gradient_param[5]; + + Point<2> gradient_start_point = svg_project_point(gradient_start_point_3d, camera_position, camera_direction, camera_horizontal, camera_focus); + Point<2> gradient_stop_point = svg_project_point(gradient_stop_point_3d, camera_position, camera_direction, camera_horizontal, camera_focus); + + // define linear gradient + out << " (.5 + ((gradient_start_point[0] - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent)) + << "\" " + << "y1=\"" + << static_cast(.5 + height - (height/100.) * margin_in_percent - ((gradient_start_point[1] - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent)) + << "\" " + << "x2=\"" + << static_cast(.5 + ((gradient_stop_point[0] - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent)) + << "\" " + << "y2=\"" + << static_cast(.5 + height - (height/100.) * margin_in_percent - ((gradient_stop_point[1] - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent)) + << "\"" + << ">" << '\n' + << " " << '\n' + << " " << '\n' + << " " << '\n'; + + // draw current triangle + double x1,y1,x2,y2; + double x3 = cell->projected_center[0]; + double y3 = cell->projected_center[1]; + + switch (triangle_index) + { + case 0: x1 = cell->projected_vertices[0][0], y1 = cell->projected_vertices[0][1], x2 = cell->projected_vertices[1][0], y2 = cell->projected_vertices[1][1]; break; + case 1: x1 = cell->projected_vertices[1][0], y1 = cell->projected_vertices[1][1], x2 = cell->projected_vertices[3][0], y2 = cell->projected_vertices[3][1]; break; + case 2: x1 = cell->projected_vertices[3][0], y1 = cell->projected_vertices[3][1], x2 = cell->projected_vertices[2][0], y2 = cell->projected_vertices[2][1]; break; + case 3: x1 = cell->projected_vertices[2][0], y1 = cell->projected_vertices[2][1], x2 = cell->projected_vertices[0][0], y2 = cell->projected_vertices[0][1]; break; + default: break; + } + + out << " (.5 + ((x1 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent)) + << ' ' + << static_cast(.5 + height - (height/100.) * margin_in_percent - ((y1 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent)) + << " L " + << static_cast(.5 + ((x2 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent)) + << ' ' + << static_cast(.5 + height - (height/100.) * margin_in_percent - ((y2 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent)) + << " L " + << static_cast(.5 + ((x3 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent)) + << ' ' + << static_cast(.5 + height - (height/100.) * margin_in_percent - ((y3 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent)) + << " L " + << static_cast(.5 + ((x1 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent)) + << ' ' + << static_cast(.5 + height - (height/100.) * margin_in_percent - ((y1 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent)) + << "\" style=\"stroke:black; fill:url(#" << triangle_counter << "); stroke-width:" << flags.line_thickness << "\"/>" << '\n'; + + triangle_counter++; + } + } + + +// draw the colorbar + if (flags.draw_colorbar) + { + out << '\n' << " " << '\n'; + + unsigned int element_height = static_cast(((height/100.) * (71. - 2.*margin_in_percent)) / 4); + unsigned int element_width = static_cast(.5 + (height/100.) * 2.5); + + additional_width = 0; + if (!flags.margin) additional_width = static_cast(.5 + (height/100.) * 2.5); + + for (unsigned int index = 0; index < 4; index++) + { + double start_h = .667 - ((index+1) / 4.) * .667; + double stop_h = .667 - (index / 4.) * .667; + + unsigned int start_r = 0; + unsigned int start_g = 0; + unsigned int start_b = 0; + + unsigned int stop_r = 0; + unsigned int stop_g = 0; + unsigned int stop_b = 0; + + unsigned int start_i = static_cast(start_h * 6.); + unsigned int stop_i = static_cast(stop_h * 6.); + + double start_f = start_h * 6. - start_i; + double start_q = 1. - start_f; + + double stop_f = stop_h * 6. - stop_i; + double stop_q = 1. - stop_f; + + switch (start_i % 6) + { + case 0: start_r = 255, start_g = static_cast(.5 + 255. * start_f); break; + case 1: start_r = static_cast(.5 + 255. * start_q), start_g = 255; break; + case 2: start_g = 255, start_b = static_cast(.5 + 255. * start_f); break; + case 3: start_g = static_cast(.5 + 255. * start_q), start_b = 255; break; + case 4: start_r = static_cast(.5 + 255. * start_f), start_b = 255; break; + case 5: start_r = 255, start_b = static_cast(.5 + 255. * start_q); break; + default: break; + } + + switch (stop_i % 6) + { + case 0: stop_r = 255, stop_g = static_cast(.5 + 255. * stop_f); break; + case 1: stop_r = static_cast(.5 + 255. * stop_q), stop_g = 255; break; + case 2: stop_g = 255, stop_b = static_cast(.5 + 255. * stop_f); break; + case 3: stop_g = static_cast(.5 + 255. * stop_q), stop_b = 255; break; + case 4: stop_r = static_cast(.5 + 255. * stop_f), stop_b = 255; break; + case 5: stop_r = 255, stop_b = static_cast(.5 + 255. * stop_q); break; + default: break; + } + + // define gradient + out << " (.5 + (height/100.) * (margin_in_percent + 29)) + (3-index) * element_height << "\" " + << "x2=\"" << width + additional_width << "\" " + << "y2=\"" << static_cast(.5 + (height/100.) * (margin_in_percent + 29)) + (4-index) * element_height << "\"" + << ">" << '\n' + << " " << '\n' + << " " << '\n' + << " " << '\n'; + + // draw box corresponding to the gradient above + out << " (.5 + (height/100.) * (margin_in_percent + 29)) + (3-index) * element_height + << "\" width=\"" << element_width + << "\" height=\"" << element_height + << "\" style=\"stroke:black; stroke-width:2; fill:url(#colorbar_" << index << ")\"/>" << '\n'; + } + + for (unsigned int index = 0; index < 5; index++) + { + out << " (1.5 * element_width) + << "\" y=\"" << static_cast(.5 + (height/100.) * (margin_in_percent + 29) + (4.-index) * element_height + 30.) << "\"" + << " style=\"text-anchor:start; font-size:80; font-family:Helvetica"; + + if (index == 0 || index == 4) out << "; font-weight:bold"; + + out << "\">" << (float)(((int)((z_min + index * (z_dimension / 4.))*10000))/10000.); + + if (index == 4) out << " max"; + if (index == 0) out << " min"; + + out << "" << '\n'; + } + } + + // finalize the svg file + out << '\n' << ""; + out.flush(); + +} + + template void @@ -5527,6 +6380,14 @@ void DataOutInterface::write_vtu (std::ostream &out) const vtk_flags, out); } +template +void DataOutInterface::write_svg (std::ostream &out) const +{ + DataOutBase::write_svg (get_patches(), get_dataset_names(), + get_vector_data_ranges(), + svg_flags, out); +} + template void DataOutInterface::write_vtu_in_parallel (const char *filename, MPI_Comm comm) const { @@ -6333,7 +7194,7 @@ DataOutInterface::write (std::ostream &out, break; case eps: - write_eps(out); + write_eps (out); break; case gmv: @@ -6356,6 +7217,10 @@ DataOutInterface::write (std::ostream &out, write_vtu (out); break; + case svg: + write_svg (out); + break; + case deal_II_intermediate: write_deal_II_intermediate (out); break; @@ -6449,6 +7314,15 @@ DataOutInterface::set_flags (const VtkFlags &flags) +template +void +DataOutInterface::set_flags (const SvgFlags &flags) +{ + svg_flags = flags; +} + + + template void DataOutInterface::set_flags (const Deal_II_IntermediateFlags &flags) @@ -6581,6 +7455,7 @@ DataOutInterface::memory_consumption () const MemoryConsumption::memory_consumption (gmv_flags) + MemoryConsumption::memory_consumption (tecplot_flags) + MemoryConsumption::memory_consumption (vtk_flags) + + MemoryConsumption::memory_consumption (svg_flags) + MemoryConsumption::memory_consumption (deal_II_intermediate_flags)); } diff --git a/deal.II/source/grid/grid_out.cc b/deal.II/source/grid/grid_out.cc index d8f1fca9ab..947e519082 100644 --- a/deal.II/source/grid/grid_out.cc +++ b/deal.II/source/grid/grid_out.cc @@ -1384,7 +1384,7 @@ void GridOut::write_svg(const Triangulation<2,2> &tria, std::ostream &out) const unsigned int cell_label_font_size; // font size for date, time, legend, and colorbar - unsigned int font_size = static_cast(.5 + (height/100.) * 2.); + unsigned int font_size = static_cast(.5 + (height/100.) * 1.75); // get date and time // time_t time_stamp; @@ -1519,7 +1519,6 @@ void GridOut::write_svg(const Triangulation<2,2> &tria, std::ostream &out) const break; } - // set the camera position to top view, targeting at the origin camera_position[0] = 0; camera_position[1] = 0; @@ -1535,9 +1534,9 @@ void GridOut::write_svg(const Triangulation<2,2> &tria, std::ostream &out) const camera_focus = .5 * std::max(x_dimension, y_dimension); - float *camera_position_temp = new float[3]; - float *camera_direction_temp = new float[3]; - float *camera_horizontal_temp = new float[3]; + Point<3> camera_position_temp; + Point<3> camera_direction_temp; + Point<3> camera_horizontal_temp; const float angle_factor = 3.14159265 / 180.; @@ -1579,10 +1578,6 @@ void GridOut::write_svg(const Triangulation<2,2> &tria, std::ostream &out) const camera_horizontal[0] = camera_horizontal_temp[0]; camera_horizontal[1] = camera_horizontal_temp[1]; - delete camera_position_temp; - delete camera_direction_temp; - delete camera_horizontal_temp; - // translate the camera to the given triangulation camera_position[0] = x_min + .5 * x_dimension; camera_position[1] = y_min + .5 * y_dimension; @@ -1672,7 +1667,7 @@ void GridOut::write_svg(const Triangulation<2,2> &tria, std::ostream &out) const x_dimension_perspective = x_max_perspective - x_min_perspective; y_dimension_perspective = y_max_perspective - y_min_perspective; - cell_label_font_size = static_cast(.5 + (height/100.) * 2.25) * 9. * (min_level_min_vertex_distance / std::min(x_dimension, y_dimension)); + cell_label_font_size = static_cast(.5 + (height/100.) * 2.75) * 9. * (min_level_min_vertex_distance / std::min(x_dimension, y_dimension)); // create the svg file with an internal style sheet @@ -2766,7 +2761,7 @@ void GridOut::write_ucd_lines (const Triangulation &tria, } -Point<2> GridOut::svg_project_point(Point<3> point, Point<3> camera_position, Point<3> camera_direction, Point<3> camera_horizontal, float camera_focus) const +Point<2> GridOut::svg_project_point(Point<3> point, Point<3> camera_position, Point<3> camera_direction, Point<3> camera_horizontal, float camera_focus) { // ... Point<3> camera_vertical; -- 2.39.5