The Conley-Morse Graphs Software
plotmdec.h
Go to the documentation of this file.
1/////////////////////////////////////////////////////////////////////////////
2///
3/// @file plotmdec.h
4///
5/// Plotting a Morse decomposition in a PNG picture.
6/// This file contains the definition of a procedure which can be used
7/// to save a Morse decomposition to a PNG bitmap picture file.
8///
9/// @author Pawel Pilarczyk
10///
11/////////////////////////////////////////////////////////////////////////////
12
13// Copyright (C) 1997-2022 by Pawel Pilarczyk.
14//
15// This file is part of my research software package. This is free software:
16// you can redistribute it and/or modify it under the terms of the GNU
17// General Public License as published by the Free Software Foundation,
18// either version 3 of the License, or (at your option) any later version.
19//
20// This software is distributed in the hope that it will be useful,
21// but WITHOUT ANY WARRANTY; without even the implied warranty of
22// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23// GNU General Public License for more details.
24//
25// You should have received a copy of the GNU General Public License
26// along with this software; see the file "license.txt". If not,
27// please, see <https://www.gnu.org/licenses/>.
28
29// Started on February 14, 2007. Last revision: February 15, 2022.
30
31
32#ifndef _CMGRAPHS_PLOTMDEC_H_
33#define _CMGRAPHS_PLOTMDEC_H_
34
35
36#include "pngimage.h"
37#include "chomp/bitmaps/colorpal.h"
38
39
40// --------------------------------------------------
41// ------------ Plot Morse Decomposition ------------
42// --------------------------------------------------
43
44/// Saves all the Morse sets in the provided Morse decomposition
45/// to a PNG file. The coordinates of all the boxes in the Morse sets
46/// must be non-negative and they should not exceed the size provided
47/// unless the size is zero and then the size of the file is adjusted
48/// so that all the Morse sets are contained in the picture.
49/// Throws an error message in case of failure.
50template <class MorseDecType>
51inline void plotMorseDecompositionPNG (const MorseDecType &m,
52 const char *filename, int xCoord, int yCoord,
53 int size = 0, bool colorBar = true)
54{
55 typedef typename MorseDecType::CubSetType CubSetType;
56 typedef typename MorseDecType::CubeType CubeType;
57 typedef typename MorseDecType::CubeType::CoordType CoordType;
58
59 // determine the dimension of the cubes in the Morse sets
60 int dim = 0;
61 int nSets = m. count ();
62 for (int n = 0; n < nSets; ++ n)
63 {
64 if (m [n]. empty ())
65 continue;
66 dim = m [n] [0]. dim ();
67 break;
68 }
69
70 // make sure that the requested coordinates are in the range
71 if (nSets && ((xCoord >= dim) || (yCoord >= dim)))
72 throw "Coordinates out of range for plotting Morse decomp.";
73
74 // prepare a temporary array for coordinates of boxes
75 CoordType *coord = new CoordType [(dim < 2) ? 2 : dim];
76 coord [0] = coord [1] = 0;
77
78 // determine the size of the bitmap file
79 int width = size;
80 int height = size;
81 int xoffset = 0;
82 int yoffset = 0;
83 int nColors = nSets ? nSets : 1;
84 if (!size)
85 {
86 xoffset = 0x7FFFFFFF;
87 yoffset = 0x7FFFFFFF;
88 for (int n = 0; n < nSets; ++ n)
89 {
90 const CubSetType &theSet = m [n];
91 if (theSet. empty ())
92 {
93 -- nColors;
94 continue;
95 }
96 int setSize = theSet. size ();
97 for (int i = 0; i < setSize; ++ i)
98 {
99 const CubeType &q = theSet [i];
100 int d = q. dim ();
101 if (d != dim)
102 throw "Inconsistent dim of cubes.";
103 q. coord (coord);
104 if (width <= coord [xCoord])
105 width = coord [xCoord] + 1;
106 if (height <= coord [yCoord])
107 height = coord [yCoord] + 1;
108 if (xoffset > coord [xCoord])
109 xoffset = coord [xCoord];
110 if (yoffset > coord [yCoord])
111 yoffset = coord [yCoord];
112 }
113 }
114 if (xoffset > width)
115 xoffset = 0;
116 if (yoffset > height)
117 yoffset = 0;
118 width -= xoffset;
119 height -= yoffset;
120 }
121 if (width < 16)
122 width = 16;
123 if (height < 16)
124 height = 16;
125
126 // reserve space for a color bar if necessary
127 int colorBoxSize = 16;
128 int colorBarHeight = colorBar ? (colorBoxSize + 1) : 0;
129 int colorBarWidth = colorBar ?
130 (nColors * colorBoxSize + nColors - 1) : 0;
131 height += colorBarHeight;
132 if (width < colorBarWidth)
133 width = colorBarWidth;
134 int bottomHeight = colorBarHeight;
135
136 // prepare an empty PNG image
137 PngImage img (width, height);
138
139 // prepare a color palette and draw the color bar if required
140 chomp::homology::ColorPalette col (nColors);
141 if (colorBar && nColors && nSets)
142 {
143 for (int n = 0; n < nColors; ++ n)
144 {
145 int xMin = n * (colorBoxSize + 1);
146 int xMax = xMin + colorBoxSize;
147 int yMin = height - colorBarHeight + 1;
148 int yMax = yMin + colorBarHeight;
149 int color = col [n];
150 for (int x = xMin; x < xMax; ++ x)
151 {
152 for (int y = yMin; y < yMax; ++ y)
153 {
154 img. putPixel (x, y, color);
155 }
156 }
157 }
158 }
159
160 // plot the Morse sets in the PNG image
161 int colorNumber = 0;
162 for (int n = 0; n < nSets; ++ n)
163 {
164 const CubSetType &theSet = m [n];
165 if (theSet. empty ())
166 continue;
167 int color = col [colorNumber ++];
168 int setSize = theSet. size ();
169 for (int i = 0; i < setSize; ++ i)
170 {
171 const CubeType &q = theSet [i];
172 int d = q. dim ();
173 if (d != dim)
174 throw "Inconsistent dim of cubes to plot.";
175 q. coord (coord);
176 img. putPixel (coord [xCoord] - xoffset, height -
177 coord [yCoord] + yoffset - 1 - bottomHeight,
178 color);
179 }
180 }
181 delete [] coord;
182
183 // save the PNG file
184 img. save (filename);
185
186 return;
187} /* plotMorseDecomposition */
188
189
190#endif // _CMGRAPHS_PLOTMDEC_H_
191
An interface to the PNG library.
Definition: pngimage.h:52
void plotMorseDecompositionPNG(const MorseDecType &m, const char *filename, int xCoord, int yCoord, int size=0, bool colorBar=true)
Saves all the Morse sets in the provided Morse decomposition to a PNG file.
Definition: plotmdec.h:51
Writing PNG images.