NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
plotting.cpp
Go to the documentation of this file.
1/*****************************************************************************
2 NumeRe: Framework fuer Numerische Rechnungen
3 Copyright (C) 2017 Erik Haenel et al.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17******************************************************************************/
18
19#include <wx/image.h>
20
21#include "plotting.hpp"
22#include "plotasset.hpp"
23#include "../maths/parser_functions.hpp"
24#include "../../kernel.hpp"
25
26
28extern mglGraph _fontData;
29
30
31std::string removeQuotationMarks(const std::string&);
32
33
34
35static bool isPlot1D(const std::string& sCommand)
36{
37 return sCommand == "plot" || sCommand == "graph";
38}
39
40static bool isPlot3D(const std::string& sCommand)
41{
42 return sCommand == "plot3d" || sCommand == "graph3d";
43}
44
45static bool isMesh2D(const std::string& sCommand)
46{
47 return sCommand == "implot"
48 || (sCommand.substr(sCommand.length()-2) != "3d"
49 && (sCommand.substr(0, 4) == "mesh"
50 || sCommand.substr(0, 4) == "surf"
51 || sCommand.substr(0, 4) == "dens"
52 || sCommand.substr(0, 4) == "cont"
53 || sCommand.substr(0, 4) == "grad"));
54}
55
56static bool isMesh3D(const std::string& sCommand)
57{
58 return sCommand.substr(sCommand.length()-2) == "3d"
59 && (sCommand.substr(0, 4) == "mesh"
60 || sCommand.substr(0, 4) == "surf"
61 || sCommand.substr(0, 4) == "dens"
62 || sCommand.substr(0, 4) == "cont"
63 || sCommand.substr(0, 4) == "grad");
64}
65
66static bool isVect2D(const std::string& sCommand)
67{
68 return sCommand == "vect" || sCommand == "vector";
69}
70
71static bool isVect3D(const std::string& sCommand)
72{
73 return sCommand == "vect3d" || sCommand == "vector3d";
74}
75
76static bool isDraw(const std::string& sCommand)
77{
78 return sCommand == "draw" || sCommand == "draw3d";
79}
80
81static bool has3DView(const std::string& sCommand)
82{
83 return sCommand == "draw3d"
84 || isPlot3D(sCommand)
85 || isMesh3D(sCommand)
86 || sCommand.substr(0, 4) == "mesh" // "mesh3d" already handled and included
87 || sCommand.substr(0, 4) == "surf"
88 || sCommand.substr(0, 4) == "cont";
89}
90
91
92// These definitions are for easier understanding of the different ranges
93#define APPR_ONE 0.9999999
94#define APPR_TWO 1.9999999
95#define STYLES_COUNT 20
96
97using namespace std;
98
113void createPlot(std::string& sCmd, MemoryManager& _data, mu::Parser& _parser, Settings& _option, FunctionDefinitionManager& _functions, PlotData& _pData)
114{
115 Plot graph(sCmd, _data, _parser, _option, _functions, _pData);
116
117 // Only open graph viewer, if not explicitly deactivated
119 {
120 GraphHelper* _graphHelper = graph.createGraphHelper();
121
122 if (_pData.getTargetGUI()[0] != -1)
123 {
125
126 if (!window.window && window.nStatus != NumeRe::STATUS_RUNNING)
127 {
128 delete _graphHelper;
129 _pData.deleteData(true);
130 throw SyntaxError(SyntaxError::INVALID_WINDOW_ID, sCmd, "streamto");
131 }
132
133 if (!window.window->setItemGraph(_graphHelper, _pData.getTargetGUI()[1]))
134 {
135 delete _graphHelper;
136 _pData.deleteData(true);
137 throw SyntaxError(SyntaxError::INVALID_WINDOW_ITEM_ID, sCmd, "streamto");
138 }
139 }
140 else
142 }
143 // --> Speicher wieder freigeben <--
144 _pData.deleteData(true);
145}
146
147
157mglData duplicatePoints(const mglData& _mData)
158{
159 if (_mData.GetNy() > 1)
160 {
161 mglData _temp(_mData.GetNx()*2, _mData.GetNy());
162
163 for (int j = 0; j < _mData.GetNy(); j++)
164 {
165 for (int i = 0; i < _mData.GetNx(); i++)
166 {
167 _temp.a[2*i + j*_temp.GetNx()] = _mData.a[i+j*_mData.GetNx()];
168 _temp.a[2*i+1+j*_temp.GetNx()] = _mData.a[i+j*_mData.GetNx()];
169 }
170 }
171
172 return _temp;
173 }
174 else
175 {
176 mglData _temp(_mData.GetNN()*2);
177
178 for (int i = 0; i < _mData.GetNx(); i++)
179 {
180 _temp.a[2*i] = _mData.a[i];
181 _temp.a[2*i+1] = _mData.a[i];
182 }
183
184 return _temp;
185 }
186}
187
188
199static void writeTiff(mglGraph* _graph, const string& sOutputName)
200{
201 const unsigned char* bb = _graph->GetRGB();
202 int w = _graph->GetWidth();
203 int h = _graph->GetHeight();
204 unsigned char *tmp = (unsigned char*)malloc(3*w*h);
205 memcpy(tmp, bb, 3*w*h);
206 wxImage tiffimage(w, h, tmp);
207
208 tiffimage.SaveFile(sOutputName, wxBITMAP_TYPE_TIF);
209}
210
211
226Plot::Plot(string& sCmd, MemoryManager& __data, Parser& __parser, Settings& __option, FunctionDefinitionManager& __functions, PlotData& __pData)
227 : _data(__data), _parser(__parser), _option(__option), _functions(__functions), _pData(__pData)
228{
229 _graph = new mglGraph();
230 bOutputDesired = false; // if a output directly into a file is desired
231
232 _pInfo.sCommand = "";
233 _pInfo.sPlotParams = "";
234 _pInfo.b2D = false;
235 _pInfo.b3D = false;
236 _pInfo.b2DVect = false;
237 _pInfo.b3DVect = false;
238 _pInfo.bDraw = false;
239 _pInfo.bDraw3D = false;
241 _pInfo.nStyleMax = STYLES_COUNT; // Gesamtzahl der Styles
242 _pInfo.secranges.intervals.resize(2, Interval(NAN, NAN));
243
244 bool bAnimateVar = false;
245 sOutputName.clear();
246
247 vector<string> vPlotCompose;
248 unsigned int nMultiplots[2] = {0, 0};
249
250 unsigned int nSubPlots = 0;
251 unsigned int nSubPlotMap = 0;
252
253
254 // Pre-analyze the contents of the passed plotting command. If it
255 // contains the "plotcompose" command at start (this will be added
256 // by the command handler), then this is either a plot composition
257 // or a multiplot.
258 //
259 // If it is a plotcompose block, then we split it up into the single
260 // command lines. If it is a multiplot, then we will add the starting
261 // "subplot" command, if it is missing.
262 if (findCommand(sCmd).sString == "plotcompose")
263 {
264 // Remove the "plotcompose" command
265 sCmd.erase(findCommand(sCmd).nPos, 11);
266
267 // Search for the multiplot parameter
268 if (findParameter(sCmd, "multiplot", '='))
269 {
270 // Decode the lines and columns of the parameter
271 _parser.SetExpr(getArgAtPos(sCmd, findParameter(sCmd, "multiplot", '=') + 9));
272 int nRes = 0;
273 value_type* v = _parser.Eval(nRes);
274
275 // Only use the option value, if it contains two values
276 if (nRes == 2)
277 {
278 nMultiplots[1] = (unsigned int)intCast(v[0]);
279 nMultiplots[0] = (unsigned int)intCast(v[1]);
280 }
281
282 // Remove everything up to the first command in the
283 // block
284 sCmd.erase(0, sCmd.find("<<COMPOSE>>") + 11);
285
286 // Add the first "subplot", if it missing
287 if (findCommand(sCmd).sString != "subplot" && sCmd.find("subplot") != string::npos)
288 sCmd.insert(0, "subplot <<COMPOSE>> ");
289 }
290
291 StripSpaces(sCmd);
292
293 // Split the block and search for the maximal
294 // plot dimension simultaneously
295 while (sCmd.length())
296 {
297 // Search the command
298 string __sCMD = findCommand(sCmd).sString;
299
300 // Identify the plotting dimensions
302
303 // Split the command lines
304 vPlotCompose.push_back(sCmd.substr(0, sCmd.find("<<COMPOSE>>")));
305 sCmd.erase(0, sCmd.find("<<COMPOSE>>") + 11);
306 StripSpaces(sCmd);
307 }
308
309 // Gather all parameters from all contained plotting commands
310 for (unsigned int i = 0; i < vPlotCompose.size(); i++)
311 {
312 if (vPlotCompose[i].find("-set") != string::npos
313 && !isInQuotes(vPlotCompose[i], vPlotCompose[i].find("-set"))
314 && findCommand(vPlotCompose[i]).sString != "subplot")
315 _pInfo.sPlotParams += vPlotCompose[i].substr(vPlotCompose[i].find("-set"));
316 else if (vPlotCompose[i].find("--") != string::npos
317 && !isInQuotes(vPlotCompose[i], vPlotCompose[i].find("--"))
318 && findCommand(vPlotCompose[i]).sString != "subplot")
319 _pInfo.sPlotParams += vPlotCompose[i].substr(vPlotCompose[i].find("--"));
320
321 _pInfo.sPlotParams += " ";
322 }
323
324 // Apply the gathered parameters. If it is a regular plot composition,
325 // then use the "GLOBAL" parameter flag, otherwise use the "SUPERGLOBAL" flag
326 if (_pInfo.sPlotParams.length())
327 {
328 if (nMultiplots[0]) // if this is a multiplot layout, then we will only evaluate the SUPERGLOBAL parameters
330 else
332 }
333
334 // Clear the parameter set
335 _pInfo.sPlotParams = "";
336 }
337 else
338 {
339 // Find the plotting command
340 string __sCMD = findCommand(sCmd).sString;
341
342 // Identify the maximal plotting dimension
344
345 // Use the current command as a single "plot composition"
346 vPlotCompose.push_back(sCmd);
347 }
348
349 // String-Arrays fuer die endgueltigen Styles:
354
355 // The following statement moves the output cursor to the first postion and
356 // cleans the line to avoid overwriting
359
360 size_t nPlotStart = 0;
361
362 // Main loop of the plotting object. This will execute all plotting
363 // commands in the current comamnd set clustered into subplots event
364 // if only one plotting command is used
365 while (nPlotStart < vPlotCompose.size())
366 {
367 // If this is a multiplot layout then we need to evaluate the global options for every subplot,
368 // because we omitted this set further up. We enter this for each "subplot" command.
369 if (vPlotCompose.size() > 1 && nMultiplots[0])
370 {
371 // Reset the maximal plotting dimension
373 _pInfo.nStyle = 0;
374
375 // Gather each plotting parameter until the next "subplot" command or until the end of the
376 // whole block
377 for (unsigned int i = nPlotStart; i < vPlotCompose.size(); i++)
378 {
379 // Leave the loop, if the current command equals "subplot"
380 if (findCommand(vPlotCompose[i]).sString == "subplot")
381 break;
382
383 if (vPlotCompose[i].find("-set") != string::npos
384 && !isInQuotes(vPlotCompose[i], vPlotCompose[i].find("-set")))
385 _pInfo.sPlotParams += vPlotCompose[i].substr(vPlotCompose[i].find("-set"));
386 else if (vPlotCompose[i].find("--") != string::npos
387 && !isInQuotes(vPlotCompose[i], vPlotCompose[i].find("--")))
388 _pInfo.sPlotParams += vPlotCompose[i].substr(vPlotCompose[i].find("--"));
389
390 // Find the maximal plotting dimension of the current subplot
391 determinePlottingDimensions(findCommand(vPlotCompose[i]).sString);
392
393 // Append a whitespace for safety reasons
394 _pInfo.sPlotParams += " ";
395 }
396
397 // Apply the global parameters for this single subplot
398 if (_pInfo.sPlotParams.length())
399 {
401 _pInfo.sPlotParams.clear();
402 }
403 }
404
405 // Create the actual subplot of this plot composition (if only
406 // one plotting command is used, the return value will be equal to
407 // the size of the plot composition vectore, which is 1)
408 nPlotStart = createSubPlotSet(bAnimateVar, vPlotCompose, nPlotStart, nMultiplots, nSubPlots, nSubPlotMap);
409
410 // Perform the reset between single subplots here
411 if (nPlotStart < vPlotCompose.size())
412 {
413 _graph->SetFunc("", "", "");
414 _graph->SetOrigin(NAN, NAN, NAN);
415 _graph->Alpha(false);
416 _graph->Light(false);
417 }
418 }
419
420 // Save the created plot to the desired file, if the user specifies a file
421 // name to write to.
423 {
424 // --> Speichern und Erfolgsmeldung <--
425 if (!_pData.getAnimateSamples() || !bAnimateVar)
426 {
428 NumeReKernel::printPreFmt("|-> " + toSystemCodePage(_lang.get("PLOT_SAVING")) + " ... ");
429
430 if (sOutputName.substr(sOutputName.length()-4) == ".bps")
431 {
432 sOutputName[sOutputName.length()-3] = 'e';
433 _graph->WriteBPS(sOutputName.c_str());
434 }
435 else if (sOutputName.substr(sOutputName.length()-4) == ".tif" || sOutputName.substr(sOutputName.length()-5) == ".tiff")
437 else
438 _graph->WriteFrame(sOutputName.c_str());
439
440 // --> TeX-Ausgabe gewaehlt? Dann werden mehrere Dateien erzeugt, die an den Zielort verschoben werden muessen <--
441 if (sOutputName.substr(sOutputName.length() - 4, 4) == ".tex")
443
445 NumeReKernel::printPreFmt(toSystemCodePage(_lang.get("COMMON_SUCCESS")) + ".\n");
446 }
447
449 NumeReKernel::printPreFmt(LineBreak("| " + _lang.get("PLOT_SAVE_LOCATION", sOutputName), _option, 0) + "\n");
450 }
451}
452
453
458{
459 clearData();
460
461 if (_graph)
462 delete _graph;
463}
464
465
475void Plot::determinePlottingDimensions(const string& sPlotCommand)
476{
477 if ((sPlotCommand.substr(0, 4) == "mesh"
478 || sPlotCommand.substr(0, 4) == "surf"
479 || sPlotCommand.substr(0, 4) == "cont"
480 || sPlotCommand.substr(0, 4) == "vect"
481 || sPlotCommand.substr(0, 4) == "dens"
482 || sPlotCommand.substr(0, 4) == "draw"
483 || sPlotCommand.substr(0, 4) == "grad"
484 || sPlotCommand.substr(0, 4) == "plot")
485 && sPlotCommand.find("3d") != string::npos)
486 {
488 }
489 else if (sPlotCommand.substr(0, 4) == "mesh" || sPlotCommand.substr(0, 4) == "surf" || sPlotCommand.substr(0, 4) == "cont")
490 {
492 }
493 else if (sPlotCommand.substr(0, 4) == "vect" || sPlotCommand.substr(0, 4) == "dens" || sPlotCommand.substr(0, 4) == "grad" || sPlotCommand == "implot")
494 {
495 if (_pInfo.nMaxPlotDim < 3)
497 }
498}
499
500
515size_t Plot::createSubPlotSet(bool& bAnimateVar, vector<string>& vPlotCompose, size_t nSubPlotStart, size_t nMultiplots[2], size_t& nSubPlots, size_t& nSubPlotMap)
516{
517 vector<string> vDrawVector;
518 string sCmd;
519 bool bNewSubPlot = nSubPlotStart != 0;
520
521 dataRanges.intervals.resize(3);
522 dataRanges.setNames({"x", "y", "z"});
523 secDataRanges.intervals.resize(2);
524 secDataRanges.setNames({"x", "y"});
525
526 nLegends = 0;
527
528 // This loop will iterate through the plotting commands from
529 // the passed starting index until the end or until the command
530 // "subplot" has been found
531 for (unsigned int nPlotCompose = nSubPlotStart; nPlotCompose < vPlotCompose.size(); nPlotCompose++)
532 {
533 m_types.clear();
534 sCmd = vPlotCompose[nPlotCompose];
535 _pInfo.sPlotParams = "";
536
537 // Clean the memory, if this is not the first
538 // run through this loop
539 if (nPlotCompose)
540 {
541 // Clear allocated memory
542 if (m_manager.assets.size())
543 m_manager.assets.clear();
544
545 // Only delete the contents of the plot data object
546 // if the last command was no "subplot" command, otherwise
547 // one would reset all global plotting parameters
548 if (!bNewSubPlot)
550
551 // Reset the plot info object
552 _pInfo.b2D = false;
553 _pInfo.b3D = false;
554 _pInfo.b2DVect = false;
555 _pInfo.b3DVect = false;
556 _pInfo.bDraw3D = false;
557 _pInfo.bDraw = false;
558 vDrawVector.clear();
559 }
560
561 // Find the current plot command
563 size_t nOffset = findCommand(sCmd).nPos;
564
565 // Extract the "function-and-data" section
566 if (sCmd.find("-set") != string::npos && !isInQuotes(sCmd, sCmd.find("-set")))
567 sFunc = sCmd.substr(nOffset + _pInfo.sCommand.length(), sCmd.find("-set") - _pInfo.sCommand.length() - nOffset);
568 else if (sCmd.find("--") != string::npos && !isInQuotes(sCmd, sCmd.find("--")))
569 sFunc = sCmd.substr(nOffset + _pInfo.sCommand.length(), sCmd.find("--") - _pInfo.sCommand.length() - nOffset);
570 else
571 sFunc = sCmd.substr(nOffset + _pInfo.sCommand.length());
572
573 // --> Unnoetige Leerstellen entfernen <--
575
576 // --> Ruf' ggf. den Prompt auf <--
577 if (sFunc.find("??") != string::npos)
579
580 // Get the plotting parameters for the current command
581 if (sCmd.find("-set") != string::npos && !isInQuotes(sCmd, sCmd.find("-set")) && _pInfo.sCommand != "subplot")
582 _pInfo.sPlotParams = sCmd.substr(sCmd.find("-set"));
583 else if (sCmd.find("--") != string::npos && !isInQuotes(sCmd, sCmd.find("--")) && _pInfo.sCommand != "subplot")
584 _pInfo.sPlotParams = sCmd.substr(sCmd.find("--"));
585
586 // If the current command has plotting parameters,
587 // evaluate them here. The contained strings are
588 // also parsed at this location
589 if (_pInfo.sPlotParams.length())
590 {
591 // Apply the parameters locally (for a plot composition) or globally, if
592 // this is a single plot command
593 if (vPlotCompose.size() > 1)
595 else
597 }
598
599 if (!nPlotCompose)
600 {
601 // Apply the quality and image dimension settings to the overall result
602 // image. This affects also a whole multiplot and is therefore done before
603 // the first plot is rendered.
605 }
606
607 // Ensure that the current command line contains a "function-and-data" section
608 if (!sFunc.length() && vPlotCompose.size() > 1 && _pInfo.sCommand != "subplot")
609 continue;
610 else if (!sFunc.length() && _pInfo.sCommand != "subplot")
612
613 setStyles();
614
619
620 // Set the number of samples depending on the
621 // current plotting command
624 && _pInfo.sCommand.substr(0, 4) != "mesh"
625 && _pInfo.sCommand.substr(0, 4) != "surf"
626 && _pInfo.sCommand.substr(0, 4) != "grad"
627 && _pInfo.sCommand.substr(0, 4) != "cont"))
630 && (_pInfo.sCommand.substr(0, 4) == "mesh"
631 || _pInfo.sCommand.substr(0, 4) == "surf"
632 || _pInfo.sCommand.substr(0, 4) == "grad"
633 || _pInfo.sCommand.substr(0, 4) == "cont"))
634 _pInfo.nSamples = 1000;
635 else
637
638 if (_pInfo.nSamples > 151 && _pInfo.b3D)
639 _pInfo.nSamples = 151;
640
641
642 // Create a file name depending on the selected current plot
643 // command, if the user did not provide a custom one
644 filename(vPlotCompose.size(), nPlotCompose);
645
646 // Get the target output file name and remove the surrounding
647 // quotation marks
648 if (!nPlotCompose)
649 {
652
653 if (sOutputName[0] == '"' && sOutputName[sOutputName.length() - 1] == '"')
654 sOutputName = sOutputName.substr(1, sOutputName.length() - 2);
655 }
656
657 // This section contains the logic, which will determine the position
658 // of subplots in a multiplot layout. We'll only enter this section, if the
659 // current command equals "subplot" and continue with the next plot
660 // command afterwards
661 if (findCommand(sCmd).sString == "subplot" && nMultiplots[0] && nMultiplots[1])
662 {
663 // This function closes the current graph (puts the legend)
664 // and determines the position of the next subplot in the
665 // plotting layout
666 evaluateSubplot(sCmd, nMultiplots, nSubPlots, nSubPlotMap);
667 nSubPlots++;
668
669 // Return the position of the next plotting command
670 return nPlotCompose+1;
671 }
672 else if (findCommand(sCmd).sString == "subplot")
673 continue; // Ignore the "subplot" command, if we have no multiplot layout
674
675 // Display the "Calculating data for SOME PLOT" message
677
678 // Apply the logic and the transformation for logarithmic
679 // plotting axes
681 && (nPlotCompose == nSubPlotStart)
683 {
684 setLogScale((_pInfo.b2D || _pInfo.sCommand == "plot3d"));
685 }
686
687 // Prepare the legend strings
688 if (!_pInfo.bDraw3D && !_pInfo.bDraw)
689 {
690 // Obtain the values of string variables, which are probably used
691 // as part of the legend strings
692 if (NumeReKernel::getInstance()->getStringParser().containsStringVars(sFunc))
694
695 // Add the legends to the function-and-data section
696 if (!addLegends(sFunc))
697 return vPlotCompose.size(); // --> Bei Fehlern: Zurueck zur aufrufenden Funktion <--
698 }
699
700 // Replace the custom defined functions with their definition
701 if (!_functions.call(sFunc))
703
704 // Call the input prompt, if one of the function definition requires this
705 if (sFunc.find("??") != string::npos)
707
708 // Split the function-and-data section into functions and data sets,
709 // evaluate the indices of the data sets and store the values of the
710 // data sets into the mglData objects, which will be used further down
711 // to display the data values in the plots
712 std::vector<std::string> vDataPlots;
713
714 if (!isDraw(_pInfo.sCommand))
715 vDataPlots = separateFunctionsAndData();
716
717 // Do we need to search for the animation parameter variable?
719 {
720 for (std::string sDataPlots : vDataPlots)
721 {
722 if (findVariableInExpression(sDataPlots, "t") != std::string::npos)
723 {
724 bAnimateVar = true;
725 // set t to the starting value
726 _defVars.vValue[TCOORD][0] = _pData.getRanges()[TRANGE].front(); // Plotparameter: t
727 break;
728 }
729 }
730 }
731
732 // Prepare the plotting memory for functions and datasets depending
733 // on their number
735
736 // Get now the data values for the plot
737 extractDataValues(vDataPlots);
738
740
741 // Ensure that either functions or data plots are available
742 if (!m_manager.assets.size() && !isDraw(_pInfo.sCommand))
744
745 // Ensure that the functions do not contain any strings, because strings
746 // cannot be plotted
747 if (NumeReKernel::getInstance()->getStringParser().isStringExpression(sFunc) && !(_pInfo.bDraw3D || _pInfo.bDraw))
748 {
749 clearData();
751 }
752
753 // Determine, whether the function string is empty. If it is and the current
754 // plotting style is not a drawing style, then assign the function string to
755 // the parser. Otherwise split the function string into the single functions.
757 {
758 try
759 {
762
763 // Search for the animation time variable "t"
765 bAnimateVar = true;
766
767 // Check, whether the number of functions correspond to special
768 // plotting styles
770 && _pInfo.b2D
771 && m_types.size() % 2)
773 }
774 catch (...)
775 {
776 clearData();
777 throw;
778 }
779 }
781 {
782 string sArgument;
783 // Append a whitespace
784 sFunc += " ";
785
786 // Split the function string into the single functions
787 // and store them in the drawing vector
788 while (sFunc.length())
789 {
790 sArgument = getNextArgument(sFunc, true);
791 StripSpaces(sArgument);
792
793 if (!sArgument.length())
794 continue;
795
796 // Try to detect the occurence of the animation variable
797 if (findVariableInExpression(sArgument, "t") != string::npos)
798 bAnimateVar = true;
799
800 vDrawVector.push_back(sArgument);
801 }
802
803 // Set the function string to be empty
804 sFunc.clear();
805 }
806 else
807 sFunc.clear();
808
809 // Calculate the default plotting ranges depending on the user
810 // specification. If the user didn't specify
811 // a set of ranges, we try to use the plotting ranges of the data
812 // points and omit negative numbers, if the corresponding axis was
813 // set to logarithmic scale.
814 defaultRanges(nPlotCompose, bNewSubPlot);
815
816 // Set the plot calculation variables (x, y and z) to their starting
817 // points
818 _defVars.vValue[XCOORD][0] = _pInfo.ranges[XRANGE].front(); // Plotvariable: x
819 _defVars.vValue[YCOORD][0] = _pInfo.ranges[YRANGE].front(); // Plotvariable: y
820 _defVars.vValue[ZCOORD][0] = _pInfo.ranges[ZRANGE].front(); // Plotvariable: z
821
822 // For the "plot3d" style or the animated plot we need the time coordinate.
823 // Set it to their corresponding starting value
824 if (_pInfo.sCommand == "plot3d" || _pData.getAnimateSamples())
825 _defVars.vValue[TCOORD][0] = _pInfo.ranges[TRANGE].front(); // Plotparameter: t
826
827 // Now create the plot or the animation using the provided and
828 // pre-calculated data. This function will also open and
829 // close the GIF, if the animation directly saved to a file
830 createPlotOrAnimation(nPlotCompose, vPlotCompose.size(), bNewSubPlot, bAnimateVar, vDrawVector, vDataPlots);
831
832 bNewSubPlot = false;
833
835 NumeReKernel::printPreFmt(toSystemCodePage(_lang.get("COMMON_DONE")) + ".\n");
836 }
837
838 // Return the lenght of the plotcompostion array, which
839 // will signal the calling function that we're finished
840 // with plotting and that the control can be returned to
841 // the kernel.
842 return vPlotCompose.size();
843}
844
845
855{
856 // Apply the quality and image dimension settings to the overall result
857 // image. This affects also a whole multiplot and is therefore done before
858 // the first plot is rendered.
859 // If the user requests a specific size, we'll preferably using this
863 {
864 // Switch between fullHD and the normal resolution
866 {
867 double dHeight = sqrt(1920.0 * 1440.0 / _pData.getSettings(PlotData::FLOAT_ASPECT));
868 _graph->SetSize((int)lrint(_pData.getSettings(PlotData::FLOAT_ASPECT)*dHeight), (int)lrint(dHeight));
869 }
870 else
871 {
872 double dHeight = sqrt(1280.0 * 960.0 / _pData.getSettings(PlotData::FLOAT_ASPECT));
873 _graph->SetSize((int)lrint(_pData.getSettings(PlotData::FLOAT_ASPECT)*dHeight), (int)lrint(dHeight));
874 }
875 }
876 else
877 {
878 // This section is for printing to the GraphViewer window
879 // we use different resolutions here
881 {
882 // Animation size (faster for rendering)
883 double dHeight = sqrt(640.0 * 480.0 / _pData.getSettings(PlotData::FLOAT_ASPECT));
884 _graph->SetSize((int)lrint(_pData.getSettings(PlotData::FLOAT_ASPECT)*dHeight), (int)lrint(dHeight));
885 }
887 {
888 // Hires output
889 double dHeight = sqrt(1280.0 * 960.0 / _pData.getSettings(PlotData::FLOAT_ASPECT));
890 _graph->SetSize((int)lrint(_pData.getSettings(PlotData::FLOAT_ASPECT)*dHeight), (int)lrint(dHeight));
891 }
892 else
893 {
894 // Standard output
895 double dHeight = sqrt(800.0 * 600.0 / _pData.getSettings(PlotData::FLOAT_ASPECT));
896 _graph->SetSize((int)lrint(_pData.getSettings(PlotData::FLOAT_ASPECT)*dHeight), (int)lrint(dHeight));
897 }
898 }
899
900 // Copy the font and select the font size
901 _graph->CopyFont(&_fontData);
902 //_graph->SetFontSizePT(8 * ((double)(1 + _pData.getSettings(PlotData::FLOAT_TEXTSIZE)) / 6.0), 72);
903 _graph->SetFontSizeCM(0.22 * (1.0 + _pData.getSettings(PlotData::FLOAT_TEXTSIZE)) / 6.0, 72);
904 _graph->SetFlagAdv(1, MGL_FULL_CURV);
905 //_graph->SubPlot(1,1,0, "");
906 //_graph->SubPlot(1,1,0, "");
907
908}
909
910
929bool Plot::createPlotOrAnimation(size_t nPlotCompose, size_t nPlotComposeSize, bool bNewSubPlot, bool bAnimateVar, vector<string>& vDrawVector, const vector<string>& vDataPlots)
930{
931 mglData _mBackground;
932
933 // If the animation is saved to a file, set the frame time
934 // for the GIF image
936 _graph->StartGIF(sOutputName.c_str(), 40); // 40msec = 2sec bei 50 Frames, d.h. 25 Bilder je Sekunde
937
938 // Load the background image from the target file and apply the
939 // black/white color scheme
941 {
944
945 if (_option.systemPrints())
946 NumeReKernel::printPreFmt(toSystemCodePage(_lang.get("PLOT_LOADING_BACKGROUND")) + " ... ");
947
948 _mBackground.Import(_pData.getSettings(PlotData::STR_BACKGROUND).c_str(), "kw");
949
951 NumeReKernel::printPreFmt(toSystemCodePage(_lang.get("COMMON_DONE")) + ".\n");
952 }
953
954 // This is the start of the actual plotting algorithm. The previous
955 // lines were only preparations for this algorithm. We create either a
956 // single plot or a set of frames for an animation
957 for (int t_animate = 0; t_animate <= _pData.getAnimateSamples(); t_animate++)
958 {
959 // If it is an animation, then we're required to reset the plotting
960 // variables for each frame. Additionally, we have to start a new
961 // frame at this location.
963 {
964 NumeReKernel::printPreFmt("\r|-> " + toSystemCodePage(_lang.get("PLOT_RENDERING_FRAME", toString(t_animate + 1), toString(_pData.getAnimateSamples() + 1))) + " ... ");
965 _pInfo.nStyle = 0;
966
967 // Prepare a new frame
968 _graph->NewFrame();
969
970 // Reset the plotting variables (x, y and z) to their initial values
971 // and increment the time variable one step further
972 if (t_animate)
973 {
975
976 // Recalculate the data plots
977 extractDataValues(vDataPlots);
978
979 defaultRanges(nPlotCompose, true);
980
981 _defVars.vValue[XCOORD][0] = _pInfo.ranges[XRANGE].front();
982 _defVars.vValue[YCOORD][0] = _pInfo.ranges[YRANGE].front();
983 _defVars.vValue[ZCOORD][0] = _pInfo.ranges[ZRANGE].front();
984 }
985 }
986
987 double dt_max = _defVars.vValue[TCOORD][0].real();
988
989 // Apply the title line to the graph
992
993 // If the user requested an orthogonal projection, then
994 // we activate this plotting mode at this location
996 {
997 _graph->Ternary(4);
998 _graph->SetRotatedText(false);
999 }
1000
1001 // Rotate the graph to the desired plotting angles
1002 if (_pInfo.nMaxPlotDim > 2 && (!nPlotCompose || bNewSubPlot))
1004
1005 // Calculate the function values for the set plotting ranges
1006 // and the eventually set time variable
1007 fillData(dt_max, t_animate);
1008
1009 // Normalize the plotting results, if the current plotting
1010 // style is a vector field
1012 m_manager.normalize(t_animate);
1013
1014 // Change the plotting ranges to fit to the calculated plot
1015 // data (only, if the user did not specify those ranges, too).
1016 fitPlotRanges(nPlotCompose, bNewSubPlot);
1017
1018 // Pass the final ranges to the graph. Only do this, if this is
1019 // the first plot of a plot composition or a new subplot.
1020 if (!nPlotCompose || bNewSubPlot)
1022
1023 // Apply a color bar, if desired and supplied by the plotting style
1024 applyColorbar();
1025
1026 // Apply the light effect, if desired and supplied by the plotting stype
1027 applyLighting();
1028
1029 // Activate the perspective effect
1030 if ((!nPlotCompose || bNewSubPlot) && _pInfo.nMaxPlotDim > 2)
1032
1033 // Render the background image
1035 {
1037 {
1038 _graph->SetRanges(_pInfo.ranges[XRANGE].min(), _pInfo.ranges[XRANGE].max(),
1039 _pInfo.ranges[YRANGE].min(), _pInfo.ranges[YRANGE].max(),
1040 _mBackground.Minimal(), _mBackground.Maximal());
1041 _graph->Dens(_mBackground, _pData.getSettings(PlotData::STR_BACKGROUNDCOLORSCHEME).c_str());
1042 }
1043 else
1045
1046 _graph->Rasterize();
1047 _graph->SetRanges(_pInfo.ranges[XRANGE].min(), _pInfo.ranges[XRANGE].max(),
1048 _pInfo.ranges[YRANGE].min(), _pInfo.ranges[YRANGE].max(),
1049 _pInfo.ranges[ZRANGE].min(), _pInfo.ranges[ZRANGE].max());
1050 }
1051
1052 // This section will transform the calculated data points into the desired
1053 // plotting style. The most complex plots are the default plot, the "plot3d"
1054 // and the 2D-Plots (mesh, surf, etc.)
1055 if (isMesh2D(_pInfo.sCommand)) // 2D-Plot
1056 create2dPlot(nPlotCompose, nPlotComposeSize);
1057 else if (isPlot1D(_pInfo.sCommand)) // Standardplot
1058 createStdPlot(nPlotCompose, nPlotComposeSize);
1059 else if (isMesh3D(_pInfo.sCommand)) // 3D-Plot
1060 create3dPlot();
1061 else if (isVect3D(_pInfo.sCommand)) // 3D-Vektorplot
1062 create3dVect();
1063 else if (isVect2D(_pInfo.sCommand)) // 2D-Vektorplot
1064 create2dVect();
1065 else if (_pInfo.bDraw)
1066 create2dDrawing(vDrawVector);
1067 else if (_pInfo.bDraw3D)
1068 create3dDrawing(vDrawVector);
1069 else // 3D-Trajektorie
1070 createStd3dPlot(nPlotCompose, nPlotComposeSize);
1071
1072 // Finalize the GIF frame
1073 if (_pData.getAnimateSamples() && bAnimateVar)
1074 _graph->EndFrame();
1075
1076 // If no animation was selected or the
1077 // animation variable ("t") is missing,
1078 // leave the loop at this position
1079 if (!bAnimateVar)
1080 break;
1081 }
1082
1083 // Finalize the GIF completely
1084 if (_pData.getAnimateSamples() && bAnimateVar && bOutputDesired)
1085 _graph->CloseGIF();
1086
1087 return true;
1088}
1089
1090
1101void Plot::create2dPlot(size_t nPlotCompose, size_t nPlotComposeSize)
1102{
1103 string sDummy = "";
1104 string sConvLegends = "";
1105 bool useImag = false;
1106 bool isComplexPlaneMode = _pData.getSettings(PlotData::INT_COMPLEXMODE) == CPLX_PLANE;
1107 mglData _mData(_pInfo.nSamples, _pInfo.nSamples);
1108 mglData _mData2;
1109 mglData _mPlotAxes[2];
1110 mglData _mContVec(_pData.getSettings(PlotData::INT_CONTLINES));
1111
1112 for (int nCont = 0; nCont < _pData.getSettings(PlotData::INT_CONTLINES); nCont++)
1113 {
1114 _mContVec.a[nCont] = _pInfo.ranges[ZRANGE](nCont, _pData.getSettings(PlotData::INT_CONTLINES)).real();
1115 }
1116
1118 _mContVec.a[_pData.getSettings(PlotData::INT_CONTLINES)/2] = _pInfo.ranges[ZRANGE].middle();
1119
1120 // Apply curvilinear coordinates
1124
1125 for (int n = 0; n < (int)m_manager.assets.size(); n++)
1126 {
1127 int nDataOffset = 0;
1128
1130 {
1131 _mPlotAxes[XCOORD].Link(m_manager.assets[n].data[0].first);
1132 _mPlotAxes[YCOORD].Link(m_manager.assets[n+1].data[0].first);
1133 nDataOffset = 2;
1134 }
1135 else
1136 {
1137 _mPlotAxes[XCOORD].Link(m_manager.assets[n].axes[XCOORD]);
1138 _mPlotAxes[YCOORD].Link(m_manager.assets[n].axes[YCOORD]);
1139 }
1140
1141 StripSpaces(m_manager.assets[n+nDataOffset].legend);
1142
1143 if (isComplexPlaneMode)
1144 _mData = m_manager.assets[n+nDataOffset].norm(0);
1145 else
1146 _mData.Link(useImag ? m_manager.assets[n+nDataOffset].data[0].second : m_manager.assets[n+nDataOffset].data[0].first);
1147
1149 && n+nDataOffset+1 < (int)m_manager.assets.size())
1150 _mData2.Link(useImag ? m_manager.assets[n+nDataOffset+1].data[0].second : m_manager.assets[n+nDataOffset+1].data[0].first);
1151 else if (isComplexPlaneMode)
1152 _mData2 = m_manager.assets[n+nDataOffset].arg(0);
1154 _mData2.Create(_pInfo.nSamples, _pInfo.nSamples);
1155
1156 // Create the actual 2D plot
1157 if (!plot2d(_mData, _mData2, _mPlotAxes, _mContVec))
1158 {
1159 clearData();
1160 return;
1161 }
1162
1163 // Do only present legend entries, if there are more than two
1164 // data sets or more than two composed data sets to be displayed
1165 if ((int)m_manager.assets.size() > 2+nDataOffset
1168 {
1169 if (_pData.getSettings(PlotData::LOG_CONTLABELS) && _pInfo.sCommand.substr(0, 4) != "cont")
1170 _graph->Cont(_mPlotAxes[0], _mPlotAxes[1], _mData,
1171 ("t" + _pInfo.sContStyles[_pInfo.nStyle]).c_str(), ("val " + toString(_pData.getSettings(PlotData::INT_CONTLINES))).c_str());
1172 else if (!_pData.getSettings(PlotData::LOG_CONTLABELS) && _pInfo.sCommand.substr(0, 4) != "cont")
1173 _graph->Cont(_mPlotAxes[0], _mPlotAxes[1], _mData,
1175
1176 sConvLegends = m_manager.assets[n+nDataOffset].legend + " -nq";
1177 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sConvLegends, sDummy, true);
1178
1179 if (_pData.getSettings(PlotData::INT_COMPLEXMODE) == CPLX_REIM && sConvLegends.length())
1180 sConvLegends = useImag ? "Im(" + sConvLegends + ")" : "Re(" + sConvLegends + ")";
1181
1182 sConvLegends = "\"" + sConvLegends + "\"";
1183
1184 if (sConvLegends != "\"\"")
1185 {
1186 _graph->AddLegend(fromSystemCodePage(replaceToTeX(sConvLegends.substr(1, sConvLegends.length() - 2))).c_str(),
1187 _pInfo.sContStyles[_pInfo.nStyle].c_str());
1188 nLegends++;
1189 }
1190
1192 }
1193
1195 {
1196 if (!useImag)
1197 {
1198 useImag = true;
1199 n--;
1200 }
1201 else
1202 {
1203 useImag = false;
1204 n += nDataOffset;
1205 }
1206 }
1207 else
1208 n += nDataOffset;
1209
1211 && n+1 < (int)m_manager.assets.size()
1213 n++;
1214 }
1215
1216 if (nLegends && !_pData.getSettings(PlotData::LOG_SCHEMATIC) && nPlotCompose + 1 == nPlotComposeSize)
1217 _graph->Legend(1.35, 1.2);
1218}
1219
1220
1233bool Plot::plot2d(mglData& _mData, mglData& _mData2, mglData* _mAxisVals, mglData& _mContVec)
1234{
1236 && _pInfo.sCommand.substr(0, 4) != "cont"
1237 && _pInfo.sCommand.substr(0, 4) != "grad"
1238 && _pInfo.sCommand.substr(0, 4) != "dens"
1239 && _pInfo.sCommand != "implot")
1242
1243 // --> Entsprechend dem gewuenschten Plotting-Style plotten <--
1244 if (_pInfo.sCommand.substr(0, 4) == "mesh")
1245 {
1247 _graph->Boxs(_mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme("#").c_str());
1248 else
1249 _graph->Mesh(_mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme().c_str());
1250 }
1251 else if (_pInfo.sCommand.substr(0, 4) == "surf")
1252 {
1254 _graph->Boxs(_mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme().c_str());
1256 _graph->SurfC(_mAxisVals[0], _mAxisVals[1], _mData, _mData2, _pData.getColorScheme().c_str());
1258 _graph->SurfA(_mAxisVals[0], _mAxisVals[1], _mData, _mData2, _pData.getColorScheme().c_str());
1259 else
1260 _graph->Surf(_mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme().c_str());
1261 }
1262 else if (_pInfo.sCommand.substr(0, 4) == "cont")
1263 {
1265 {
1267 _graph->ContF(_mContVec, _mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme().c_str());
1268
1269 _graph->Cont(_mContVec, _mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme("t").c_str());
1270 }
1272 {
1274 {
1275 _graph->ContF(_mContVec, _mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme("_").c_str());
1276 _graph->Cont(_mContVec, _mAxisVals[0], _mAxisVals[1], _mData, "_k");
1277 }
1278 else
1279 _graph->Cont(_mContVec, _mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme("_").c_str());
1280 }
1282 {
1283 _graph->ContF(_mContVec, _mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme().c_str());
1284 _graph->Cont(_mContVec, _mAxisVals[0], _mAxisVals[1], _mData, "k");
1285 }
1286 else
1287 _graph->Cont(_mContVec, _mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme().c_str());
1288 }
1289 else if (_pInfo.sCommand.substr(0, 4) == "grad")
1290 {
1292 {
1294 _graph->Grad(_mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorSchemeMedium().c_str(), "value 10");
1295 else
1296 _graph->Grad(_mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme().c_str(), "value 10");
1297 }
1298 else
1299 {
1301 _graph->Grad(_mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorSchemeMedium().c_str());
1302 else
1303 _graph->Grad(_mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme().c_str());
1304 }
1305
1307 _graph->Dens(_mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorSchemeLight().c_str());
1308 }
1309 else if (_pInfo.sCommand.substr(0, 4) == "dens" || _pInfo.sCommand == "implot")
1310 {
1312 _graph->Tile(_mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme().c_str());
1314 {
1315 // Density plot from -PI to PI
1316 _graph->Dens(_mAxisVals[0], _mAxisVals[1], _mData2, _pData.getColorScheme().c_str());
1317
1318 // Contour lines from ZRANGE-min to ZRANGE-max
1319 _graph->SetRange('c', _pInfo.ranges[ZRANGE].min(), _pInfo.ranges[ZRANGE].max());
1320 _graph->SetTicksVal('c', "");
1321 _graph->Colorbar(_pData.getSettings(PlotData::LOG_BOX) ? "kw^I" : "kw^");
1322 _graph->Cont(_mContVec, _mAxisVals[0], _mAxisVals[1], _mData, "kw");
1323 }
1324 else
1325 _graph->Dens(_mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme().c_str());
1326 }
1327 else
1328 return false;
1329
1331 && _pInfo.sCommand.substr(0, 4) != "cont"
1332 && _pInfo.sCommand.substr(0, 4) != "grad"
1333 && _pInfo.sCommand.substr(0, 4) != "dens")
1334 _graph->SetCutBox(mglPoint(0), mglPoint(0));
1335
1336 // --> Ggf. Konturlinien ergaenzen <--
1337 if (_pData.getSettings(PlotData::LOG_CONTPROJ) && _pInfo.sCommand.substr(0, 4) != "cont")
1338 {
1339 if (_pData.getSettings(PlotData::LOG_CONTFILLED) && _pInfo.sCommand.substr(0, 4) != "dens")
1340 {
1341 _graph->ContF(_mContVec, _mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme("_").c_str());
1342 _graph->Cont(_mContVec, _mAxisVals[0], _mAxisVals[1], _mData, "_k");
1343 }
1344 else if (_pInfo.sCommand.substr(0, 4) == "dens" && _pData.getSettings(PlotData::LOG_CONTFILLED))
1345 _graph->Cont(_mContVec, _mAxisVals[0], _mAxisVals[1], _mData, "_k");
1346 else
1347 _graph->Cont(_mContVec, _mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme("_").c_str());
1348 }
1349
1350 if (_pData.getSettings(PlotData::LOG_CONTLABELS) && _pInfo.sCommand.substr(0, 4) != "cont" && _pInfo.nFunctions == 1)
1351 {
1352 _graph->Cont(_mContVec, _mAxisVals[0], _mAxisVals[1], _mData, ("t" + _pInfo.sContStyles[_pInfo.nStyle]).c_str());
1353
1355 _graph->ContF(_mContVec, _mAxisVals[0], _mAxisVals[1], _mData, _pData.getColorScheme().c_str());
1356 }
1357
1358 return true;
1359}
1360
1361
1372static mglData scaleSecondaryToPrimaryInterval(const mglData& _mData, const Interval& ivl, const Interval& secIvl)
1373{
1374 return (_mData - secIvl.min()) * ivl.range() / secIvl.range() + ivl.min();
1375}
1376
1377
1388void Plot::createStdPlot(size_t nPlotCompose, size_t nPlotComposeSize)
1389{
1390 string sDummy = "";
1391 string sConvLegends = "";
1392 bool useImag = false;
1393 bool isCplxPlaneMode = _pData.getSettings(PlotData::INT_COMPLEXMODE) == CPLX_PLANE;
1394
1395 mglData _mData;
1396 mglData _mPlotAxes;
1397 mglData _mData2[2];
1398
1399 int nPrevDataLayers = 0;
1400 int nCurrentStyle = 0;
1401
1402 // Apply curvilinear coordinates
1404
1405 for (int n = 0; n < (int)m_manager.assets.size(); n++)
1406 {
1407 int nDataOffset = 0;
1408
1409 if (_pData.getSettings(PlotData::LOG_PARAMETRIC) && n+1 < (int)m_manager.assets.size() && !isCplxPlaneMode)
1410 {
1411 _mPlotAxes.Link(m_manager.assets[n].data[0].first);
1412 nDataOffset = 1;
1413 }
1414 else
1415 _mPlotAxes.Link(isCplxPlaneMode ? m_manager.assets[n].data[0].first : m_manager.assets[n].axes[XCOORD]);
1416
1417 StripSpaces(m_manager.assets[n+nDataOffset].legend);
1418
1419 _mData.Link(useImag || isCplxPlaneMode ? m_manager.assets[n+nDataOffset].data[0].second : m_manager.assets[n+nDataOffset].data[0].first);
1420
1421 if (_pData.getSettings(PlotData::LOG_REGION) && n+nDataOffset+1 < (int)m_manager.assets.size())
1422 _mData2[0].Link(useImag || isCplxPlaneMode ? m_manager.assets[n+nDataOffset+1].data[0].second : m_manager.assets[n+nDataOffset+1].data[0].first);
1423 else
1424 _mData2[0] = 0.0 * _mData;
1425
1426 // Copy the data to the relevant memory
1427 if (m_manager.assets[n+nDataOffset].type == PT_FUNCTION)
1428 {
1429 if (m_manager.assets[n+nDataOffset].boundAxes.find('r') != std::string::npos)
1431
1432 if (_pData.getSettings(PlotData::LOG_REGION) && m_manager.assets[n+nDataOffset+1].boundAxes.find('r') != std::string::npos)
1434 }
1435 else
1436 {
1438 {
1439 // Create the boxplot axis (count of elements has to be one element larger)
1440 _mData2[0].Create(m_manager.assets[n+nDataOffset].getLayers()+1);
1441
1442 for (size_t col = 0; col < m_manager.assets[n+nDataOffset].getLayers()+1; col++)
1443 {
1444 // Create the axis by adding previous layers to shift
1445 // the current box plots to the right
1446 _mData2[0].a[col] = nPrevDataLayers + 0.5 + col;
1447 }
1448
1449 nPrevDataLayers += m_manager.assets[n+nDataOffset].getLayers();
1450 _mData = m_manager.assets[n+nDataOffset].vectorsToMatrix();
1451 _mData.Transpose();
1452 }
1455 _mData = m_manager.assets[n+nDataOffset].vectorsToMatrix();
1456 else
1457 {
1459 {
1461 {
1462 // If the current data dimension is higher than 2, then we
1463 // expand it into an array of curves
1464 if (m_manager.assets[n+nDataOffset].getLayers() > 1)
1465 _mData = m_manager.assets[n+nDataOffset].vectorsToMatrix();
1466
1467 // Create an zero-error data set
1468 _mData2[0] = 0.0 * _mData;
1469 }
1470 }
1472 {
1473 size_t layer = 1;
1474
1475 if (_pData.getSettings(PlotData::LOG_XERROR) && m_manager.assets[n+nDataOffset].getLayers() > layer)
1476 {
1477 _mData2[XCOORD].Link(m_manager.assets[n+nDataOffset].data[layer].first);
1478 layer++;
1479 }
1480 else
1481 _mData2[XCOORD] = 0.0 * _mData;
1482
1483 if (_pData.getSettings(PlotData::LOG_YERROR) && m_manager.assets[n+nDataOffset].getLayers() > layer)
1484 _mData2[YCOORD].Link(m_manager.assets[n+nDataOffset].data[layer].first);
1485 else
1486 _mData2[YCOORD] = 0.0 * _mData;
1487 }
1488 else if (m_manager.assets[n+nDataOffset].getLayers() > 1)
1489 _mData = m_manager.assets[n+nDataOffset].vectorsToMatrix();
1490 }
1491
1492 if (m_manager.assets[n+nDataOffset].boundAxes.find('t') != std::string::npos)
1493 {
1494 for (int i = 0; i < getNN(_mPlotAxes); i++)
1495 {
1496 if (!_pInfo.secranges[XRANGE].isInside(_mPlotAxes.a[i]))
1497 _mPlotAxes.a[i] = NAN;
1498 }
1499
1501 }
1502 else
1503 {
1504 for (int i = 0; i < getNN(_mPlotAxes); i++)
1505 {
1506 if (!_pInfo.ranges[XRANGE].isInside(_mPlotAxes.a[i]))
1507 _mPlotAxes.a[i] = NAN;
1508 }
1509 }
1510
1511 if (m_manager.assets[n+nDataOffset].boundAxes.find('r') != std::string::npos)
1513
1514 if (_pData.getSettings(PlotData::LOG_REGION) && m_manager.assets[n+nDataOffset+1].boundAxes.find('r') != std::string::npos && getNN(_mData2[0]) > 1)
1516
1517 if (_pData.getSettings(PlotData::LOG_YERROR) && m_manager.assets[n+nDataOffset].boundAxes.find('r') != std::string::npos)
1519
1520 if (_pData.getSettings(PlotData::LOG_XERROR) && m_manager.assets[n+nDataOffset].boundAxes.find('t') != std::string::npos)
1522 }
1523
1524 // Store the current style
1525 nCurrentStyle = _pInfo.nStyle;
1526
1527 // Create the plot
1528 if (!plotstd(_mData, _mPlotAxes, _mData2, m_manager.assets[n+nDataOffset].type))
1529 {
1530 // --> Den gibt's nicht: Speicher freigeben und zurueck! <--
1531 clearData();
1532 return;
1533 }
1534
1535 // Increment the style counter
1537
1538 // Create the legend
1539 if (_pData.getSettings(PlotData::LOG_REGION) && getNN(_mData2[0]) > 1)
1540 sConvLegends = "\"" + removeQuotationMarks(m_manager.assets[n+nDataOffset].legend) + "\n"
1541 + removeQuotationMarks(m_manager.assets[n+nDataOffset].legend) + "\" -nq";
1542 else
1543 sConvLegends = m_manager.assets[n+nDataOffset].legend + " -nq";
1544
1545 // Apply the string parser
1546 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sConvLegends, sDummy, true);
1547
1548 // While the legend string is not empty
1549 while (sConvLegends.length())
1550 {
1551 // Get the next legend string
1552 string sLegend = sConvLegends.substr(0, sConvLegends.find('\n'));
1553
1554 if (sConvLegends.find('\n') != string::npos)
1555 sConvLegends.erase(0, sConvLegends.find('\n')+1);
1556 else
1557 sConvLegends.clear();
1558
1559 if (_pData.getSettings(PlotData::INT_COMPLEXMODE) == CPLX_REIM && sLegend.length())
1560 sLegend = useImag ? "Im(" + sLegend + ")" : "Re(" + sLegend + ")";
1561
1562 // Add new surrounding quotation marks
1563 sLegend = "\"" + sLegend + "\"";
1564
1565 // Add the legend
1566 if (sLegend != "\"\"")
1567 {
1568 std::string sLegendStyle;
1569
1570 if (m_manager.assets[n+nDataOffset].type == PT_FUNCTION)
1571 sLegendStyle = getLegendStyle(_pInfo.sLineStyles[nCurrentStyle]);
1572 else
1573 {
1575 sLegendStyle = getLegendStyle(_pInfo.sLineStyles[nCurrentStyle]);
1577 {
1578 if ((_pData.getSettings(PlotData::LOG_INTERPOLATE) && m_manager.assets[n+nDataOffset].axes[0].nx >= _pInfo.nSamples)
1581 sLegendStyle = getLegendStyle(_pInfo.sLineStyles[nCurrentStyle]);
1583 || (_pData.getSettings(PlotData::LOG_INTERPOLATE) && m_manager.assets[n+nDataOffset].axes[0].nx >= 0.9 * _pInfo.nSamples))
1584 sLegendStyle = getLegendStyle(_pInfo.sConPointStyles[nCurrentStyle]);
1586 sLegendStyle = getLegendStyle(_pInfo.sLineStyles[nCurrentStyle]);
1587 else
1588 sLegendStyle = getLegendStyle(_pInfo.sPointStyles[nCurrentStyle]);
1589 }
1590 else
1591 sLegendStyle = getLegendStyle(_pInfo.sPointStyles[nCurrentStyle]);
1592 }
1593
1594 nLegends++;
1595 _graph->AddLegend(fromSystemCodePage(replaceToTeX(sLegend.substr(1, sLegend.length() - 2))).c_str(), sLegendStyle.c_str());
1596 }
1597
1598 if (nCurrentStyle == _pInfo.nStyleMax - 1)
1599 nCurrentStyle = 0;
1600 else
1601 nCurrentStyle++;
1602 }
1603
1605 && n+nDataOffset+1 < (int)m_manager.assets.size()
1607 n++;
1608
1609 if (getNN(_mData2[0]) && _pData.getSettings(PlotData::LOG_REGION))
1611
1613 {
1614 if (!useImag)
1615 {
1616 useImag = true;
1617 n--;
1618 }
1619 else
1620 {
1621 useImag = false;
1622 n += nDataOffset;
1623 }
1624 }
1625 else
1626 n += nDataOffset;
1627 }
1628
1629 double AutoRangeX = _pData.getLogscale(XRANGE) ? log10(_pInfo.ranges[XRANGE].range()) : _pInfo.ranges[XRANGE].range();
1630 double AutoRangeY = _pData.getLogscale(YRANGE) ? log10(_pInfo.ranges[YRANGE].range()) : _pInfo.ranges[YRANGE].range();
1631
1632 for (const Line& line : _pData.getHLines())
1633 {
1634 if (!line.sDesc.length())
1635 continue;
1636
1637 double xpos = _pInfo.ranges[XRANGE].min() + 0.03 * AutoRangeX;
1638 double ypos = line.dPos + 0.01 * AutoRangeY;
1639
1640 _graph->Line(mglPoint(_pInfo.ranges[XRANGE].min(), line.dPos), mglPoint(_pInfo.ranges[XRANGE].max(), line.dPos), line.sStyle.c_str(), 100);
1641 _graph->Puts(xpos, ypos, fromSystemCodePage(line.sDesc).c_str(), ":kL");
1642 }
1643
1644 for (const Line& line : _pData.getVLines())
1645 {
1646 if (!line.sDesc.length())
1647 continue;
1648
1649 mglPoint textpos = mglPoint(line.dPos - 0.01 * AutoRangeX,
1650 _pInfo.ranges[YRANGE].min() + 0.05 * AutoRangeY);
1651 mglPoint textdir = mglPoint(line.dPos - 0.01 * AutoRangeX,
1652 _pInfo.ranges[YRANGE].max());
1653
1654 _graph->Line(mglPoint(line.dPos, _pInfo.ranges[YRANGE].min()), mglPoint(line.dPos, _pInfo.ranges[YRANGE].max()), line.sStyle.c_str());
1655 _graph->Puts(textpos, textdir, fromSystemCodePage(line.sDesc).c_str(), ":kL");
1656 }
1657
1658 if (nLegends && !_pData.getSettings(PlotData::LOG_SCHEMATIC) && nPlotCompose + 1 == nPlotComposeSize)
1660}
1661
1662
1675bool Plot::plotstd(mglData& _mData, mglData& _mAxisVals, mglData _mData2[2], const short nType)
1676{
1677#warning NOTE (numere#3#08/15/21): Temporary fix for MathGL misbehaviour
1685 {
1686 _mData = duplicatePoints(_mData);
1687 _mAxisVals = duplicatePoints(_mAxisVals);
1688 _mData2[0] = duplicatePoints(_mData2[0]);
1689 _mData2[1] = duplicatePoints(_mData2[1]);
1690 }
1691
1692 int nNextStyle = _pInfo.nextStyle();
1693
1694 if (nType == PT_FUNCTION)
1695 {
1696 if (_pData.getSettings(PlotData::LOG_REGION) && getNN(_mData2[0]) > 1) // Default region plot
1697 {
1698 _graph->Region(_mAxisVals, _mData, _mData2[0],
1699 ("a{" + _pData.getColors().substr(_pInfo.nStyle, 1) + "7}{" + _pData.getColors().substr(nNextStyle, 1) + "7}").c_str());
1700 _graph->Plot(_mAxisVals, _mData,
1701 ("a" + _pInfo.sLineStyles[_pInfo.nStyle]).c_str());
1702 _graph->Plot(_mAxisVals, _mData2[0],
1703 ("a" + _pInfo.sLineStyles[nNextStyle]).c_str());
1704 }
1705 else if (_pData.getSettings(PlotData::LOG_AREA) || _pData.getSettings(PlotData::LOG_REGION)) // Fallback for region with only single plot
1706 _graph->Area(_mAxisVals, _mData,
1707 ("a" + _pInfo.sLineStyles[_pInfo.nStyle] + "{" + _pData.getColors()[_pInfo.nStyle] + "9}").c_str());
1708 else
1709 _graph->Plot(_mAxisVals, _mData, ("a" + _pInfo.sLineStyles[_pInfo.nStyle]).c_str());
1710 }
1711 else
1712 {
1714 _graph->BoxPlot(_mData2[0], _mData,
1715 _pInfo.sLineStyles[_pInfo.nStyle].c_str());
1717 {
1719 {
1721 _graph->Bars(_mAxisVals, _mData,
1722 (composeColoursForBarChart(_mData.ny) + "^").c_str());
1723 else if (_pData.getSettings(PlotData::LOG_REGION) && getNN(_mData2[0]) > 1)
1724 {
1725 _graph->Region(_mAxisVals, _mData, _mData2[0],
1726 ("a{" + _pData.getColors().substr(_pInfo.nStyle, 1) + "7}{" + _pData.getColors().substr(nNextStyle, 1) + "7}").c_str());
1727 _graph->Plot(_mAxisVals, _mData,
1728 ("a" + _pInfo.sLineStyles[_pInfo.nStyle]).c_str());
1729 _graph->Plot(_mAxisVals, _mData2[0],
1730 ("a" + _pInfo.sLineStyles[nNextStyle]).c_str());
1731 }
1733 _graph->Area(_mAxisVals, _mData,
1734 ("a" + _pInfo.sLineStyles[_pInfo.nStyle] + "{" + _pData.getColors()[_pInfo.nStyle] + "9}").c_str());
1736 _graph->Step(_mAxisVals, _mData,
1737 (_pInfo.sLineStyles[_pInfo.nStyle]).c_str());
1738 else
1739 _graph->Plot(_mAxisVals, _mData,
1740 ("a" + expandStyleForCurveArray(_pInfo.sLineStyles[_pInfo.nStyle], _mData.ny > 1)).c_str());
1741 }
1744 {
1746 _graph->Bars(_mAxisVals, _mData,
1747 (composeColoursForBarChart(_mData.ny) + "^").c_str());
1749 _graph->Step(_mAxisVals, _mData,
1750 (_pInfo.sLineStyles[_pInfo.nStyle]).c_str());
1752 _graph->Area(_mAxisVals, _mData,
1753 ("a" + _pInfo.sLineStyles[_pInfo.nStyle] + "{" + _pData.getColors()[_pInfo.nStyle] + "9}").c_str());
1754 else
1755 _graph->Plot(_mAxisVals, _mData,
1756 ("a" + expandStyleForCurveArray(_pInfo.sConPointStyles[_pInfo.nStyle], _mData.ny > 1)).c_str());
1757 }
1758 else
1759 {
1760
1762 _graph->Bars(_mAxisVals, _mData,
1763 (composeColoursForBarChart(_mData.ny) + "^").c_str());
1765 _graph->Barh(_mAxisVals, _mData,
1766 (composeColoursForBarChart(_mData.ny) + "^").c_str());
1768 _graph->Step(_mAxisVals, _mData,
1769 (_pInfo.sLineStyles[_pInfo.nStyle]).c_str());
1771 _graph->Stem(_mAxisVals, _mData,
1773 else
1774 _graph->Plot(_mAxisVals, _mData,
1775 ("a" + expandStyleForCurveArray(_pInfo.sPointStyles[_pInfo.nStyle], _mData.ny > 1)).c_str());
1776 }
1777 }
1778 else
1779 _graph->Error(_mAxisVals, _mData, _mData2[0], _mData2[1],
1780 _pInfo.sPointStyles[_pInfo.nStyle].c_str());
1781 }
1782
1783 return true;
1784}
1785
1786
1795{
1796 static const std::string slicesStyleChars[3] = {"x", "", "z"};
1797
1798 if (sFunc.length())
1799 {
1800 mglData _mContVec(15);
1801 IntervalSet dataInterval = m_manager.assets[0].getDataIntervals();
1802 m_manager.weightedRange(ALLRANGES, dataInterval[0]);
1803
1804 // Apply curvilinear coordinates
1806
1807 if (!isnan(_pInfo.ranges[CRANGE].front()))
1808 dataInterval[0] = _pInfo.ranges[CRANGE];
1809
1810 for (int nCont = 0; nCont < 15; nCont++)
1811 {
1812 _mContVec.a[nCont] = dataInterval[0](nCont, 15).real();
1813 }
1814
1815 _mContVec.a[7] = dataInterval[0].middle();
1816
1817 mglData& _mData = m_manager.assets[0].data[0].first;
1818
1820 && _pInfo.sCommand.substr(0, 4) != "cont"
1821 && _pInfo.sCommand.substr(0, 4) != "grad"
1822 && (_pInfo.sCommand.substr(0, 4) != "dens" || (_pInfo.sCommand.substr(0, 4) == "dens" && _pData.getSettings(PlotData::LOG_CLOUDPLOT))))
1823 {
1826 }
1827
1828 // --> Entsprechend dem gewuenschten Plotting-Style plotten <--
1829 if (_pInfo.sCommand.substr(0, 4) == "mesh")
1830 {
1831 _graph->Surf3(m_manager.assets[0].axes[XCOORD],
1832 m_manager.assets[0].axes[YCOORD],
1833 m_manager.assets[0].axes[ZCOORD],
1834 _mData,
1835 _pData.getColorScheme("#").c_str(),
1836 "value 11");
1837
1838 if (m_manager.assets[0].isComplex(0))
1839 _graph->Surf3(m_manager.assets[0].axes[XCOORD],
1840 m_manager.assets[0].axes[YCOORD],
1841 m_manager.assets[0].axes[ZCOORD],
1842 m_manager.assets[0].data[0].second,
1843 _pData.getColorScheme("#").c_str(),
1844 "value 11");
1845 }
1846 else if (_pInfo.sCommand.substr(0, 4) == "surf" && !_pData.getSettings(PlotData::LOG_ALPHA))
1847 {
1848 _graph->Surf3(m_manager.assets[0].axes[XCOORD],
1849 m_manager.assets[0].axes[YCOORD],
1850 m_manager.assets[0].axes[ZCOORD],
1851 _mData,
1852 _pData.getColorScheme().c_str(),
1853 "value 11");
1854
1855 if (m_manager.assets[0].isComplex(0))
1856 _graph->Surf3(m_manager.assets[0].axes[XCOORD],
1857 m_manager.assets[0].axes[YCOORD],
1858 m_manager.assets[0].axes[ZCOORD],
1859 m_manager.assets[0].data[0].second,
1860 _pData.getColorScheme().c_str(),
1861 "value 11");
1862 }
1863 else if (_pInfo.sCommand.substr(0, 4) == "surf" && _pData.getSettings(PlotData::LOG_ALPHA))
1864 {
1865 _graph->Surf3A(m_manager.assets[0].axes[XCOORD],
1866 m_manager.assets[0].axes[YCOORD],
1867 m_manager.assets[0].axes[ZCOORD],
1868 _mData,
1869 _mData,
1870 _pData.getColorScheme().c_str(),
1871 "value 11");
1872
1873 if (m_manager.assets[0].isComplex(0))
1874 _graph->Surf3A(m_manager.assets[0].axes[XCOORD],
1875 m_manager.assets[0].axes[YCOORD],
1876 m_manager.assets[0].axes[ZCOORD],
1877 m_manager.assets[0].data[0].second,
1878 m_manager.assets[0].data[0].second,
1879 _pData.getColorScheme().c_str(),
1880 "value 11");
1881 }
1882 else if (_pInfo.sCommand.substr(0, 4) == "cont")
1883 {
1885 {
1887 {
1888 _graph->ContFX(_mContVec, _mData.Sum("x"), _pData.getColorScheme().c_str(), getProjBackground(_pData.getRotateAngle(1)));
1889 _graph->ContFY(_mContVec, _mData.Sum("y"), _pData.getColorScheme().c_str(), getProjBackground(_pData.getRotateAngle(1),1));
1890 _graph->ContFZ(_mContVec, _mData.Sum("z"), _pData.getColorScheme().c_str(), _pInfo.ranges[ZRANGE].min());
1891 _graph->ContX(_mContVec, _mData.Sum("x"), "k", getProjBackground(_pData.getRotateAngle(1)));
1892 _graph->ContY(_mContVec, _mData.Sum("y"), "k", getProjBackground(_pData.getRotateAngle(1), 1));
1893 _graph->ContZ(_mContVec, _mData.Sum("z"), "k", _pInfo.ranges[ZRANGE].min());
1894 }
1895 else
1896 {
1897 _graph->ContX(_mContVec, _mData.Sum("x"), _pData.getColorScheme().c_str(), getProjBackground(_pData.getRotateAngle(1)));
1898 _graph->ContY(_mContVec, _mData.Sum("y"), _pData.getColorScheme().c_str(), getProjBackground(_pData.getRotateAngle(1), 1));
1899 _graph->ContZ(_mContVec, _mData.Sum("z"), _pData.getColorScheme().c_str(), _pInfo.ranges[ZRANGE].min());
1900 }
1901 }
1903 {
1904 for (int i = XCOORD; i <= ZCOORD; i++)
1905 {
1906 for (unsigned short n = 0; n < _pData.getSlices(i); n++)
1907 {
1908 _graph->ContF3(_mContVec,
1909 m_manager.assets[0].axes[XCOORD],
1910 m_manager.assets[0].axes[YCOORD],
1911 m_manager.assets[0].axes[ZCOORD],
1912 _mData,
1913 _pData.getColorScheme(slicesStyleChars[i]).c_str(),
1914 (n + 1)*_pInfo.nSamples / (_pData.getSlices(i) + 1));
1915 _graph->Cont3(_mContVec,
1916 m_manager.assets[0].axes[XCOORD],
1917 m_manager.assets[0].axes[YCOORD],
1918 m_manager.assets[0].axes[ZCOORD],
1919 _mData,
1920 ("k" + slicesStyleChars[i]).c_str(),
1921 (n + 1)*_pInfo.nSamples / (_pData.getSlices() + 1));
1922 }
1923 }
1924 }
1925 else
1926 {
1927 for (int i = XCOORD; i <= ZCOORD; i++)
1928 {
1929 for (unsigned short n = 0; n < _pData.getSlices(i); n++)
1930 _graph->Cont3(_mContVec,
1931 m_manager.assets[0].axes[XCOORD],
1932 m_manager.assets[0].axes[YCOORD],
1933 m_manager.assets[0].axes[ZCOORD],
1934 _mData,
1935 _pData.getColorScheme(slicesStyleChars[i]).c_str(),
1936 (n + 1)*_pInfo.nSamples / (_pData.getSlices(i) + 1));
1937 }
1938 }
1939 }
1940 else if (_pInfo.sCommand.substr(0, 4) == "grad")
1941 {
1943 {
1945 _graph->Grad(m_manager.assets[0].axes[XCOORD],
1946 m_manager.assets[0].axes[YCOORD],
1947 m_manager.assets[0].axes[ZCOORD],
1948 _mData,
1949 _pData.getColorSchemeMedium().c_str(),
1950 "value 10");
1951 else
1952 _graph->Grad(m_manager.assets[0].axes[XCOORD],
1953 m_manager.assets[0].axes[YCOORD],
1954 m_manager.assets[0].axes[ZCOORD],
1955 _mData,
1956 _pData.getColorScheme().c_str(),
1957 "value 10");
1958 }
1959 else
1960 {
1962 _graph->Grad(m_manager.assets[0].axes[XCOORD],
1963 m_manager.assets[0].axes[YCOORD],
1964 m_manager.assets[0].axes[ZCOORD],
1965 _mData,
1966 _pData.getColorSchemeMedium().c_str());
1967 else
1968 _graph->Grad(m_manager.assets[0].axes[XCOORD],
1969 m_manager.assets[0].axes[YCOORD],
1970 m_manager.assets[0].axes[ZCOORD],
1971 _mData,
1972 _pData.getColorScheme().c_str());
1973 }
1974
1976 {
1977 for (int i = XCOORD; i <= ZCOORD; i++)
1978 {
1979 _graph->Dens3(m_manager.assets[0].axes[XCOORD],
1980 m_manager.assets[0].axes[YCOORD],
1981 m_manager.assets[0].axes[ZCOORD],
1982 _mData,
1983 _pData.getColorSchemeLight(slicesStyleChars[i]).c_str(),
1984 _pInfo.nSamples / 2);
1985 }
1986 }
1987 }
1988 else if (_pInfo.sCommand.substr(0, 4) == "dens")
1989 {
1992 {
1993 for (int i = XCOORD; i <= ZCOORD; i++)
1994 {
1995 for (unsigned short n = 0; n < _pData.getSlices(i); n++)
1996 _graph->Dens3(m_manager.assets[0].axes[XCOORD],
1997 m_manager.assets[0].axes[YCOORD],
1998 m_manager.assets[0].axes[ZCOORD],
1999 _mData,
2000 _pData.getColorScheme(slicesStyleChars[i]).c_str(),
2001 (n + 1)*_pInfo.nSamples / (_pData.getSlices(i) + 1));
2002 }
2003 }
2006 _graph->Cloud(m_manager.assets[0].axes[XCOORD],
2007 m_manager.assets[0].axes[YCOORD],
2008 m_manager.assets[0].axes[ZCOORD],
2009 _mData,
2010 _pData.getColorScheme().c_str());
2011 }
2012 else
2013 {
2014 clearData();
2015 return;
2016 }
2017
2019 && _pInfo.sCommand.substr(0, 4) != "cont"
2020 && _pInfo.sCommand.substr(0, 4) != "grad"
2021 && (_pInfo.sCommand.substr(0, 4) != "dens" || (_pInfo.sCommand.substr(0, 4) == "dens" && _pData.getSettings(PlotData::LOG_CLOUDPLOT))))
2022 _graph->SetCutBox(mglPoint(0), mglPoint(0));
2023
2024 // --> Ggf. Konturlinien ergaenzen <--
2025 if (_pData.getSettings(PlotData::LOG_CONTPROJ) && _pInfo.sCommand.substr(0, 4) != "cont")
2026 {
2028 && (_pInfo.sCommand.substr(0, 4) != "dens" && _pInfo.sCommand.substr(0, 4) != "grad"))
2029 {
2030 _graph->ContFX(_mContVec, _mData.Sum("x"), _pData.getColorScheme().c_str(), getProjBackground(_pData.getRotateAngle(1)));
2031 _graph->ContFY(_mContVec, _mData.Sum("y"), _pData.getColorScheme().c_str(), getProjBackground(_pData.getRotateAngle(1), 1));
2032 _graph->ContFZ(_mContVec, _mData.Sum("z"), _pData.getColorScheme().c_str(), _pInfo.ranges[ZRANGE].min());
2033 _graph->ContX(_mContVec, _mData.Sum("x"), "k", getProjBackground(_pData.getRotateAngle(1)));
2034 _graph->ContY(_mContVec, _mData.Sum("y"), "k", getProjBackground(_pData.getRotateAngle(1), 1));
2035 _graph->ContZ(_mContVec, _mData.Sum("z"), "k", _pInfo.ranges[ZRANGE].min());
2036 }
2037 else if ((_pInfo.sCommand.substr(0, 4) == "dens" || _pInfo.sCommand.substr(0, 4) == "grad")
2039 {
2040 if (_pInfo.sCommand == "dens")
2041 {
2042 _graph->DensX(_mData.Sum("x"), _pData.getColorScheme().c_str(), getProjBackground(_pData.getRotateAngle(1)));
2043 _graph->DensY(_mData.Sum("y"), _pData.getColorScheme().c_str(), getProjBackground(_pData.getRotateAngle(1), 1));
2044 _graph->DensZ(_mData.Sum("z"), _pData.getColorScheme().c_str(), _pInfo.ranges[ZRANGE].min());
2045 }
2046 else
2047 {
2048 _graph->DensX(_mData.Sum("x"), _pData.getColorSchemeLight().c_str(), getProjBackground(_pData.getRotateAngle(1)));
2049 _graph->DensY(_mData.Sum("y"), _pData.getColorSchemeLight().c_str(), getProjBackground(_pData.getRotateAngle(1), 1));
2050 _graph->DensZ(_mData.Sum("z"), _pData.getColorSchemeLight().c_str(), _pInfo.ranges[ZRANGE].min());
2051 }
2052
2053 _graph->ContX(_mContVec, _mData.Sum("x"), "k", getProjBackground(_pData.getRotateAngle(1)));
2054 _graph->ContY(_mContVec, _mData.Sum("y"), "k", getProjBackground(_pData.getRotateAngle(1), 1));
2055 _graph->ContZ(_mContVec, _mData.Sum("z"), "k", _pInfo.ranges[ZRANGE].min());
2056 }
2057 else
2058 {
2059 _graph->ContX(_mContVec, _mData.Sum("x"), _pData.getColorScheme().c_str(), getProjBackground(_pData.getRotateAngle(1)));
2060 _graph->ContY(_mContVec, _mData.Sum("y"), _pData.getColorScheme().c_str(), getProjBackground(_pData.getRotateAngle(1), 1));
2061 _graph->ContZ(_mContVec, _mData.Sum("z"), _pData.getColorScheme().c_str(), _pInfo.ranges[ZRANGE].min());
2062 }
2063 }
2064 }
2065}
2066
2067
2077{
2078 if (sFunc.length())
2079 {
2081 {
2084 }
2085
2086 for (size_t i = 0; i < m_manager.assets.size(); i++)
2087 {
2088 mglData& _mData_x = m_manager.assets[i].data[XCOORD].first;
2089 mglData& _mData_y = m_manager.assets[i].data[YCOORD].first;
2090 mglData& _mData_z = m_manager.assets[i].data[ZCOORD].first;
2091
2092 // --> Entsprechend dem gewuenschten Plotting-Style plotten <--
2094 _graph->Flow(_mData_x, _mData_y, _mData_z, _pData.getColorScheme("v").c_str());
2096 _graph->Pipe(_mData_x, _mData_y, _mData_z, _pData.getColorScheme().c_str());
2098 _graph->Vect(_mData_x, _mData_y, _mData_z, _pData.getColorScheme("f").c_str());
2100 _graph->Vect(_mData_x, _mData_y, _mData_z, _pData.getColorScheme().c_str());
2101 else
2102 {
2103 // --> Den gibt's nicht: Speicher freigeben und zurueck! <--
2104 clearData();
2105 return;
2106 }
2107 }
2108
2110 _graph->SetCutBox(mglPoint(0), mglPoint(0));
2111 }
2112}
2113
2114
2123{
2124 mglData* _mData_x = nullptr;
2125 mglData* _mData_y = nullptr;
2126
2127 for (size_t i = 0; i < m_manager.assets.size(); i++)
2128 {
2129 if (!m_manager.assets[i].isComplex(0) && m_manager.assets[i].type == PT_FUNCTION)
2130 {
2131 _mData_x = &m_manager.assets[i].data[XCOORD].first;
2132 _mData_y = &m_manager.assets[i].data[YCOORD].first;
2133 }
2134 else
2135 {
2136 _mData_x = &m_manager.assets[i].data[XCOORD].first;
2137 _mData_y = &m_manager.assets[i].data[XCOORD].second;
2138 }
2139
2140 // --> Entsprechend dem gewuenschten Plotting-Style plotten <--
2142 _graph->Flow(*_mData_x, *_mData_y, _pData.getColorScheme("v").c_str());
2144 _graph->Pipe(*_mData_x, *_mData_y, _pData.getColorScheme().c_str());
2146 _graph->Vect(*_mData_x, *_mData_y, _pData.getColorScheme("f").c_str());
2148 _graph->Vect(*_mData_x, *_mData_y, _pData.getColorScheme().c_str());
2149 else
2150 {
2151 // --> Den gibt's nicht: Speicher freigeben und zurueck! <--
2152 clearData();
2153 return;
2154 }
2155 }
2156}
2157
2158
2167void Plot::create2dDrawing(vector<string>& vDrawVector)
2168{
2169 int nFunctions;
2170 string sStyle;
2171 string sTextString;
2172 string sDrawExpr;
2173 string sCurrentDrawingFunction;
2174 string sDummy;
2175
2176 for (unsigned int v = 0; v < vDrawVector.size(); v++)
2177 {
2178 sStyle = "k";
2179 sTextString = "";
2180 sDrawExpr = "";
2181 sCurrentDrawingFunction = vDrawVector[v];
2182 if (NumeReKernel::getInstance()->getStringParser().isStringExpression(sCurrentDrawingFunction))
2183 {
2184 for (int n = (int)sCurrentDrawingFunction.length() - 1; n >= 0; n--)
2185 {
2186 if (sCurrentDrawingFunction[n] == ',' && !isInQuotes(sCurrentDrawingFunction, (unsigned)n, true))
2187 {
2188 sStyle = sCurrentDrawingFunction.substr(n + 1);
2189 sCurrentDrawingFunction.erase(n);
2190
2191 break;
2192 }
2193 }
2194 sStyle = sStyle.substr(0, sStyle.rfind(')')) + " -nq";
2195 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sStyle, sDummy, true);
2196 }
2197 if (NumeReKernel::getInstance()->getStringParser().isStringExpression(sCurrentDrawingFunction))
2198 {
2199 for (int n = (int)sCurrentDrawingFunction.length() - 1; n >= 0; n--)
2200 {
2201 if (sCurrentDrawingFunction[n] == ',' && !isInQuotes(sCurrentDrawingFunction, (unsigned)n, true))
2202 {
2203 sTextString = sCurrentDrawingFunction.substr(n + 1);
2204 sCurrentDrawingFunction.erase(n);
2205
2206 break;
2207 }
2208 }
2209 sTextString += " -nq";
2210 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sTextString, sDummy, true);
2211 }
2212 if (sCurrentDrawingFunction.back() == ')')
2213 sDrawExpr = sCurrentDrawingFunction.substr(sCurrentDrawingFunction.find('(') + 1, sCurrentDrawingFunction.rfind(')') - sCurrentDrawingFunction.find('(') - 1);
2214 else
2215 sDrawExpr = sCurrentDrawingFunction.substr(sCurrentDrawingFunction.find('(') + 1);
2216 if (sDrawExpr.find('{') != string::npos)
2218 _parser.SetExpr(sDrawExpr);
2219 mu::value_type* vRes = _parser.Eval(nFunctions);
2220 std::vector<double> vResults = real({vRes, vRes+nFunctions});
2221
2222 if (sCurrentDrawingFunction.substr(0, 6) == "trace(" || sCurrentDrawingFunction.substr(0, 5) == "line(")
2223 {
2224 if (nFunctions < 2)
2225 continue;
2226 if (nFunctions < 4)
2227 _graph->Line(mglPoint(), mglPoint(vResults[0], vResults[1]), sStyle.c_str());
2228 else
2229 _graph->Line(mglPoint(vResults[0], vResults[1]), mglPoint(vResults[2], vResults[3]), sStyle.c_str());
2230 }
2231 else if (sCurrentDrawingFunction.substr(0, 7) == "tracev(" || sCurrentDrawingFunction.substr(0, 6) == "linev(")
2232 {
2233 if (nFunctions < 2)
2234 continue;
2235 if (nFunctions < 4)
2236 _graph->Line(mglPoint(), mglPoint(vResults[0], vResults[1]), sStyle.c_str());
2237 else
2238 _graph->Line(mglPoint(vResults[0], vResults[1]), mglPoint(vResults[0] + vResults[2], vResults[1] + vResults[3]), sStyle.c_str());
2239 }
2240 else if (sCurrentDrawingFunction.substr(0, 5) == "face(" || sCurrentDrawingFunction.substr(0, 7) == "cuboid(")
2241 {
2242 if (nFunctions < 4)
2243 continue;
2244 if (nFunctions < 6)
2245 _graph->Face(mglPoint(vResults[2] - vResults[3] + vResults[1], vResults[3] + vResults[2] - vResults[0]),
2246 mglPoint(vResults[2], vResults[3]),
2247 mglPoint(vResults[0] - vResults[3] + vResults[1], vResults[1] + vResults[2] - vResults[0]),
2248 mglPoint(vResults[0], vResults[1]),
2249 sStyle.c_str());
2250 else if (nFunctions < 8)
2251 _graph->Face(mglPoint(vResults[4], vResults[5]),
2252 mglPoint(vResults[2], vResults[3]),
2253 mglPoint(vResults[0] + vResults[4] - vResults[2], vResults[1] + vResults[5] - vResults[3]),
2254 mglPoint(vResults[0], vResults[1]),
2255 sStyle.c_str());
2256 else
2257 _graph->Face(mglPoint(vResults[4], vResults[5]),
2258 mglPoint(vResults[2], vResults[3]),
2259 mglPoint(vResults[6], vResults[7]),
2260 mglPoint(vResults[0], vResults[1]),
2261 sStyle.c_str());
2262 }
2263 else if (sCurrentDrawingFunction.substr(0, 6) == "facev(")
2264 {
2265 if (nFunctions < 4)
2266 continue;
2267 if (nFunctions < 6)
2268 _graph->Face(mglPoint(vResults[0] + vResults[2] - vResults[3], vResults[1] + vResults[3] + vResults[2]),
2269 mglPoint(vResults[0] + vResults[2], vResults[1] + vResults[3]),
2270 mglPoint(vResults[0] - vResults[3], vResults[1] + vResults[2]),
2271 mglPoint(vResults[0], vResults[1]),
2272 sStyle.c_str());
2273 else if (nFunctions < 8)
2274 _graph->Face(mglPoint(vResults[0] + vResults[4] + vResults[2], vResults[1] + vResults[3] + vResults[5]),
2275 mglPoint(vResults[0] + vResults[2], vResults[1] + vResults[3]),
2276 mglPoint(vResults[0] + vResults[4], vResults[1] + vResults[5]),
2277 mglPoint(vResults[0], vResults[1]),
2278 sStyle.c_str());
2279 else
2280 _graph->Face(mglPoint(vResults[0] + vResults[4], vResults[1] + vResults[5]),
2281 mglPoint(vResults[0] + vResults[2], vResults[1] + vResults[3]),
2282 mglPoint(vResults[0] + vResults[6], vResults[1] + vResults[7]),
2283 mglPoint(vResults[0], vResults[1]),
2284 sStyle.c_str());
2285 }
2286 else if (sCurrentDrawingFunction.substr(0, 9) == "triangle(")
2287 {
2288 if (nFunctions < 4)
2289 continue;
2290 double c = hypot(vResults[2] - vResults[0], vResults[3] - vResults[1]) / 2.0 * sqrt(3) / hypot(vResults[2], vResults[3]);
2291 if (nFunctions < 6)
2292 _graph->Face(mglPoint((-vResults[0] + vResults[2]) / 2.0 - c * vResults[3], (-vResults[1] + vResults[3]) / 2.0 + c * vResults[2]),
2293 mglPoint(vResults[2], vResults[3]),
2294 mglPoint((-vResults[0] + vResults[2]) / 2.0 - c * vResults[3], (-vResults[1] + vResults[3]) / 2.0 + c * vResults[2]),
2295 mglPoint(vResults[0], vResults[1]),
2296 sStyle.c_str());
2297 else
2298 _graph->Face(mglPoint(vResults[4], vResults[5]),
2299 mglPoint(vResults[2], vResults[3]),
2300 mglPoint(vResults[4], vResults[5]),
2301 mglPoint(vResults[0], vResults[1]),
2302 sStyle.c_str());
2303 }
2304 else if (sCurrentDrawingFunction.substr(0, 10) == "trianglev(")
2305 {
2306 if (nFunctions < 4)
2307 continue;
2308 double c = sqrt(3.0) / 2.0;
2309 if (nFunctions < 6)
2310 _graph->Face(mglPoint((vResults[0] + 0.5 * vResults[2]) - c * vResults[3], (vResults[1] + 0.5 * vResults[3]) + c * vResults[2]),
2311 mglPoint(vResults[0] + vResults[2], vResults[1] + vResults[3]),
2312 mglPoint((vResults[0] + 0.5 * vResults[2]) - c * vResults[3], (vResults[1] + 0.5 * vResults[3]) + c * vResults[2]),
2313 mglPoint(vResults[0], vResults[1]),
2314 sStyle.c_str());
2315 else
2316 _graph->Face(mglPoint(vResults[0] + vResults[4], vResults[1] + vResults[5]),
2317 mglPoint(vResults[0] + vResults[2], vResults[1] + vResults[3]),
2318 mglPoint(vResults[0] + vResults[4], vResults[1] + vResults[5]),
2319 mglPoint(vResults[0], vResults[1]),
2320 sStyle.c_str());
2321 }
2322 else if (sCurrentDrawingFunction.substr(0, 7) == "sphere(")
2323 {
2324 if (nFunctions < 3)
2325 continue;
2326 _graph->Sphere(mglPoint(vResults[0], vResults[1]), vResults[2], sStyle.c_str());
2327 }
2328 else if (sCurrentDrawingFunction.substr(0, 5) == "drop(")
2329 {
2330 if (nFunctions < 5)
2331 continue;
2332 double dShift = 1;
2333 double dAspherity = 1;
2334 if (nFunctions >= 6)
2335 dShift = vResults[5];
2336 if (nFunctions >= 7)
2337 dAspherity = vResults[6];
2338 _graph->Drop(mglPoint(vResults[0], vResults[1]),
2339 mglPoint(vResults[2], vResults[3]),
2340 vResults[4],
2341 sStyle.c_str(),
2342 dShift,
2343 dAspherity);
2344 }
2345 else if (sCurrentDrawingFunction.substr(0, 7) == "circle(")
2346 {
2347 if (nFunctions < 3)
2348 continue;
2349 _graph->Circle(mglPoint(vResults[0], vResults[1]), vResults[2], sStyle.c_str());
2350 }
2351 else if (sCurrentDrawingFunction.substr(0, 4) == "arc(")
2352 {
2353 if (nFunctions < 5)
2354 continue;
2355 _graph->Arc(mglPoint(vResults[0], vResults[1]), mglPoint(vResults[2], vResults[3]), vResults[4], sStyle.c_str());
2356 }
2357 else if (sCurrentDrawingFunction.substr(0, 5) == "arcv(")
2358 {
2359 if (nFunctions < 5)
2360 continue;
2361 _graph->Arc(mglPoint(vResults[0], vResults[1]), mglPoint(vResults[2] + vResults[0], vResults[3] + vResults[1]), vResults[4], sStyle.c_str());
2362 }
2363 else if (sCurrentDrawingFunction.substr(0, 6) == "point(")
2364 {
2365 if (nFunctions < 2)
2366 continue;
2367 _graph->Mark(mglPoint(vResults[0], vResults[1]), sStyle.c_str());
2368 }
2369 else if (sCurrentDrawingFunction.substr(0, 6) == "curve(")
2370 {
2371 if (nFunctions < 8)
2372 continue;
2373 _graph->Curve(mglPoint(vResults[0], vResults[1]),
2374 mglPoint(vResults[2], vResults[3]),
2375 mglPoint(vResults[4], vResults[5]),
2376 mglPoint(vResults[6], vResults[7]), sStyle.c_str());
2377 }
2378 else if (sCurrentDrawingFunction.substr(0, 8) == "ellipse(")
2379 {
2380 if (nFunctions < 5)
2381 continue;
2382 _graph->Ellipse(mglPoint(vResults[0], vResults[1]), mglPoint(vResults[2], vResults[3]), vResults[4], sStyle.c_str());
2383 }
2384 else if (sCurrentDrawingFunction.substr(0, 9) == "ellipsev(")
2385 {
2386 if (nFunctions < 5)
2387 continue;
2388 _graph->Ellipse(mglPoint(vResults[0], vResults[1]), mglPoint(vResults[2] + vResults[0], vResults[3] + vResults[1]), vResults[4], sStyle.c_str());
2389 }
2390 else if (sCurrentDrawingFunction.substr(0, 5) == "text(")
2391 {
2392 if (!sTextString.length())
2393 {
2394 sTextString = sStyle;
2395 sStyle = "k";
2396 }
2397 if (nFunctions >= 4)
2398 _graph->Puts(mglPoint(vResults[0], vResults[1]), mglPoint(vResults[2], vResults[3]), sTextString.c_str(), sStyle.c_str());
2399 else if (nFunctions >= 2)
2400 _graph->Puts(mglPoint(vResults[0], vResults[1]), sTextString.c_str(), sStyle.c_str());
2401 else
2402 continue;
2403 }
2404 else if (sCurrentDrawingFunction.substr(0, 8) == "polygon(")
2405 {
2406 if (nFunctions < 5 || vResults[4] < 3)
2407 continue;
2408 _graph->Polygon(mglPoint(vResults[0], vResults[1]), mglPoint(vResults[2], vResults[3]), (int)vResults[4], sStyle.c_str());
2409 }
2410 else if (sCurrentDrawingFunction.substr(0, 9) == "polygonv(")
2411 {
2412 if (nFunctions < 5 || vResults[4] < 3)
2413 continue;
2414 _graph->Polygon(mglPoint(vResults[0], vResults[1]), mglPoint(vResults[2] + vResults[0], vResults[3] + vResults[1]), (int)vResults[4], sStyle.c_str());
2415 }
2416 else
2417 continue;
2418 }
2419}
2420
2421
2430void Plot::create3dDrawing(vector<string>& vDrawVector)
2431{
2432 int nFunctions;
2433 string sStyle;
2434 string sTextString;
2435 string sDrawExpr;
2436 string sCurrentDrawingFunction;
2437 string sDummy;
2438
2439 for (unsigned int v = 0; v < vDrawVector.size(); v++)
2440 {
2441 sStyle = "k";
2442 sTextString = "";
2443 sDrawExpr = "";
2444 sCurrentDrawingFunction = vDrawVector[v];
2445 if (NumeReKernel::getInstance()->getStringParser().isStringExpression(sCurrentDrawingFunction))
2446 {
2447 for (int n = (int)sCurrentDrawingFunction.length() - 1; n >= 0; n--)
2448 {
2449 if (sCurrentDrawingFunction[n] == ',' && !isInQuotes(sCurrentDrawingFunction, (unsigned)n, true))
2450 {
2451 sStyle = sCurrentDrawingFunction.substr(n + 1);
2452 sCurrentDrawingFunction.erase(n);
2453
2454 break;
2455 }
2456 }
2457 sStyle = sStyle.substr(0, sStyle.rfind(')')) + " -nq";
2458 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sStyle, sDummy, true);
2459 }
2460 if (NumeReKernel::getInstance()->getStringParser().isStringExpression(sCurrentDrawingFunction))
2461 {
2462 for (int n = (int)sCurrentDrawingFunction.length() - 1; n >= 0; n--)
2463 {
2464 if (sCurrentDrawingFunction[n] == ',' && !isInQuotes(sCurrentDrawingFunction, (unsigned)n, true))
2465 {
2466 sTextString = sCurrentDrawingFunction.substr(n + 1);
2467 sCurrentDrawingFunction.erase(n);
2468
2469 break;
2470 }
2471 }
2472 sTextString += " -nq";
2473 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sTextString, sDummy, true);
2474 }
2475 if (sCurrentDrawingFunction.back() == ')')
2476 sDrawExpr = sCurrentDrawingFunction.substr(sCurrentDrawingFunction.find('(') + 1, sCurrentDrawingFunction.rfind(')') - sCurrentDrawingFunction.find('(') - 1);
2477 else
2478 sDrawExpr = sCurrentDrawingFunction.substr(sCurrentDrawingFunction.find('(') + 1);
2479 if (sDrawExpr.find('{') != string::npos)
2481 _parser.SetExpr(sDrawExpr);
2482 mu::value_type* vRes = _parser.Eval(nFunctions);
2483 std::vector<double> vResults = real({vRes, vRes+nFunctions});
2484 if (sCurrentDrawingFunction.substr(0, 6) == "trace(" || sCurrentDrawingFunction.substr(0, 5) == "line(")
2485 {
2486 if (nFunctions < 3)
2487 continue;
2488 if (nFunctions < 6)
2489 _graph->Line(mglPoint(), mglPoint(vResults[0], vResults[1], vResults[2]), sStyle.c_str());
2490 else
2491 _graph->Line(mglPoint(vResults[0], vResults[1], vResults[2]), mglPoint(vResults[3], vResults[4], vResults[5]), sStyle.c_str());
2492 }
2493 else if (sCurrentDrawingFunction.substr(0, 7) == "tracev(" || sCurrentDrawingFunction.substr(0, 6) == "linev(")
2494 {
2495 if (nFunctions < 3)
2496 continue;
2497 if (nFunctions < 6)
2498 _graph->Line(mglPoint(), mglPoint(vResults[0], vResults[1], vResults[2]), sStyle.c_str());
2499 else
2500 _graph->Line(mglPoint(vResults[0], vResults[1], vResults[2]), mglPoint(vResults[3] + vResults[0], vResults[4] + vResults[1], vResults[5] + vResults[2]), sStyle.c_str());
2501 }
2502 else if (sCurrentDrawingFunction.substr(0, 5) == "face(")
2503 {
2504 if (nFunctions < 6)
2505 continue;
2506 if (nFunctions < 9)
2507 _graph->Face(mglPoint(vResults[3] - vResults[4] + vResults[1], vResults[4] + vResults[3] - vResults[0], vResults[5]),
2508 mglPoint(vResults[0] + vResults[3], vResults[1] + vResults[4], vResults[2] + vResults[5]),
2509 mglPoint(vResults[0] - vResults[4] + vResults[1], vResults[1] + vResults[3] - vResults[0], vResults[2]),
2510 mglPoint(vResults[0], vResults[1], vResults[2]),
2511 sStyle.c_str());
2512 else if (nFunctions < 12)
2513 _graph->Face(mglPoint(vResults[6], vResults[7], vResults[8]),
2514 mglPoint(vResults[3], vResults[4], vResults[5]),
2515 mglPoint(vResults[0] + vResults[6] - vResults[3], vResults[1] + vResults[7] - vResults[4], vResults[2] + vResults[8] - vResults[5]),
2516 mglPoint(vResults[0], vResults[1], vResults[2]),
2517 sStyle.c_str());
2518 else
2519 _graph->Face(mglPoint(vResults[6], vResults[7], vResults[8]),
2520 mglPoint(vResults[3], vResults[4], vResults[5]),
2521 mglPoint(vResults[9], vResults[10], vResults[11]),
2522 mglPoint(vResults[0], vResults[1], vResults[2]),
2523 sStyle.c_str());
2524 }
2525 else if (sCurrentDrawingFunction.substr(0, 6) == "facev(")
2526 {
2527 if (nFunctions < 6)
2528 continue;
2529 if (nFunctions < 9)
2530 _graph->Face(mglPoint(vResults[0] + vResults[3] - vResults[4], vResults[1] + vResults[4] + vResults[3], vResults[5] + vResults[2]),
2531 mglPoint(vResults[0] + vResults[3], vResults[1] + vResults[4], vResults[5] + vResults[2]),
2532 mglPoint(vResults[0] - vResults[4], vResults[1] + vResults[3], vResults[2]),
2533 mglPoint(vResults[0], vResults[1], vResults[2]),
2534 sStyle.c_str());
2535 else if (nFunctions < 12)
2536 _graph->Face(mglPoint(vResults[0] + vResults[6] + vResults[3], vResults[1] + vResults[7] + vResults[4], vResults[2] + vResults[8] + vResults[5]),
2537 mglPoint(vResults[0] + vResults[6], vResults[1] + vResults[4], vResults[2] + vResults[5]),
2538 mglPoint(vResults[0] + vResults[3], vResults[1] + vResults[7], vResults[2] + vResults[8]),
2539 mglPoint(vResults[0], vResults[1], vResults[2]),
2540 sStyle.c_str());
2541 else
2542 _graph->Face(mglPoint(vResults[0] + vResults[6], vResults[1] + vResults[7], vResults[2] + vResults[8]),
2543 mglPoint(vResults[0] + vResults[3], vResults[1] + vResults[4], vResults[2] + vResults[5]),
2544 mglPoint(vResults[0] + vResults[9], vResults[1] + vResults[10], vResults[2] + vResults[11]),
2545 mglPoint(vResults[0], vResults[1], vResults[2]),
2546 sStyle.c_str());
2547 }
2548 else if (sCurrentDrawingFunction.substr(0, 9) == "triangle(")
2549 {
2550 if (nFunctions < 6)
2551 continue;
2552 double c = sqrt((vResults[3] - vResults[0]) * (vResults[3] - vResults[0])
2553 + (vResults[4] - vResults[1]) * (vResults[4] - vResults[1])
2554 + (vResults[5] - vResults[2]) * (vResults[5] - vResults[2])) / 2.0 * sqrt(3) / hypot(vResults[3], vResults[4]);
2555 if (nFunctions < 9)
2556 _graph->Face(mglPoint((-vResults[0] + vResults[3]) / 2.0 - c * vResults[4], (-vResults[1] + vResults[4]) / 2.0 + c * vResults[3], (vResults[5] + vResults[2]) / 2.0),
2557 mglPoint(vResults[3], vResults[4], vResults[5]),
2558 mglPoint((-vResults[0] + vResults[3]) / 2.0 - c * vResults[4], (-vResults[1] + vResults[4]) / 2.0 + c * vResults[3], (vResults[5] + vResults[2]) / 2.0),
2559 mglPoint(vResults[0], vResults[1], vResults[2]),
2560 sStyle.c_str());
2561 else
2562 _graph->Face(mglPoint(vResults[6], vResults[7], vResults[8]),
2563 mglPoint(vResults[3], vResults[4], vResults[5]),
2564 mglPoint(vResults[6], vResults[7], vResults[8]),
2565 mglPoint(vResults[0], vResults[1], vResults[2]),
2566 sStyle.c_str());
2567 }
2568 else if (sCurrentDrawingFunction.substr(0, 10) == "trianglev(")
2569 {
2570 if (nFunctions < 6)
2571 continue;
2572 double c = sqrt((vResults[3]) * (vResults[3])
2573 + (vResults[4]) * (vResults[4])
2574 + (vResults[5]) * (vResults[5])) / 2.0 * sqrt(3) / hypot(vResults[3], vResults[4]);
2575 if (nFunctions < 9)
2576 _graph->Face(mglPoint((vResults[0] + 0.5 * vResults[3]) - c * vResults[4], (vResults[1] + 0.5 * vResults[4]) + c * vResults[3], (vResults[5] + 0.5 * vResults[2])),
2577 mglPoint(vResults[0] + vResults[3], vResults[1] + vResults[4], vResults[2] + vResults[5]),
2578 mglPoint((vResults[0] + 0.5 * vResults[3]) - c * vResults[4], (vResults[1] + 0.5 * vResults[4]) + c * vResults[3], (vResults[5] + 0.5 * vResults[2])),
2579 mglPoint(vResults[0], vResults[1], vResults[2]),
2580 sStyle.c_str());
2581 else
2582 _graph->Face(mglPoint(vResults[0] + vResults[6], vResults[1] + vResults[7], vResults[2] + vResults[8]),
2583 mglPoint(vResults[0] + vResults[3], vResults[1] + vResults[4], vResults[2] + vResults[5]),
2584 mglPoint(vResults[0] + vResults[6], vResults[1] + vResults[7], vResults[2] + vResults[8]),
2585 mglPoint(vResults[0], vResults[1], vResults[2]),
2586 sStyle.c_str());
2587 }
2588 else if (sCurrentDrawingFunction.substr(0, 7) == "cuboid(")
2589 {
2590 if (nFunctions < 6)
2591 continue;
2592 mglPoint _mDx;
2593 mglPoint _mDy;
2594 mglPoint _mDz;
2595
2596 if (nFunctions < 9)
2597 {
2598 _mDx = mglPoint(vResults[3], vResults[4], vResults[5]);
2599 _mDy = mglPoint(-vResults[4], vResults[3], vResults[5]);
2600 _mDz = mglPoint(vResults[4] * vResults[5] - vResults[3] * vResults[5],
2601 -vResults[4] * vResults[5] - vResults[3] * vResults[5],
2602 vResults[3] * vResults[3] + vResults[4] * vResults[4])
2603 / sqrt(vResults[3] * vResults[3] + vResults[4] * vResults[4] + vResults[5] * vResults[5]);
2604 }
2605 else if (nFunctions < 12)
2606 {
2607 _mDx = mglPoint(vResults[3], vResults[4], vResults[5]);
2608 _mDy = mglPoint(vResults[6], vResults[7], vResults[8]);
2609 _mDz = mglPoint(vResults[4] * vResults[8] - vResults[7] * vResults[5],
2610 vResults[6] * vResults[5] - vResults[3] * vResults[8],
2611 vResults[3] * vResults[7] - vResults[6] * vResults[4]) * 2.0
2612 / (sqrt(vResults[3] * vResults[3] + vResults[4] * vResults[4] + vResults[5] * vResults[5])
2613 + sqrt(vResults[6] * vResults[6] + vResults[7] * vResults[7] + vResults[8] * vResults[8]));
2614 }
2615 else
2616 {
2617 _mDx = mglPoint(vResults[3], vResults[4], vResults[5]);
2618 _mDy = mglPoint(vResults[6], vResults[7], vResults[8]);
2619 _mDz = mglPoint(vResults[9], vResults[10], vResults[11]);
2620 }
2621
2622 _graph->Face(mglPoint(vResults[0], vResults[1], vResults[2]),
2623 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDx,
2624 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDy,
2625 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDx + _mDy,
2626 sStyle.c_str());
2627 _graph->Face(mglPoint(vResults[0], vResults[1], vResults[2]),
2628 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDx,
2629 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDz,
2630 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDz + _mDx,
2631 sStyle.c_str());
2632 _graph->Face(mglPoint(vResults[0], vResults[1], vResults[2]),
2633 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDy,
2634 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDz,
2635 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDy + _mDz,
2636 sStyle.c_str());
2637 _graph->Face(mglPoint(vResults[0], vResults[1], vResults[2]) + _mDz,
2638 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDx + _mDz,
2639 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDy + _mDz,
2640 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDx + _mDy + _mDz,
2641 sStyle.c_str());
2642 _graph->Face(mglPoint(vResults[0], vResults[1], vResults[2]) + _mDy,
2643 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDx + _mDy,
2644 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDz + _mDy,
2645 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDz + _mDx + _mDy,
2646 sStyle.c_str());
2647 _graph->Face(mglPoint(vResults[0], vResults[1], vResults[2]) + _mDx,
2648 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDy + _mDx,
2649 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDz + _mDx,
2650 mglPoint(vResults[0], vResults[1], vResults[2]) + _mDy + _mDz + _mDx,
2651 sStyle.c_str());
2652 }
2653 else if (sCurrentDrawingFunction.substr(0, 7) == "sphere(")
2654 {
2655 if (nFunctions < 4)
2656 continue;
2657 _graph->Sphere(mglPoint(vResults[0], vResults[1], vResults[2]), vResults[3], sStyle.c_str());
2658 }
2659 else if (sCurrentDrawingFunction.substr(0, 5) == "cone(")
2660 {
2661 if (nFunctions < 7)
2662 continue;
2663 if (nFunctions >= 8)
2664 _graph->Cone(mglPoint(vResults[0], vResults[1], vResults[2]), mglPoint(vResults[3], vResults[4], vResults[5]), vResults[6], vResults[7], sStyle.c_str());
2665 else
2666 _graph->Cone(mglPoint(vResults[0], vResults[1], vResults[2]), mglPoint(vResults[3], vResults[4], vResults[5]), vResults[6], 0.0, sStyle.c_str());
2667 }
2668 else if (sCurrentDrawingFunction.substr(0, 6) == "conev(")
2669 {
2670 if (nFunctions < 7)
2671 continue;
2672 if (nFunctions >= 8)
2673 _graph->Cone(mglPoint(vResults[0], vResults[1], vResults[2]), mglPoint(vResults[3], vResults[4], vResults[5]) + mglPoint(vResults[0], vResults[1], vResults[2]), vResults[6], vResults[7], sStyle.c_str());
2674 else
2675 _graph->Cone(mglPoint(vResults[0], vResults[1], vResults[2]), mglPoint(vResults[3], vResults[4], vResults[5]) + mglPoint(vResults[0], vResults[1], vResults[2]), vResults[6], 0.0, sStyle.c_str());
2676 }
2677 else if (sCurrentDrawingFunction.substr(0, 5) == "drop(")
2678 {
2679 if (nFunctions < 7)
2680 continue;
2681 double dShift = 1;
2682 double dAspherity = 1;
2683 if (nFunctions >= 8)
2684 dShift = vResults[7];
2685 if (nFunctions >= 9)
2686 dAspherity = vResults[8];
2687 _graph->Drop(mglPoint(vResults[0], vResults[1], vResults[2]),
2688 mglPoint(vResults[3], vResults[4], vResults[5]),
2689 vResults[6],
2690 sStyle.c_str(),
2691 dShift,
2692 dAspherity);
2693 }
2694 else if (sCurrentDrawingFunction.substr(0, 7) == "circle(")
2695 {
2696 if (nFunctions < 4)
2697 continue;
2698 _graph->Circle(mglPoint(vResults[0], vResults[1], vResults[2]), vResults[3], sStyle.c_str());
2699 }
2700 else if (sCurrentDrawingFunction.substr(0, 4) == "arc(")
2701 {
2702 if (nFunctions < 7)
2703 continue;
2704 if (nFunctions < 9)
2705 _graph->Arc(mglPoint(vResults[0], vResults[1], vResults[2]),
2706 mglPoint(vResults[3], vResults[4], vResults[5]), vResults[6], sStyle.c_str());
2707 else
2708 _graph->Arc(mglPoint(vResults[0], vResults[1], vResults[2]),
2709 mglPoint(vResults[3], vResults[4], vResults[5]),
2710 mglPoint(vResults[6], vResults[7], vResults[8]),
2711 vResults[9], sStyle.c_str());
2712
2713 }
2714 else if (sCurrentDrawingFunction.substr(0, 5) == "arcv(")
2715 {
2716 if (nFunctions < 7)
2717 continue;
2718 if (nFunctions < 9)
2719 _graph->Arc(mglPoint(vResults[0], vResults[1], vResults[2]),
2720 mglPoint(vResults[3], vResults[4], vResults[5]) + mglPoint(vResults[0], vResults[1], vResults[2]), vResults[6], sStyle.c_str());
2721 else
2722 _graph->Arc(mglPoint(vResults[0], vResults[1], vResults[2]),
2723 mglPoint(vResults[3], vResults[4], vResults[5]) + mglPoint(vResults[0], vResults[1], vResults[2]),
2724 mglPoint(vResults[6], vResults[7], vResults[8]) + mglPoint(vResults[0], vResults[1], vResults[2]),
2725 vResults[9], sStyle.c_str());
2726
2727 }
2728 else if (sCurrentDrawingFunction.substr(0, 6) == "point(")
2729 {
2730 if (nFunctions < 3)
2731 continue;
2732 _graph->Mark(mglPoint(vResults[0], vResults[1], vResults[2]), sStyle.c_str());
2733 }
2734 else if (sCurrentDrawingFunction.substr(0, 6) == "curve(")
2735 {
2736 if (nFunctions < 12)
2737 continue;
2738 _graph->Curve(mglPoint(vResults[0], vResults[1], vResults[2]),
2739 mglPoint(vResults[3], vResults[4], vResults[5]),
2740 mglPoint(vResults[6], vResults[7], vResults[8]),
2741 mglPoint(vResults[9], vResults[10], vResults[11]), sStyle.c_str());
2742 }
2743 else if (sCurrentDrawingFunction.substr(0, 8) == "ellipse(")
2744 {
2745 if (nFunctions < 7)
2746 continue;
2747 _graph->Ellipse(mglPoint(vResults[0], vResults[1], vResults[2]), mglPoint(vResults[3], vResults[4], vResults[5]), vResults[6], sStyle.c_str());
2748 }
2749 else if (sCurrentDrawingFunction.substr(0, 9) == "ellipsev(")
2750 {
2751 if (nFunctions < 7)
2752 continue;
2753 _graph->Ellipse(mglPoint(vResults[0], vResults[1], vResults[2]), mglPoint(vResults[3], vResults[4], vResults[5]) + mglPoint(vResults[0], vResults[1], vResults[2]), vResults[6], sStyle.c_str());
2754 }
2755 else if (sCurrentDrawingFunction.substr(0, 5) == "text(")
2756 {
2757 if (!sTextString.length())
2758 {
2759 sTextString = sStyle;
2760 sStyle = "k";
2761 }
2762 if (nFunctions >= 6)
2763 _graph->Puts(mglPoint(vResults[0], vResults[1], vResults[2]), mglPoint(vResults[3], vResults[4], vResults[5]), sTextString.c_str(), sStyle.c_str());
2764 else if (nFunctions >= 3)
2765 _graph->Puts(mglPoint(vResults[0], vResults[1], vResults[2]), sTextString.c_str(), sStyle.c_str());
2766 else
2767 continue;
2768 }
2769 else if (sCurrentDrawingFunction.substr(0, 8) == "polygon(")
2770 {
2771 if (nFunctions < 7 || vResults[6] < 3)
2772 continue;
2773 _graph->Polygon(mglPoint(vResults[0], vResults[1], vResults[2]), mglPoint(vResults[3], vResults[4], vResults[5]), (int)vResults[6], sStyle.c_str());
2774 }
2775 else if (sCurrentDrawingFunction.substr(0, 9) == "polygonv(")
2776 {
2777 if (nFunctions < 7 || vResults[6] < 3)
2778 continue;
2779 _graph->Polygon(mglPoint(vResults[0], vResults[1], vResults[2]), mglPoint(vResults[3], vResults[4], vResults[5]) + mglPoint(vResults[0], vResults[1], vResults[2]), (int)vResults[6], sStyle.c_str());
2780 }
2781 else
2782 continue;
2783 }
2784}
2785
2786
2797void Plot::createStd3dPlot(size_t nPlotCompose, size_t nPlotComposeSize)
2798{
2799 string sDummy = "";
2800 string sConvLegends = "";
2801 bool useImag = false;
2802
2803 mglData _mData[3];
2804 mglData _mData2[3];
2805
2809
2810 // Apply curvilinear coordinates
2812
2813 for (size_t n = 0; n < m_manager.assets.size(); n++)
2814 {
2815 int nDataOffset = 0;
2816
2818 {
2819 _mData[XCOORD].Link(useImag ? m_manager.assets[n].data[0].second : m_manager.assets[n].data[0].first);
2820 _mData[YCOORD].Link(useImag ? m_manager.assets[n+1].data[0].second : m_manager.assets[n+1].data[0].first);
2821 _mData[ZCOORD].Link(useImag ? m_manager.assets[n+2].data[0].second : m_manager.assets[n+2].data[0].first);
2822 nDataOffset = 2;
2823 }
2824 else
2825 {
2826 _mData[XCOORD].Link(useImag ? m_manager.assets[n].data[XCOORD].second : m_manager.assets[n].data[XCOORD].first);
2827 _mData[YCOORD].Link(useImag ? m_manager.assets[n].data[YCOORD].second : m_manager.assets[n].data[YCOORD].first);
2828 _mData[ZCOORD].Link(useImag ? m_manager.assets[n].data[ZCOORD].second : m_manager.assets[n].data[ZCOORD].first);
2829 }
2830
2831 StripSpaces(m_manager.assets[n+nDataOffset].legend);
2832
2834 && n+nDataOffset+1 < m_manager.assets.size())
2835 {
2836 _mData2[XCOORD].Link(useImag ? m_manager.assets[n+nDataOffset+1].data[XCOORD].second : m_manager.assets[n+nDataOffset+1].data[XCOORD].first);
2837 _mData2[YCOORD].Link(useImag ? m_manager.assets[n+nDataOffset+1].data[YCOORD].second : m_manager.assets[n+nDataOffset+1].data[YCOORD].first);
2838 _mData2[ZCOORD].Link(useImag ? m_manager.assets[n+nDataOffset+1].data[ZCOORD].second : m_manager.assets[n+nDataOffset+1].data[ZCOORD].first);
2839 }
2840 else
2841 {
2842 for (int j = XCOORD; j <= ZCOORD; j++)
2843 {
2844 _mData2[j] = 0.0 * _mData[j];
2845 }
2846 }
2847
2848 if (m_manager.assets[n+nDataOffset].type == PT_DATA)
2849 {
2850 for (int j = XRANGE; j <= ZRANGE; j++)
2851 {
2852 for (int i = 0; i < getNN(_mData[j]); i++)
2853 {
2854 if (!_pInfo.ranges[j].isInside(_mData[j].a[i]))
2855 _mData[j].a[i] = NAN;
2856 }
2857 }
2858
2860 {
2861 _mData2[XCOORD].Link(m_manager.assets[n+nDataOffset].data[XCOORD+3].first);
2862 _mData2[YCOORD].Link(m_manager.assets[n+nDataOffset].data[YCOORD+3].first);
2863 _mData2[ZCOORD].Link(m_manager.assets[n+nDataOffset].data[ZCOORD+3].first);
2864 }
2865 }
2866
2867 // Create the actual 3D trajectory plot
2868 if (!plotstd3d(_mData, _mData2, m_manager.assets[n+nDataOffset].type))
2869 {
2870 clearData();
2871 return;
2872 }
2873
2874 if (m_manager.assets[n+nDataOffset].type == PT_FUNCTION)
2875 {
2876 if (_pData.getSettings(PlotData::LOG_REGION) && n+nDataOffset+1 < m_manager.assets.size())
2877 {
2878 for (int k = 0; k < 2; k++)
2879 {
2880 sConvLegends = m_manager.assets[n+nDataOffset].legend + " -nq";
2881 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sConvLegends, sDummy, true);
2882 sConvLegends = "\"" + sConvLegends + "\"";
2883
2884 for (unsigned int l = 0; l < sConvLegends.length(); l++)
2885 {
2886 if (sConvLegends[l] == '(')
2887 l += getMatchingParenthesis(sConvLegends.substr(l));
2888
2889 if (sConvLegends[l] == ',')
2890 {
2891 sConvLegends = "\"[" + sConvLegends.substr(1, sConvLegends.length() - 2) + "]\"";
2892 break;
2893 }
2894 }
2895
2896 if (sConvLegends != "\"\"")
2897 {
2898 _graph->AddLegend(fromSystemCodePage(replaceToTeX(sConvLegends.substr(1, sConvLegends.length() - 2))).c_str(),
2899 _pInfo.sLineStyles[_pInfo.nStyle].c_str());
2900 nLegends++;
2901 }
2902
2903 }
2904 }
2905 else
2906 {
2907 sConvLegends = m_manager.assets[n+nDataOffset].legend + " -nq";
2908 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sConvLegends, sDummy, true);
2909
2910 if (_pData.getSettings(PlotData::INT_COMPLEXMODE) == CPLX_REIM && sConvLegends.length())
2911 sConvLegends = useImag ? "Im(" + sConvLegends + ")" : "Re(" + sConvLegends + ")";
2912
2913 sConvLegends = "\"" + sConvLegends + "\"";
2914
2915 if (sConvLegends != "\"\"")
2916 {
2917 _graph->AddLegend(fromSystemCodePage(replaceToTeX(sConvLegends.substr(1, sConvLegends.length() - 2))).c_str(),
2919 nLegends++;
2920 }
2921
2922 }
2923 }
2924 else
2925 {
2926 sConvLegends = m_manager.assets[n+nDataOffset].legend + " -nq";
2927 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sConvLegends, sDummy, true);
2928
2929 if (_pData.getSettings(PlotData::INT_COMPLEXMODE) == CPLX_REIM && sConvLegends.length())
2930 sConvLegends = useImag ? "Im(" + sConvLegends + ")" : "Re(" + sConvLegends + ")";
2931
2932 sConvLegends = "\"" + sConvLegends + "\"";
2933
2934 if (sConvLegends != "\"\"")
2935 {
2936 nLegends++;
2937 std::string sLegendStyle;
2938 std::string sLegend = fromSystemCodePage(replaceToTeX(sConvLegends.substr(1, sConvLegends.length() - 2)));
2939
2941 {
2950 else
2952 }
2953 else
2955
2956 _graph->AddLegend(sLegend.c_str(), sLegendStyle.c_str());
2957 }
2958
2959 }
2960
2962
2964 && n+nDataOffset+1 < m_manager.assets.size()
2966 n++;
2967
2968 if (getNN(_mData2[0]) && _pData.getSettings(PlotData::LOG_REGION))
2970
2972 {
2973 if (!useImag)
2974 {
2975 useImag = true;
2976 n--;
2977 }
2978 else
2979 {
2980 useImag = false;
2981 n += nDataOffset;
2982 }
2983 }
2984 else
2985 n += nDataOffset;
2986 }
2987
2989 _graph->SetCutBox(mglPoint(0), mglPoint(0));
2990
2991 if (nPlotCompose + 1 == nPlotComposeSize
2993 && nLegends
2995 {
2997 _graph->Legend(1.35, 1.2);
2998 else
3000 }
3001}
3002
3003
3014bool Plot::plotstd3d(mglData _mData[3], mglData _mData2[3], const short nType)
3015{
3016#warning NOTE (numere#3#08/15/21): Temporary fix for MathGL misbehaviour
3023 {
3024 for (int i = XCOORD; i <= ZCOORD; i++)
3025 {
3026 _mData[i] = duplicatePoints(_mData[i]);
3027 _mData2[i] = duplicatePoints(_mData2[i]);
3028 }
3029 }
3030
3031 int nNextStyle = _pInfo.nextStyle();
3032
3033 if (nType == PT_FUNCTION)
3034 {
3037 _graph->Plot(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD], ("a" + _pInfo.sLineStyles[_pInfo.nStyle]).c_str());
3039 && getNN(_mData2[0]))
3040 {
3041 _graph->Region(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD], _mData2[XCOORD], _mData2[YCOORD], _mData2[ZCOORD],
3042 ("a{" + _pData.getColors().substr(_pInfo.nStyle, 1) + "7}{" + _pData.getColors().substr(nNextStyle, 1) + "7}").c_str());
3043 _graph->Plot(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD],
3044 ("a" + _pInfo.sLineStyles[_pInfo.nStyle]).c_str());
3045 _graph->Plot(_mData2[XCOORD], _mData2[YCOORD], _mData2[ZCOORD],
3046 ("a" + _pInfo.sLineStyles[nNextStyle]).c_str());
3047 }
3048 else
3049 _graph->Area(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD],
3050 ("a" + _pInfo.sLineStyles[_pInfo.nStyle] + "{" + _pData.getColors()[_pInfo.nStyle] + "9}").c_str());
3051 }
3052 else
3053 {
3055 {
3056 // --> Interpolate-Schalter. Siehe weiter oben fuer Details <--
3058 && countValidElements(_mData[0]) >= (size_t)_pInfo.nSamples)
3059 {
3061 _graph->Bars(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD],
3062 (_pInfo.sLineStyles[_pInfo.nStyle] + "^").c_str());
3064 _graph->Area(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD],
3065 ("a" + _pInfo.sLineStyles[_pInfo.nStyle] + "{" + _pData.getColors()[_pInfo.nStyle] + "9}").c_str());
3066 else
3067 _graph->Plot(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD],
3068 ("a" + _pInfo.sLineStyles[_pInfo.nStyle]).c_str());
3069 }
3072 {
3074 _graph->Bars(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD],
3075 (_pInfo.sLineStyles[_pInfo.nStyle] + "^").c_str());
3077 _graph->Area(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD],
3078 ("a" + _pInfo.sLineStyles[_pInfo.nStyle] + "{" + _pData.getColors()[_pInfo.nStyle] + "9}").c_str());
3079 else
3080 _graph->Plot(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD],
3081 ("a" + _pInfo.sConPointStyles[_pInfo.nStyle]).c_str());
3082 }
3083 else
3084 {
3086 _graph->Dots(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD],
3089 _graph->Crust(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD],
3090 _pData.getColorScheme().c_str());
3092 _graph->Bars(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD],
3093 (_pInfo.sLineStyles[_pInfo.nStyle] + "^").c_str());
3095 _graph->Step(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD],
3096 (_pInfo.sLineStyles[_pInfo.nStyle]).c_str());
3098 _graph->Stem(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD],
3100 else
3101 _graph->Plot(_mData[XCOORD], _mData[YCOORD], _mData[ZCOORD],
3102 ("a" + _pInfo.sPointStyles[_pInfo.nStyle]).c_str());
3103 }
3104 }
3107 {
3108 for (int m = 0; m < _mData[0].nx; m++)
3109 {
3110 _graph->Error(mglPoint(_mData[XCOORD].a[m], _mData[YCOORD].a[m], _mData[ZCOORD].a[m]),
3111 mglPoint(_mData2[XCOORD].a[m], _mData2[YCOORD].a[m], _mData2[ZCOORD].a[m]),
3112 _pInfo.sPointStyles[_pInfo.nStyle].c_str());
3113 }
3114 }
3115 }
3116
3117 return true;
3118}
3119
3120
3130long Plot::getNN(const mglData& _mData)
3131{
3132 return _mData.nx * _mData.ny * _mData.nz;
3133}
3134
3135
3146void Plot::filename(size_t nPlotComposeSize, size_t nPlotCompose)
3147{
3148 // --> Ggf. waehlen eines Default-Dateinamens <--
3149 if (!_pData.getSettings(PlotData::STR_FILENAME).length() && !nPlotCompose)
3150 {
3151 string sExt = ".png";
3152
3154 sExt = ".gif";
3155
3156 if (nPlotComposeSize > 1)
3157 _pData.setFileName("composition" + sExt);
3158 else if (_pInfo.sCommand == "plot3d")
3159 _pData.setFileName("plot3d" + sExt);
3160 else if (_pInfo.sCommand == "plot")
3161 _pData.setFileName("plot" + sExt);
3162 else if (_pInfo.sCommand == "meshgrid3d" || _pInfo.sCommand.substr(0, 6) == "mesh3d")
3163 _pData.setFileName("meshgrid3d" + sExt);
3164 else if (_pInfo.sCommand.substr(0, 4) == "mesh")
3165 _pData.setFileName("meshgrid" + sExt);
3166 else if (_pInfo.sCommand.substr(0, 6) == "surf3d" || _pInfo.sCommand == "surface3d")
3167 _pData.setFileName("surface3d" + sExt);
3168 else if (_pInfo.sCommand.substr(0, 4) == "surf")
3169 _pData.setFileName("surface" + sExt);
3170 else if (_pInfo.sCommand.substr(0, 6) == "cont3d" || _pInfo.sCommand == "contour3d")
3171 _pData.setFileName("contour3d" + sExt);
3172 else if (_pInfo.sCommand.substr(0.4) == "cont")
3173 _pData.setFileName("contour" + sExt);
3174 else if (_pInfo.sCommand.substr(0, 6) == "grad3d" || _pInfo.sCommand == "gradient3d")
3175 _pData.setFileName("gradient3d" + sExt);
3176 else if (_pInfo.sCommand.substr(0, 4) == "grad")
3177 _pData.setFileName("gradient" + sExt);
3178 else if (_pInfo.sCommand == "density3d" || _pInfo.sCommand.substr(0, 6) == "dens3d")
3179 _pData.setFileName("density3d" + sExt);
3180 else if (_pInfo.sCommand.substr(0, 4) == "dens")
3181 _pData.setFileName("density" + sExt);
3182 else if (_pInfo.sCommand.substr(0, 6) == "vect3d" || _pInfo.sCommand == "vector3d")
3183 _pData.setFileName("vectorfield3d" + sExt);
3184 else if (_pInfo.sCommand.substr(0, 4) == "vect")
3185 _pData.setFileName("vectorfield" + sExt);
3186 else if (_pInfo.sCommand.substr(0, 6) == "draw3d")
3187 _pData.setFileName("drawing3d" + sExt);
3188 else if (_pInfo.sCommand.substr(0, 4) == "draw")
3189 _pData.setFileName("drawing" + sExt);
3190 else if (_pInfo.sCommand == "implot")
3191 _pData.setFileName("image" + sExt);
3192 else
3193 _pData.setFileName("unknown_style" + sExt);
3194 }
3195 else if (_pData.getSettings(PlotData::STR_FILENAME).length() && !nPlotCompose)
3196 bOutputDesired = true;
3197
3198 if (NumeReKernel::getInstance()->getStringParser().isStringExpression(_pData.getSettings(PlotData::STR_FILENAME)) && !nPlotCompose)
3199 {
3201 string sTemp_2 = "";
3202 string sExtension = sTemp.substr(sTemp.find('.'));
3203 sTemp = sTemp.substr(0, sTemp.find('.'));
3204
3205 if (sExtension[sExtension.length() - 1] == '"')
3206 {
3207 sTemp += "\"";
3208 sExtension = sExtension.substr(0, sExtension.length() - 1);
3209 }
3210
3211 NumeReKernel::getInstance()->getStringParser().evalAndFormat(sTemp, sTemp_2, true);
3212 _pData.setFileName(sTemp.substr(1, sTemp.length() - 2) + sExtension);
3213 }
3214
3215 if (_pData.getAnimateSamples() && _pData.getSettings(PlotData::STR_FILENAME).substr(_pData.getSettings(PlotData::STR_FILENAME).rfind('.')) != ".gif" && !nPlotCompose)
3217}
3218
3219
3229{
3230 for (int i = 0; i < _pInfo.nStyleMax; i++)
3231 {
3232 _pInfo.sLineStyles[i] = _pData.getColors().substr(i, 1);
3233 _pInfo.sPointStyles[i] = _pData.getColors().substr(i, 1);
3234 _pInfo.sContStyles[i] = _pData.getColors().substr(i, 1);
3235 _pInfo.sConPointStyles[i] = _pData.getColors().substr(i, 1);
3236 }
3237
3238 for (int i = 0; i < _pInfo.nStyleMax; i++)
3239 {
3241
3243 {
3244 if (_pData.getSettings(PlotData::STR_POINTSTYLES)[2 * i] != ' ')
3246
3248 }
3249
3251 {
3252 if (_pData.getSettings(PlotData::STR_POINTSTYLES)[2 * i] != ' ')
3254
3256 }
3257 else
3258 {
3259 if (_pData.getSettings(PlotData::STR_POINTSTYLES)[2 * i] != ' ')
3260 _pInfo.sPointStyles[i] += " " + _pData.getSettings(PlotData::STR_POINTSTYLES).substr(2 * i, 1) + _pData.getSettings(PlotData::STR_POINTSTYLES).substr(2 * i + 1, 1);
3261 else
3262 _pInfo.sPointStyles[i] += " " + _pData.getSettings(PlotData::STR_POINTSTYLES).substr(2 * i + 1, 1);
3263 }
3264
3265 if (_pData.getSettings(PlotData::STR_POINTSTYLES)[2 * i] != ' ')
3267 else
3268 _pInfo.sConPointStyles[i] += _pData.getLineStyles().substr(i, 1) + _pData.getSettings(PlotData::STR_POINTSTYLES).substr(2 * i + 1, 1);
3269
3272 }
3273}
3274
3275
3287string Plot::expandStyleForCurveArray(const string& sCurrentStyle, bool expand)
3288{
3289 // Do nothing, if the string shall not be expanded
3290 if (!expand)
3291 return sCurrentStyle;
3292
3293 string sExpandedStyle;
3294
3295 // Expand the style string
3296 for (size_t i = 1; i <= 9; i++)
3297 {
3298 sExpandedStyle += "{" + sCurrentStyle.substr(0, 1) + toString(i) + "}" + sCurrentStyle.substr(1);
3299 }
3300
3301 return sExpandedStyle;
3302}
3303
3304
3318void Plot::evaluateSubplot(string& sCmd, size_t nMultiplots[2], size_t& nSubPlots, size_t& nSubPlotMap)
3319{
3321 {
3323 _graph->ClearLegend();
3324 }
3325
3326 string sSubPlotIDX = sCmd.substr(findCommand(sCmd).nPos + 7);
3327 if (sSubPlotIDX.find("-set") != string::npos || sSubPlotIDX.find("--") != string::npos)
3328 {
3329 if (sSubPlotIDX.find("-set") != string::npos)
3330 sSubPlotIDX.erase(sSubPlotIDX.find("-set"));
3331 else
3332 sSubPlotIDX.erase(sSubPlotIDX.find("--"));
3333 }
3334 StripSpaces(sSubPlotIDX);
3335 if (findParameter(sCmd, "cols", '=') || findParameter(sCmd, "lines", '='))
3336 {
3337 unsigned int nMultiLines = 1, nMultiCols = 1;
3338
3339 if (findParameter(sCmd, "cols", '='))
3340 {
3341 _parser.SetExpr(getArgAtPos(sCmd, findParameter(sCmd, "cols", '=') + 4));
3342 nMultiCols = (unsigned int)intCast(_parser.Eval());
3343 }
3344 if (findParameter(sCmd, "lines", '='))
3345 {
3346 _parser.SetExpr(getArgAtPos(sCmd, findParameter(sCmd, "lines", '=') + 5));
3347 nMultiLines = (unsigned int)intCast(_parser.Eval());
3348 }
3349 if (sSubPlotIDX.length())
3350 {
3351 if (!_functions.call(sSubPlotIDX))
3353 if (_data.containsTablesOrClusters(sSubPlotIDX))
3354 {
3355 getDataElements(sSubPlotIDX, _parser, _data, _option);
3356 }
3357 _parser.SetExpr(sSubPlotIDX);
3358 int nRes = 0;
3359 value_type* v = _parser.Eval(nRes);
3360 if (nRes == 1)
3361 {
3362 if (intCast(v[0]) < 1)
3363 v[0] = 1;
3364 if ((unsigned int)intCast(v[0]) - 1 >= nMultiplots[0]*nMultiplots[1])
3366 if (!checkMultiPlotArray(nMultiplots, nSubPlotMap, (unsigned int)(intCast(v[0]) - 1), nMultiCols, nMultiLines))
3368 _graph->MultiPlot(nMultiplots[0], nMultiplots[1], (unsigned int)intCast(v[0]) - 1, nMultiCols, nMultiLines);
3369 } // cols, lines
3370 else
3371 {
3372 if ((unsigned int)(intCast(v[1]) - 1 + (intCast(v[0]) - 1)*nMultiplots[1]) >= nMultiplots[0]*nMultiplots[1])
3374 if (!checkMultiPlotArray(nMultiplots, nSubPlotMap, (unsigned int)((intCast(v[1]) - 1) + (intCast(v[0]) - 1)*nMultiplots[0]), nMultiCols, nMultiLines))
3376 _graph->MultiPlot(nMultiplots[0], nMultiplots[1], (unsigned int)((intCast(v[1]) - 1) + (intCast(v[0]) - 1)*nMultiplots[0]), nMultiCols, nMultiLines);
3377 }
3378 }
3379 else
3380 {
3381 if (nSubPlots >= nMultiplots[0]*nMultiplots[1])
3383 int nPlotPos = 1;
3384 for (unsigned int nSub = 0; nSub < nMultiplots[0]*nMultiplots[1]; nSub++)
3385 {
3386 if (nPlotPos & nSubPlotMap)
3387 nPlotPos <<= 1;
3388 else
3389 {
3390 if (!checkMultiPlotArray(nMultiplots, nSubPlotMap, nSub, nMultiCols, nMultiLines))
3392 _graph->MultiPlot(nMultiplots[0], nMultiplots[1], nSub, nMultiCols, nMultiLines);
3393 break;
3394 }
3395 if (nSub == nMultiplots[0]*nMultiplots[1] - 1)
3396 {
3398 }
3399 }
3400 }
3401 }
3402 else
3403 {
3404 if (sSubPlotIDX.length())
3405 {
3406 if (!_functions.call(sSubPlotIDX))
3408 if (_data.containsTablesOrClusters(sSubPlotIDX))
3409 {
3410 getDataElements(sSubPlotIDX, _parser, _data, _option);
3411 }
3412 _parser.SetExpr(sSubPlotIDX);
3413 int nRes = 0;
3414 value_type* v = _parser.Eval(nRes);
3415 if (nRes == 1)
3416 {
3417 if (intCast(v[0]) < 1)
3418 v[0] = 1;
3419 if ((unsigned int)intCast(v[0]) - 1 >= nMultiplots[0]*nMultiplots[1])
3421 if ((unsigned int)intCast(v[0]) != 1)
3422 nRes <<= (unsigned int)(intCast(v[0]) - 1);
3423 if (nRes & nSubPlotMap)
3425 nSubPlotMap |= nRes;
3426 _graph->SubPlot(nMultiplots[0], nMultiplots[1], (unsigned int)intCast(v[0]) - 1);
3427 }
3428 else
3429 {
3430 if ((unsigned int)(intCast(v[1]) - 1 + (intCast(v[0]) - 1)*nMultiplots[0]) >= nMultiplots[0]*nMultiplots[1])
3432 nRes = 1;
3433 if ((unsigned int)(intCast(v[1]) + (intCast(v[0]) - 1)*nMultiplots[0]) != 1)
3434 nRes <<= (unsigned int)((intCast(v[1]) - 1) + (intCast(v[0]) - 1) * nMultiplots[0]);
3435 if (nRes & nSubPlotMap)
3437 nSubPlotMap |= nRes;
3438 _graph->SubPlot(nMultiplots[0], nMultiplots[1], (unsigned int)((intCast(v[1]) - 1) + (intCast(v[0]) - 1)*nMultiplots[0]));
3439 }
3440 }
3441 else
3442 {
3443 if (nSubPlots >= nMultiplots[0]*nMultiplots[1])
3445 int nPlotPos = 1;
3446 for (unsigned int nSub = 0; nSub < nMultiplots[0]*nMultiplots[1]; nSub++)
3447 {
3448 if (nPlotPos & nSubPlotMap)
3449 nPlotPos <<= 1;
3450 else
3451 {
3452 nSubPlotMap |= nPlotPos;
3453 _graph->SubPlot(nMultiplots[0], nMultiplots[1], nSub);
3454 break;
3455 }
3456 if (nSub == nMultiplots[0]*nMultiplots[1] - 1)
3457 {
3459 }
3460 }
3461 }
3462 }
3463}
3464
3465
3475void Plot::displayMessage(bool bAnimateVar)
3476{
3478 NumeReKernel::printPreFmt(toSystemCodePage("|-> " + _lang.get("PLOT_CALCULATING_DATA_FOR") + " "));
3479
3480 if (_pInfo.sCommand == "surface3d"
3481 || _pInfo.sCommand.substr(0, 6) == "surf3d"
3482 || _pInfo.sCommand == "meshgrid3d"
3483 || _pInfo.sCommand.substr(0, 6) == "mesh3d"
3484 || _pInfo.sCommand == "contour3d"
3485 || _pInfo.sCommand.substr(0, 6) == "cont3d"
3486 || _pInfo.sCommand == "density3d"
3487 || _pInfo.sCommand.substr(0, 6) == "dens3d"
3488 || _pInfo.sCommand == "gradient3d"
3489 || _pInfo.sCommand.substr(0, 6) == "grad3d")
3490 {
3491 _pInfo.b3D = true;
3492 if (_pInfo.nSamples > 71)
3493 {
3495 _pInfo.nSamples = 151;
3498 else
3499 _pInfo.nSamples = 71;
3500 }
3501 if (!_pData.getSettings(PlotData::LOG_SILENTMODE) && _option.systemPrints() && _pInfo.sCommand.substr(0, 4) == "surf")
3502 NumeReKernel::printPreFmt("3D-" + toSystemCodePage(_lang.get("PLOT_SURFACE")) + "-");
3503 else if (!_pData.getSettings(PlotData::LOG_SILENTMODE) && _option.systemPrints() && _pInfo.sCommand.substr(0, 4) == "mesh")
3504 NumeReKernel::printPreFmt("3D-" + toSystemCodePage(_lang.get("PLOT_MESHGRID")) + "-");
3505 else if (!_pData.getSettings(PlotData::LOG_SILENTMODE) && _option.systemPrints() && _pInfo.sCommand.substr(0, 4) == "cont")
3506 NumeReKernel::printPreFmt("3D-" + toSystemCodePage(_lang.get("PLOT_CONTOUR")) + "-");
3507 else if (!_pData.getSettings(PlotData::LOG_SILENTMODE) && _option.systemPrints() && _pInfo.sCommand.substr(0, 4) == "dens")
3508 NumeReKernel::printPreFmt("3D-" + toSystemCodePage(_lang.get("PLOT_DENSITY")) + "-");
3509 else if (!_pData.getSettings(PlotData::LOG_SILENTMODE) && _option.systemPrints() && _pInfo.sCommand.substr(0, 4) == "grad")
3510 NumeReKernel::printPreFmt("3D-" + toSystemCodePage(_lang.get("PLOT_GRADIENT")) + "-");
3511 }
3512 else if (_pInfo.sCommand.substr(0, 6) == "vect3d" || _pInfo.sCommand == "vector3d")
3513 {
3514 _pInfo.b3DVect = true;
3515 if (_pInfo.nSamples > 11)
3516 _pInfo.nSamples = 11;
3518 NumeReKernel::printPreFmt("3D-" + toSystemCodePage(_lang.get("PLOT_VECTOR")) + "-");
3520 {
3521 if (_pInfo.nSamples % 2)
3522 _pInfo.nSamples -= 1;
3523 }
3524 }
3525 else if (_pInfo.sCommand.substr(0, 4) == "vect")
3526 {
3527 _pInfo.b2DVect = true;
3528 if (_pInfo.nSamples > 21)
3529 _pInfo.nSamples = 21;
3531 NumeReKernel::printPreFmt(toSystemCodePage(_lang.get("PLOT_VECTOR")) + "-");
3532 }
3533 else if (_pInfo.sCommand.substr(0, 4) == "mesh"
3534 || _pInfo.sCommand.substr(0, 4) == "surf"
3535 || _pInfo.sCommand.substr(0, 4) == "cont"
3536 || _pInfo.sCommand.substr(0, 4) == "grad"
3537 || _pInfo.sCommand.substr(0, 4) == "dens")
3538 {
3539 _pInfo.b2D = true;
3540 if (!_pData.getSettings(PlotData::LOG_SILENTMODE) && _option.systemPrints() && _pInfo.sCommand.substr(0, 4) == "surf")
3541 NumeReKernel::printPreFmt("2D-" + toSystemCodePage(_lang.get("PLOT_SURFACE")) + "-");
3542 else if (!_pData.getSettings(PlotData::LOG_SILENTMODE) && _option.systemPrints() && _pInfo.sCommand.substr(0, 4) == "mesh")
3543 NumeReKernel::printPreFmt("2D-" + toSystemCodePage(_lang.get("PLOT_MESHGRID")) + "-");
3544 else if (!_pData.getSettings(PlotData::LOG_SILENTMODE) && _option.systemPrints() && _pInfo.sCommand.substr(0, 4) == "cont")
3545 NumeReKernel::printPreFmt("2D-" + toSystemCodePage(_lang.get("PLOT_CONTOUR")) + "-");
3546 else if (!_pData.getSettings(PlotData::LOG_SILENTMODE) && _option.systemPrints() && _pInfo.sCommand.substr(0, 4) == "dens")
3547 NumeReKernel::printPreFmt("2D-" + toSystemCodePage(_lang.get("PLOT_DENSITY")) + "-");
3548 else if (!_pData.getSettings(PlotData::LOG_SILENTMODE) && _option.systemPrints() && _pInfo.sCommand.substr(0, 4) == "grad")
3549 NumeReKernel::printPreFmt("2D-" + toSystemCodePage(_lang.get("PLOT_GRADIENT")) + "-");
3550 }
3551 else if (_pInfo.sCommand == "plot3d")
3552 {
3555 }
3556 else if (_pInfo.sCommand == "draw")
3557 {
3558 _pInfo.bDraw = true;
3559 }
3560 else if (_pInfo.sCommand == "draw3d")
3561 {
3562 _pInfo.bDraw3D = true;
3565 }
3566 else if (_pInfo.sCommand == "implot")
3567 _pInfo.b2D = true;
3568
3569 if (!_pData.getSettings(PlotData::LOG_SILENTMODE) && _option.systemPrints() && !bAnimateVar && !(_pInfo.bDraw3D || _pInfo.bDraw) && _pInfo.sCommand != "implot")
3570 NumeReKernel::printPreFmt("Plot ... ");
3572 NumeReKernel::printPreFmt("Image plot ... ");
3573 else if (!_pData.getSettings(PlotData::LOG_SILENTMODE) && _option.systemPrints() && !bAnimateVar)
3574 NumeReKernel::printPreFmt(toSystemCodePage(_lang.get("PLOT_DRAWING")) + " ... ");
3576 NumeReKernel::printPreFmt(toSystemCodePage(_lang.get("PLOT_ANIMATION")) + " ... \n");
3577
3578}
3579
3580
3590std::vector<std::string> Plot::separateFunctionsAndData()
3591{
3592 string sFuncTemp = sFunc;
3593 string sToken = "";
3594
3595 while (sFuncTemp.length())
3596 {
3597 sToken = getNextArgument(sFuncTemp, true);
3598 StripSpaces(sToken);
3599
3600 if (_data.containsTablesOrClusters(sToken))
3601 {
3602 if (_data.containsTablesOrClusters(sToken.substr(0, sToken.find_first_of("({") + 1))
3603 && !_data.isTable(sToken.substr(0, sToken.find_first_of("({")))
3604 && !_data.isCluster(sToken.substr(0, sToken.find_first_of("({"))))
3606
3607 string sSubstr = sToken.substr(getMatchingParenthesis(sToken.substr(sToken.find_first_of("({"))) + sToken.find_first_of("({") + 1);
3608
3609 if (sSubstr[sSubstr.find_first_not_of(' ')] != '"' && sSubstr[sSubstr.find_first_not_of(' ')] != '#')
3611 }
3612 }
3613
3614 // --> Zerlegen von sFunc in Funktionenteile und Datenplots <--
3615 sFuncTemp = sFunc;
3616 sFunc.clear();
3617
3618 std::vector<std::string> vDataPlots;
3619
3620 while (sFuncTemp.length())
3621 {
3622 sToken = getNextArgument(sFuncTemp, true);
3623 size_t nPos = sToken.find_first_of("#\"");
3624
3625 if (_data.containsTablesOrClusters(sToken))
3626 {
3627 m_types.push_back(PT_DATA);
3628 m_manager.assets.push_back(PlotAsset());
3629 m_manager.assets.back().boundAxes = _pData.getAxisbind(m_manager.assets.size()-1);
3630 m_manager.assets.back().legend = sToken.substr(nPos);
3631
3632 vDataPlots.push_back(sToken.substr(0, nPos));
3633 }
3634 else
3635 {
3636 m_types.push_back(PT_FUNCTION);
3637 m_manager.assets.push_back(PlotAsset());
3638 m_manager.assets.back().boundAxes = _pData.getAxisbind(m_manager.assets.size()-1);
3639 m_manager.assets.back().legend = sToken.substr(nPos);
3640
3641 sFunc += "," + sToken.substr(0, nPos);
3642 }
3643 }
3644
3645 sFunc.erase(0, 1);
3646
3649
3650 return vDataPlots;
3651}
3652
3653
3663void Plot::extractDataValues(const std::vector<std::string>& vDataPlots)
3664{
3665 size_t typeCounter = 0;
3666 size_t datIvlID = PlotAssetManager::REAL;
3667 size_t datIvlID3D = PlotAssetManager::REAL;
3668
3670 {
3671 datIvlID = PlotAssetManager::REIM;
3672 datIvlID3D = PlotAssetManager::REIM;
3673 }
3675 {
3676 datIvlID = PlotAssetManager::IMAG;
3677 datIvlID3D = PlotAssetManager::ABSREIM;
3678 }
3679
3680 // Now extract the index informations of each referred
3681 // data object and copy its contents to the prepared
3682 // mglData objects
3683 for (size_t i = 0; i < vDataPlots.size(); i++)
3684 {
3685 size_t nParPos = vDataPlots[i].find_first_of("({");
3686 DataAccessParser _accessParser;
3687
3688 while (m_types[typeCounter] != PT_DATA && typeCounter+1 < m_types.size())
3689 typeCounter++;
3690
3691 if (nParPos == string::npos || m_types[typeCounter] != PT_DATA)
3692 throw SyntaxError(SyntaxError::INVALID_DATA_ACCESS, vDataPlots[i] , vDataPlots[i]);
3693
3694 // Get the indices for the current data plot object optimized
3695 // for the plotting algorithm
3696 _accessParser = getAccessParserForPlotAndFit(vDataPlots[i]);
3697
3698 Indices& _idx = _accessParser.getIndices();
3699 std::string& sDataTable = _accessParser.getDataObject();
3700 bool openEnd = _idx.col.isOpenEnd();
3701
3702 // fill the open end indices
3703 _accessParser.evalIndices();
3704
3705 if (!_accessParser.isCluster())
3706 {
3707 if (_idx.row.last() >= _data.getLines(sDataTable, false))
3708 _idx.row.setRange(0, _data.getLines(sDataTable, false)-1);
3709
3710 if (_idx.col.last() >= _data.getCols(sDataTable) && _pInfo.sCommand != "plot3d")
3711 _idx.col.setRange(0, _data.getCols(sDataTable)-1);
3712 }
3713 else
3714 {
3715 if (_idx.row.last() >= (int)_data.getCluster(sDataTable).size())
3716 _idx.row.setRange(0, _data.getCluster(sDataTable).size()-1);
3717 }
3718
3719 // Validize the indices depending on whether a cluster or
3720 // a table is used for the current data access
3721 if (_accessParser.isCluster())
3722 {
3723 if (_idx.row.front() >= (int)_data.getCluster(sDataTable).size())
3725 }
3726 else
3727 {
3728 if (_idx.row.front() >= _data.getLines(sDataTable, false)
3729 || (_idx.col.front() >= _data.getCols(sDataTable) && _pInfo.sCommand != "plot3d"))
3731 }
3732
3734 {
3735 size_t datarows = 1;
3736
3738 datarows = 3;
3740 datarows = 2;
3741 else if (_idx.col.numberOfNodes() >= 2)
3743
3744 m_manager.assets[typeCounter].create1DPlot(PT_DATA, _idx.row.size(), datarows);
3745
3746 if (m_manager.assets[typeCounter].type == PT_NONE)
3748
3749 // A vector index was used. Insert a column index
3750 // if the current plot is a boxplot or an axis coordinate
3751 // is missing
3753 _idx.col.prepend(std::vector<int>({-1}));
3754
3755 if (_idx.col.front() == VectorIndex::INVALID)
3756 {
3757 for (size_t n = 0; n < _idx.row.size(); n++)
3758 m_manager.assets[typeCounter].writeAxis(n+1.0, n, XCOORD);
3759 }
3760 else
3761 {
3762 std::vector<mu::value_type> vAxis = getDataFromObject(_accessParser.getDataObject(),
3763 _idx.row, _idx.col.front(),
3764 _accessParser.isCluster());
3765
3766 for (size_t n = 0; n < vAxis.size(); n++)
3767 {
3768 m_manager.assets[typeCounter].writeAxis(vAxis[n].real(), n, XCOORD);
3769 }
3770 }
3771
3772 // Fill the mglData objects with the data from the
3773 // referenced data object
3774 if (datarows == 1 && _idx.col.numberOfNodes() == 2 && !openEnd)
3775 {
3776 std::vector<mu::value_type> vVals = getDataFromObject(_accessParser.getDataObject(),
3777 _idx.row, _idx.col.last(),
3778 _accessParser.isCluster());
3779
3780 for (size_t n = 0; n < vVals.size(); n++)
3781 {
3782 m_manager.assets[typeCounter].writeData(vVals[n], 0, n);
3783 }
3784 }
3785 else
3786 {
3787 for (size_t q = 0; q < datarows; q++)
3788 {
3789 if (q >= _idx.col.size())
3790 {
3791 // Write zeroes for errorbars or similar
3792 for (size_t n = 0; n < _idx.row.size(); n++)
3793 m_manager.assets[typeCounter].writeData(0.0, q, n);
3794 }
3795 else if (_idx.col[q+1] == VectorIndex::INVALID)
3796 {
3797 for (size_t n = 0; n < _idx.row.size(); n++)
3798 m_manager.assets[typeCounter].writeData(n+1.0, q, n);
3799 }
3800 else
3801 {
3802 std::vector<mu::value_type> vVals = getDataFromObject(_accessParser.getDataObject(),
3803 _idx.row, _idx.col[q+1],
3804 _accessParser.isCluster());
3805
3806 for (size_t n = 0; n < vVals.size(); n++)
3807 {
3808 m_manager.assets[typeCounter].writeData(vVals[n], q, n);
3809 }
3810 }
3811 }
3812 }
3813
3814 bool isHbar = _pData.getSettings(PlotData::FLOAT_HBARS) != 0.0;
3815 bool isMultiDataSet = _pData.getSettings(PlotData::FLOAT_HBARS) != 0.0
3819
3820
3821 // Calculate the data ranges
3822 if (_pData.getSettings(PlotData::LOG_PARAMETRIC) && typeCounter < (m_manager.assets.size() / 2) * 2)
3823 {
3824 Interval range = m_manager.assets[typeCounter].getDataIntervals(0)[datIvlID];
3825
3826 for (size_t layer = 1; layer < std::max(1u, isMultiDataSet*m_manager.assets[typeCounter].getLayers()); layer++)
3827 {
3828 range = range.combine(m_manager.assets[typeCounter].getDataIntervals(layer)[datIvlID]);
3829 }
3830
3831 if (!(typeCounter % 2) && m_manager.assets[typeCounter].boundAxes.find('t') != std::string::npos)
3832 secDataRanges[XRANGE+isHbar] = secDataRanges[XRANGE+isHbar].combine(range);
3833
3834 dataRanges[(typeCounter+isHbar) % 2] = dataRanges[(typeCounter+isHbar) % 2].combine(range);
3835 }
3836 else
3837 {
3838 Interval axisrange = m_manager.assets[typeCounter].getAxisInterval(XCOORD);
3839
3840 if (m_manager.assets[typeCounter].boundAxes.find('t') != std::string::npos)
3841 secDataRanges[XRANGE+isHbar] = secDataRanges[XRANGE+isHbar].combine(axisrange);
3842 else
3843 dataRanges[XRANGE+isHbar] = dataRanges[XRANGE+isHbar].combine(axisrange);
3844
3845 for (size_t layer = 0; layer < std::max(1u, isMultiDataSet*m_manager.assets[typeCounter].getLayers()); layer++)
3846 {
3847 IntervalSet datIvl = m_manager.assets[typeCounter].getDataIntervals(layer);
3848
3849 if (m_manager.assets[typeCounter].boundAxes.find('r') != std::string::npos)
3850 secDataRanges[YRANGE-isHbar] = secDataRanges[YRANGE-isHbar].combine(datIvl[datIvlID]);
3851 else
3852 dataRanges[YRANGE-isHbar] = dataRanges[YRANGE-isHbar].combine(datIvl[datIvlID]);
3853 }
3854 }
3855 }
3856 else if (isPlot3D(_pInfo.sCommand))
3857 {
3858 size_t datarows = 1;
3859
3861 datarows = 2;
3862 else if (_idx.col.numberOfNodes() > 2)
3863 datarows = _idx.col.numberOfNodes() - 1;
3864
3865 m_manager.assets[typeCounter].create3DPlot(PT_DATA, _idx.row.size(), datarows);
3866 m_manager.assets[typeCounter].boundAxes = "lb";
3867
3868 if (m_manager.assets[typeCounter].type == PT_NONE)
3870
3871 for (size_t q = 0; q < 3*datarows; q++)
3872 {
3873 // If the column is invalid or completely empty, then
3874 // use zeros to fill it
3875 if (_idx.col[q] == VectorIndex::INVALID
3876 || !_data.getColElements(_idx.col.subidx(q, 1), _accessParser.getDataObject()))
3877 {
3878 for (size_t t = 0; t < _idx.row.size(); t++)
3879 m_manager.assets[typeCounter].writeData(0.0, q, t);
3880 }
3881 else
3882 {
3883 std::vector<mu::value_type> vVals = getDataFromObject(_accessParser.getDataObject(),
3884 _idx.row, _idx.col[q],
3885 _accessParser.isCluster());
3886
3887 for (size_t t = 0; t < vVals.size(); t++)
3888 {
3889 m_manager.assets[typeCounter].writeData(vVals[t], q, t);
3890 }
3891 }
3892 }
3893
3894 // Calculate the data ranges
3895 if (_pData.getSettings(PlotData::LOG_PARAMETRIC) && typeCounter < (m_manager.assets.size() / 3) * 3)
3896 dataRanges[typeCounter%3] = dataRanges[typeCounter%3].combine(m_manager.assets[typeCounter].getDataIntervals(0)[datIvlID3D]);
3897 else
3898 {
3899 for (size_t c = XCOORD; c <= ZCOORD; c++)
3900 dataRanges[c] = dataRanges[c].combine(m_manager.assets[typeCounter].getDataIntervals(c)[datIvlID]);
3901 }
3902 }
3903 else if (isMesh2D(_pInfo.sCommand))
3904 {
3905 bool isBars = _pInfo.sCommand == "dens" && _pData.getSettings(PlotData::FLOAT_BARS) > 0;
3906 std::vector<size_t> samples = _accessParser.getDataGridDimensions();
3907
3908 // Density plots with bars enabled need
3909 // one additional element per axis
3910 if (isBars)
3911 {
3912 samples.front()++;
3913 samples.back()++;
3914 }
3915
3916 m_manager.assets[typeCounter].create2DMesh(PT_DATA, samples, 1);
3917 m_manager.assets[typeCounter].boundAxes = "lb";
3918
3919 if (m_manager.assets[typeCounter].type == PT_NONE)
3921
3922 // Write the axes (do not write the additional value for
3923 // the bar-density mixture)
3924 for (size_t axis = 0; axis < samples.size(); axis++)
3925 {
3926 std::vector<mu::value_type> vAxis = getDataFromObject(_accessParser.getDataObject(),
3927 _idx.row, _idx.col[axis],
3928 _accessParser.isCluster());
3929
3930 for (size_t m = 0; m < std::min(samples[axis]-isBars, vAxis.size()); m++)
3931 {
3932 m_manager.assets[typeCounter].writeAxis(vAxis[m].real(), m, (PlotCoords)axis);
3933 }
3934 }
3935
3936 // For bars and density plots, we simply repeat the last
3937 // axis step distance to add another axis value
3938 if (isBars)
3939 {
3940 double diff = m_manager.assets[typeCounter].axes[XCOORD].a[samples.front()-2]
3941 - m_manager.assets[typeCounter].axes[XCOORD].a[samples.front()-3];
3942 m_manager.assets[typeCounter].axes[XCOORD].a[samples.front()-1] = diff
3943 + m_manager.assets[typeCounter].axes[XCOORD].a[samples.front()-2];
3944
3945 diff = m_manager.assets[typeCounter].axes[YCOORD].a[samples.back()-2]
3946 - m_manager.assets[typeCounter].axes[YCOORD].a[samples.back()-3];
3947 m_manager.assets[typeCounter].axes[YCOORD].a[samples.back()-1] = diff
3948 + m_manager.assets[typeCounter].axes[YCOORD].a[samples.back()-2];
3949 }
3950
3951 // Write the meshgrid data
3952 #pragma omp parallel for
3953 for (size_t y = 0; y < samples[1]-isBars; y++)
3954 {
3955 std::vector<mu::value_type> vVals = getDataFromObject(_accessParser.getDataObject(),
3956 _idx.row, _idx.col[y+2],
3957 _accessParser.isCluster());
3958
3959 for (size_t x = 0; x < std::min(samples[0]-isBars, vVals.size()); x++)
3960 {
3961 m_manager.assets[typeCounter].writeData(vVals[x], 0, x, y);
3962 }
3963 }
3964
3965 // Calculate the data ranges
3966 if (_pData.getSettings(PlotData::LOG_PARAMETRIC) && typeCounter < (m_manager.assets.size() / 3) * 3)
3967 dataRanges[typeCounter%3] = dataRanges[typeCounter%3].combine(m_manager.assets[typeCounter].getDataIntervals(0)[datIvlID3D]);
3968 else
3969 {
3970 dataRanges[XRANGE] = dataRanges[XRANGE].combine(m_manager.assets[typeCounter].getAxisInterval(XCOORD));
3971 dataRanges[YRANGE] = dataRanges[YRANGE].combine(m_manager.assets[typeCounter].getAxisInterval(YCOORD));
3972
3973 if (_pInfo.sCommand == "implot")
3974 dataRanges[ZRANGE] = dataRanges[ZRANGE].combine(Interval(0.0, 255.0));
3975 else
3976 dataRanges[ZRANGE] = dataRanges[ZRANGE].combine(m_manager.assets[typeCounter].getDataIntervals(0)[datIvlID3D]);
3977 }
3978 }
3979 else if (isVect2D(_pInfo.sCommand))
3980 {
3981
3982 std::vector<size_t> samples = _accessParser.getDataGridDimensions();
3983
3984 m_manager.assets[typeCounter].create2DMesh(PT_DATA, samples, 1);
3985 m_manager.assets[typeCounter].boundAxes = "lb";
3986
3987 if (m_manager.assets[typeCounter].type == PT_NONE)
3989
3990 // Write the axes
3991 for (size_t axis = 0; axis < samples.size(); axis++)
3992 {
3993 std::vector<mu::value_type> vAxis = getDataFromObject(_accessParser.getDataObject(),
3994 _idx.row, _idx.col[axis],
3995 _accessParser.isCluster());
3996
3997 for (size_t m = 0; m < std::min(samples[axis], vAxis.size()); m++)
3998 {
3999 m_manager.assets[typeCounter].writeAxis(vAxis[m].real(), m, (PlotCoords)axis);
4000 }
4001 }
4002
4003 // Write the complex vector data
4004 #pragma omp parallel for
4005 for (size_t y = 0; y < samples[1]; y++)
4006 {
4007 std::vector<mu::value_type> vVals = getDataFromObject(_accessParser.getDataObject(),
4008 _idx.row, _idx.col[y+2],
4009 _accessParser.isCluster());
4010
4011 for (size_t x = 0; x < std::min(samples[0], vVals.size()); x++)
4012 {
4013 m_manager.assets[typeCounter].writeData(vVals[x], 0, x, y);
4014 }
4015 }
4016
4017 // Calculate the data ranges
4018 //if (_pData.getSettings(PlotData::LOG_PARAMETRIC) && typeCounter < (m_manager.assets.size() / 3) * 3)
4019 // dataRanges[typeCounter%3] = dataRanges[typeCounter%3].combine(m_manager.assets[typeCounter].getDataIntervals(0)[datIvlID3D]);
4020 //else
4021 //{
4022 dataRanges[XRANGE] = dataRanges[XRANGE].combine(m_manager.assets[typeCounter].getAxisInterval(XCOORD));
4023 dataRanges[YRANGE] = dataRanges[YRANGE].combine(m_manager.assets[typeCounter].getAxisInterval(YCOORD));
4024 dataRanges[ZRANGE] = dataRanges[ZRANGE].combine(m_manager.assets[typeCounter].getDataIntervals(0)[datIvlID3D]);
4025 //}
4026 }
4027 else
4029
4030 typeCounter++;
4031 }
4032}
4033
4034
4043{
4044 // Examine all data labels
4045 for (size_t i = 0; i < m_manager.assets.size(); i++)
4046 {
4047 if (m_types[i] != PT_DATA)
4048 continue;
4049
4050 // Extraxt the current label and
4051 // remove the surrounding quotation marks
4052 std::string sTemp = removeQuotationMarks(m_manager.assets[i].legend);
4053
4054 // Try to find a data object in the current label
4055 if (_data.containsTables(sTemp)
4056 && (sTemp.find(',') != string::npos || sTemp.substr(sTemp.find('('), 2) == "()")
4057 && sTemp.find(')') != string::npos)
4058 {
4059 // Ensure that the referenced data object contains valid data
4062
4063 // Strip all spaces and extract the table name
4064 StripSpaces(sTemp);
4065 string sTableName = sTemp.substr(0, sTemp.find('('));
4066
4067 // Ensure that the parentheses are matching each other
4068 if (getMatchingParenthesis(sTemp.substr(sTemp.find('('))) == string::npos)
4069 throw SyntaxError(SyntaxError::UNMATCHED_PARENTHESIS, sTemp, sTemp.find('('));
4070
4071 // Extract the argument of the data object
4072 string sArgs = sTemp.substr(sTemp.find('('), getMatchingParenthesis(sTemp.substr(sTemp.find('('))) + 1);
4073
4074 // Update the data dimension variables
4075 _data.updateDimensionVariables(sTableName);
4076
4077 // Expand empty parentheses
4078 if (sArgs == "()")
4079 sArgs = ":,:";
4080 else
4081 sArgs = sArgs.substr(1, sArgs.length()-2);
4082
4083 string sArg_1 = sArgs;
4084 string sArg_2 = "<<empty>>";
4085 string sArg_3 = "<<empty>>";
4086
4087 // Get the second dimension of the argument parentheses
4088 getNextArgument(sArg_1, true);
4089 StripSpaces(sArg_1);
4090
4091 // If the second dimension contains one or more colons,
4092 // extract the individual columns here
4093 if (sArg_1 == ":")
4094 {
4095 sArg_1 = "";
4096 sArg_2 = "";
4097 }
4098 else if (sArg_1.find(':') != string::npos)
4099 {
4100 auto indices = getAllIndices(sArg_1);
4101 sArg_1 = indices[0];
4102
4103 if (indices.size() > 1)
4104 {
4105 sArg_2 = indices[1];
4106
4107 if (indices.size() > 2)
4108 sArg_3 = indices[2];
4109 }
4110 else if (_data.containsTablesOrClusters(sArg_1))
4111 {
4113 }
4114 }
4115
4116 // Strip surrounding whitespaces
4117 StripSpaces(sArg_1);
4118
4119 // Handle special cases
4120 if (!sArg_1.length() && !sArg_2.length() && sArg_3 == "<<empty>>")
4121 {
4122 sArg_1 = "1";
4123 }
4124 else if (!sArg_1.length())
4125 continue;
4126
4127 // Parse the single arguments to extract the corresponding
4128 // headline elements
4129 if (sArg_2 == "<<empty>>" && sArg_3 == "<<empty>>" && _pInfo.sCommand != "plot3d")
4130 {
4131 // Only one index or an index vector
4132 sTemp = "\"" + constructDataLegendElement(sArg_1, sTableName) + "\"";
4133 }
4134 else if (sArg_2.length())
4135 {
4136 // First and second index value available
4137 if (_pInfo.sCommand != "plot3d")
4138 {
4139 // Standard plot
4141 {
4142 // Handle here barcharts
4144 {
4145 double dArg_1, dArg_2;
4146 _parser.SetExpr(sArg_1);
4147 dArg_1 = _parser.Eval().real();
4148 _parser.SetExpr(sArg_2);
4149 dArg_2 = _parser.Eval().real();
4150 sTemp = "\"";
4151
4152 // Don't use the first one
4153 for (int i = intCast(dArg_1); i < intCast(dArg_2); i++)
4154 {
4155 sTemp += _data.getTopHeadLineElement(i, sTableName) + "\n";
4156 }
4157
4158 sTemp.pop_back();
4159 sTemp += "\"";
4160 }
4161 else
4162 sTemp = "\"" + constructDataLegendElement(sArg_2, sTableName)
4163 + " vs. " + constructDataLegendElement(sArg_1, sTableName) + "\"";
4164 }
4165 else if (sArg_3 != "<<empty>>")
4166 sTemp = "\"" + constructDataLegendElement(sArg_2, sTableName)
4167 + " vs. " + constructDataLegendElement(sArg_1, sTableName) + "\"";
4168 else
4169 {
4170 double dArg_1, dArg_2;
4171 _parser.SetExpr(sArg_1);
4172 dArg_1 = _parser.Eval().real();
4173 _parser.SetExpr(sArg_2);
4174 dArg_2 = _parser.Eval().real();
4175
4176 if (dArg_1 < dArg_2)
4177 sTemp = "\"" + _data.getTopHeadLineElement((int)dArg_1, sTableName)
4178 + " vs. " + _data.getTopHeadLineElement((int)dArg_1 - 1, sTableName) + "\"";
4179 else
4180 sTemp = "\"" + _data.getTopHeadLineElement((int)dArg_2 - 1, sTableName)
4181 + " vs. " + _data.getTopHeadLineElement((int)dArg_2, sTableName) + "\"";
4182 }
4183 }
4184 else if (sArg_3 == "<<empty>>" || !sArg_3.length())
4185 {
4186 // three-dimensional plot
4187 double dArg_1, dArg_2;
4188 _parser.SetExpr(sArg_1);
4189 dArg_1 = _parser.Eval().real();
4190 _parser.SetExpr(sArg_2);
4191 dArg_2 = _parser.Eval().real();
4192
4193 if (dArg_1 < dArg_2)
4194 sTemp = "\"" + _data.getTopHeadLineElement((int)dArg_1 - 1, sTableName) + ", "
4195 + _data.getTopHeadLineElement((int)dArg_2 - 2, sTableName) + ", "
4196 + _data.getTopHeadLineElement((int)dArg_2 - 1, sTableName) + "\"";
4197 else
4198 sTemp = "\"" + _data.getTopHeadLineElement((int)dArg_2 - 1, sTableName) + ", "
4199 + _data.getTopHeadLineElement((int)dArg_1 - 2, sTableName) + ", "
4200 + _data.getTopHeadLineElement((int)dArg_1 - 1, sTableName) + "\"";
4201 }
4202 else if (sArg_3.length())
4203 {
4204 // Three dimensional plot
4205 sTemp = "\"" + constructDataLegendElement(sArg_1, sTableName) + ", "
4206 + constructDataLegendElement(sArg_2, sTableName) + ", "
4207 + constructDataLegendElement(sArg_3, sTableName) + "\"";
4208 }
4209 }
4210 else if (!sArg_2.length())
4211 {
4212 // second index open end
4213 if (_pInfo.sCommand != "plot3d")
4214 {
4215 // Handle here barcharts
4217 {
4218 double dArg_1;
4219 _parser.SetExpr(sArg_1);
4220 dArg_1 = _parser.Eval().real();
4221
4222 sTemp = "\"";
4223
4224 // Don't use the first one
4225 for (int i = intCast(dArg_1); i < _data.getCols(sTableName, false); i++)
4226 {
4227 sTemp += _data.getTopHeadLineElement(i, sTableName) + "\n";
4228 }
4229
4230 sTemp.pop_back();
4231 sTemp += "\"";
4232 }
4233 else
4234 {
4235 _parser.SetExpr(sArg_1);
4236 sTemp = "\"" + _data.getTopHeadLineElement(intCast(_parser.Eval()), sTableName)
4237 + " vs. " + _data.getTopHeadLineElement(intCast(_parser.Eval()) - 1, sTableName) + "\"";
4238 }
4239 }
4240 else if (sArg_3 == "<<empty>>" || !sArg_3.length())
4241 {
4242 _parser.SetExpr(sArg_1);
4243 sTemp = "\"" + _data.getTopHeadLineElement(intCast(_parser.Eval()) - 1, sTableName) + ", "
4244 + _data.getTopHeadLineElement(intCast(_parser.Eval()), sTableName) + ", "
4245 + _data.getTopHeadLineElement(intCast(_parser.Eval()) + 1, sTableName) + "\"";
4246 }
4247 else if (sArg_3.length())
4248 {
4249 _parser.SetExpr(sArg_1);
4250 sTemp = "\"" + _data.getTopHeadLineElement(intCast(_parser.Eval()) - 1, sTableName)
4251 + ", " + _data.getTopHeadLineElement(intCast(_parser.Eval()), sTableName) + ", ";
4252 sTemp += constructDataLegendElement(sArg_3, sTableName) + "\"";
4253 }
4254 }
4255 else
4256 continue;
4257
4258 // Prepend backslashes before opening and closing
4259 // braces
4260 for (size_t i = 0; i < sTemp.size(); i++)
4261 {
4262 if (sTemp[i] == '{' || sTemp[i] == '}')
4263 {
4264 sTemp.insert(i, 1, '\\');
4265 i++;
4266 }
4267 }
4268
4269 // Replace the data expression with the parsed headlines
4270 m_manager.assets[i].legend = sTemp;
4271 }
4272 }
4273}
4274
4275
4285string Plot::constructDataLegendElement(string& sColumnIndices, const string& sTableName)
4286{
4287 if (NumeReKernel::getInstance()->getMemoryManager().containsTablesOrClusters(sColumnIndices))
4288 getDataElements(sColumnIndices, _parser, NumeReKernel::getInstance()->getMemoryManager(), NumeReKernel::getInstance()->getSettings());
4289
4290 value_type* v = nullptr;
4291 int nResults = 0;
4292
4293 // Set the expression and evaluate it
4294 _parser.SetExpr(sColumnIndices);
4295 v = _parser.Eval(nResults);
4296
4297 // If only one value, simply return the corresponding head line
4298 if (nResults == 1)
4299 return _data.getTopHeadLineElement(intCast(v[0]) - 1, sTableName);
4300
4301 string sFirst = "[";
4302 string sLast = "]";
4303 char cSep = ',';
4304 int nStart = 0;
4305
4306 // Barcharts and boxplots will need other legend strings
4308 {
4309 sFirst.clear();
4310 sLast.clear();
4311 cSep = '\n';
4312 nStart = 1;
4313 }
4314
4315 string sLegend = sFirst;
4316
4317 // combine the legend strings
4318 for (int i = nStart; i < nResults; i++)
4319 {
4320 sLegend += _data.getTopHeadLineElement(intCast(v[i]) - 1, sTableName);
4321 if (i + 1 < nResults)
4322 sLegend += cSep;
4323 }
4324 return sLegend + sLast;
4325}
4326
4327
4336size_t Plot::countValidElements(const mglData& _mData)
4337{
4338 size_t nElements = 0;
4339
4340 // Go through the array
4341 for (int i = 0; i < _mData.nx; i++)
4342 {
4343 // count only non-nans
4344 if (!isnan(_mData.a[i]))
4345 nElements++;
4346 }
4347
4348 // return the number of elements
4349 return nElements;
4350}
4351
4352
4362{
4364 {
4365 for (size_t i = 0; i < m_types.size(); i++)
4366 {
4367 if (m_types[i] == PT_FUNCTION)
4368 m_manager.assets[i].create1DPlot(PT_FUNCTION, _pInfo.nSamples);
4369 }
4370 }
4371 else if (isPlot3D(_pInfo.sCommand))
4372 {
4373 for (size_t i = 0; i < m_types.size(); i++)
4374 {
4375 if (m_types[i] == PT_FUNCTION)
4376 m_manager.assets[i].create3DPlot(PT_FUNCTION, _pInfo.nSamples);
4377 }
4378 }
4379 else if (isMesh2D(_pInfo.sCommand))
4380 {
4381 for (size_t i = 0; i < m_types.size(); i++)
4382 {
4383 if (m_types[i] == PT_FUNCTION)
4384 m_manager.assets[i].create2DMesh(PT_FUNCTION, std::vector<size_t>(2, _pInfo.nSamples));
4385 }
4386 }
4387 else if (isMesh3D(_pInfo.sCommand))
4388 {
4389 for (size_t i = 0; i < m_types.size(); i++)
4390 {
4391 if (m_types[i] == PT_FUNCTION)
4392 m_manager.assets[i].create3DMesh(PT_FUNCTION, std::vector<size_t>(3, _pInfo.nSamples));
4393 }
4394 }
4395 else if (isVect2D(_pInfo.sCommand))
4396 {
4397 for (size_t i = 0; i < m_types.size(); i++)
4398 {
4399 if (m_types[i] == PT_FUNCTION)
4400 m_manager.assets[i].create2DVect(PT_FUNCTION, std::vector<size_t>(2, _pInfo.nSamples));
4401 }
4402 }
4403 else if (isVect3D(_pInfo.sCommand))
4404 {
4405 for (size_t i = 0; i < m_types.size(); i++)
4406 {
4407 if (m_types[i] == PT_FUNCTION)
4408 m_manager.assets[i].create3DVect(PT_FUNCTION, std::vector<size_t>(3, _pInfo.nSamples));
4409 }
4410 }
4411}
4412
4413
4428void Plot::defaultRanges(size_t nPlotCompose, bool bNewSubPlot)
4429{
4430 if (!nPlotCompose || bNewSubPlot)
4431 {
4433
4434 // --> Standard-Ranges zuweisen: wenn weniger als i+1 Ranges gegeben sind und Datenranges vorhanden sind, verwende die Datenranges <--
4435 for (int i = XCOORD; i <= ZCOORD; i++)
4436 {
4437 if (_pInfo.bDraw3D || _pInfo.bDraw)
4438 continue;
4439
4441 {
4442 if ((isinf(dataRanges[i].front()) || isnan(dataRanges[i].front())) && (unsigned)i < _pInfo.nMaxPlotDim)
4443 {
4444 clearData();
4446 }
4447 else if (!(isinf(dataRanges[i].front()) || isnan(dataRanges[i].front())))
4448 _pInfo.ranges[i] = dataRanges[i];
4449
4450 if (i < 2 && !isinf(secDataRanges[i].front()) && !isnan(secDataRanges[i].front()))
4452 }
4453 else if (i)
4455
4456 if (!isnan(_pData.getAddAxis(i).ivl.min()))
4458 }
4459
4460 // --> Spezialfall: Wenn nur eine Range gegeben ist, verwende im 3D-Fall diese fuer alle drei benoetigten Ranges <--
4461 if (_pData.getGivenRanges() == 1 && (_pInfo.b3D || _pInfo.b3DVect))
4462 {
4463 _pInfo.ranges[YRANGE].reset(_pInfo.ranges[XRANGE].front(), _pInfo.ranges[XRANGE].back());
4464 _pInfo.ranges[ZRANGE].reset(_pInfo.ranges[XRANGE].front(), _pInfo.ranges[XRANGE].back());
4465 }
4466 }
4467 // --> Sonderkoordinatensaetze und dazu anzugleichende Ranges. Noch nicht korrekt implementiert <--
4469 {
4470 /* --> Im Falle logarithmischer Plots muessen die Darstellungsintervalle angepasst werden. Falls
4471 * die Intervalle zu Teilen im Negativen liegen, versuchen wir trotzdem etwas sinnvolles
4472 * daraus zu machen. <--
4473 */
4474 for (size_t i = XRANGE; i <= ZRANGE; i++)
4475 {
4476 if (_pData.getLogscale(i) && (i != ZRANGE || (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect)))
4477 {
4478 if (_pInfo.ranges[i].min() <= 0 && _pInfo.ranges[i].max() > 0)
4479 _pInfo.ranges[i].reset(_pInfo.ranges[i].max() * 1e-3, _pInfo.ranges[i].max());
4480 else if (_pInfo.ranges[i].min() < 0 && _pInfo.ranges[i].max() <= 0)
4481 {
4482 clearData();
4484 }
4485 }
4486
4487 }
4488 }
4490 {
4491 // --> Im Falle polarer oder sphaerischer Koordinaten muessen die Darstellungsintervalle angepasst werden <--
4495 {
4496 if (_pInfo.sCommand.find("3d") == string::npos && !_pInfo.b2DVect)
4497 {
4498 int nRCoord = ZCOORD;
4499 int nPhiCoord = XCOORD;
4500
4502 {
4503 nRCoord = XCOORD;
4504 nPhiCoord = YRANGE;
4505 }
4507 {
4508 nRCoord = XCOORD;
4509 nPhiCoord = ZCOORD;
4510 }
4511 else if (!(_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect || _pInfo.b2DVect))
4512 nRCoord = YRANGE;
4513
4514 if (!_pData.getRangeSetting(nRCoord))
4515 _pInfo.ranges[nRCoord].reset(0.0, _pInfo.ranges[nRCoord].max());
4516
4517 if (!_pData.getRangeSetting(nPhiCoord))
4518 _pInfo.ranges[nPhiCoord].reset(0.0, 2.0 * M_PI);
4519 }
4520 else
4521 {
4522 _pInfo.ranges[XRANGE].reset(0.0, _pInfo.ranges[XRANGE].max());
4523
4525 _pInfo.ranges[YRANGE].reset(0.0, 2.0 * M_PI);
4526 }
4527 }
4531 {
4532 if (_pInfo.sCommand.find("3d") == string::npos)
4533 {
4534 int nRCoord = ZCOORD;
4535 int nPhiCoord = XCOORD;
4536 int nThetaCoord = YCOORD;
4537
4539 {
4540 nRCoord = XCOORD;
4541 nPhiCoord = YCOORD;
4542 nThetaCoord = ZCOORD;
4543 }
4545 {
4546 nRCoord = XCOORD;
4547 nPhiCoord = ZCOORD;
4548 nThetaCoord = YCOORD;
4549 }
4550 else if (!(_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect || _pInfo.b2DVect))
4551 {
4552 nRCoord = YCOORD;
4553 nThetaCoord = ZCOORD;
4554 }
4555
4556 if (!_pData.getRangeSetting(nRCoord))
4557 _pInfo.ranges[nRCoord].reset(0.0, _pInfo.ranges[nRCoord].max());
4558
4559 if (!_pData.getRangeSetting(nPhiCoord))
4560 _pInfo.ranges[nPhiCoord].reset(0.0, 2.0 * M_PI);
4561
4562 if (!_pData.getRangeSetting(nThetaCoord))
4563 _pInfo.ranges[nThetaCoord].reset(0.0, M_PI);
4564 }
4565 else
4566 {
4567 _pInfo.ranges[XRANGE].reset(0.0, _pInfo.ranges[XRANGE].max());
4568
4570 _pInfo.ranges[YRANGE].reset(0.0, 2.0 * M_PI);
4571
4573 _pInfo.ranges[ZRANGE].reset(0.0, M_PI);
4574 }
4575 }
4576 }
4577}
4578
4579
4589void Plot::fillData(double dt_max, int t_animate)
4590{
4591 mu::value_type* vResults = nullptr;
4592
4593 if (!sFunc.length())
4594 return;
4595
4596 std::vector<size_t> vFuncMap;
4597
4598 for (size_t i = 0; i < m_types.size(); i++)
4599 {
4600 if (m_types[i] == PT_FUNCTION)
4601 vFuncMap.push_back(i);
4602 }
4603
4605 {
4606 if (sFunc.find('{') != string::npos && !_pInfo.bDraw3D && !_pInfo.bDraw)
4608
4609 for (int x = 0; x < _pInfo.nSamples; x++)
4610 {
4611 if (x != 0)
4612 {
4615 else
4617 }
4618
4619 vResults = _parser.Eval(_pInfo.nFunctions);
4620
4621 if ((size_t)_pInfo.nFunctions != vFuncMap.size())
4622 throw SyntaxError(SyntaxError::PLOT_ERROR, "", "");
4623
4624 for (int i = 0; i < _pInfo.nFunctions; i++)
4625 {
4626 m_manager.assets[vFuncMap[i]].writeAxis(_defVars.vValue[XCOORD][0].real(), x, XCOORD);
4627 m_manager.assets[vFuncMap[i]].writeData(vResults[i], 0, x);
4628 }
4629 }
4630 }
4631 else if (isPlot3D(_pInfo.sCommand))
4632 {
4634
4635 for (size_t k = 0; k < vFuncMap.size(); k++)
4636 {
4637 _defVars.vValue[XCOORD][0] = 0.0;
4638 _defVars.vValue[YCOORD][0] = 0.0;
4639 _defVars.vValue[ZCOORD][0] = 0.0;
4640
4641 if (expressions[k].find('{') != string::npos && !_pInfo.bDraw3D && !_pInfo.bDraw)
4642 convertVectorToExpression(expressions[k], _option);
4643
4644 _parser.SetExpr(expressions[k]);
4645 vResults = _parser.Eval(_pInfo.nFunctions);
4646
4647 _defVars.vValue[TCOORD][0] = _pInfo.ranges[TRANGE].front();
4648 _defVars.vValue[XCOORD][0] = vResults[XCOORD];
4649
4650 if (YCOORD < _pInfo.nFunctions)
4651 _defVars.vValue[YCOORD][0] = vResults[YCOORD];
4652
4653 if (ZCOORD < _pInfo.nFunctions)
4654 _defVars.vValue[ZCOORD][0] = vResults[ZCOORD];
4655
4656 int nRenderSamples = _pInfo.nSamples;
4657
4658 for (int t = 0; t < nRenderSamples; t++)
4659 {
4660 if (t != 0)
4661 {
4663 {
4664 double dSamples = 1.0;
4665
4666 if ((t_animate * 100.0) / _pData.getAnimateSamples() <= 25.0)
4667 dSamples = (double)(_pInfo.nSamples - 1) * 0.25;
4668 else if ((t_animate * 100.0) / _pData.getAnimateSamples() <= 50.0)
4669 dSamples = (double)(_pInfo.nSamples - 1) * 0.5;
4670 else if ((t_animate * 100.0) / _pData.getAnimateSamples() <= 75.0)
4671 dSamples = (double)(_pInfo.nSamples - 1) * 0.75;
4672 else
4673 dSamples = (double)(_pInfo.nSamples - 1);
4674
4675 nRenderSamples = (int)dSamples + 1;
4676 _defVars.vValue[TCOORD][0] += (dt_max - _pInfo.ranges[TRANGE].front()) / dSamples;
4677 }
4678 else
4680
4681 _defVars.vValue[XCOORD][0] = m_manager.assets[vFuncMap[k]].data[XCOORD].first.a[t-1];
4682 _defVars.vValue[YCOORD][0] = m_manager.assets[vFuncMap[k]].data[YCOORD].first.a[t-1];
4683 _defVars.vValue[ZCOORD][0] = m_manager.assets[vFuncMap[k]].data[ZCOORD].first.a[t-1];
4684 }
4685
4686 // --> Wir werten alle Koordinatenfunktionen zugleich aus und verteilen sie auf die einzelnen Parameterkurven <--
4687 vResults = _parser.Eval(_pInfo.nFunctions);
4688
4689 for (int i = XCOORD; i <= ZCOORD; i++)
4690 {
4691 if (i >= _pInfo.nFunctions)
4692 m_manager.assets[vFuncMap[k]].writeData(0.0, i, t);
4693 else
4694 m_manager.assets[vFuncMap[k]].writeData(vResults[i], i, t);
4695 }
4696 }
4697
4698 for (int t = nRenderSamples; t < _pInfo.nSamples; t++)
4699 {
4700 for (int i = XCOORD; i <= ZCOORD; i++)
4701 m_manager.assets[vFuncMap[k]].writeData(NAN, i, t);
4702 }
4703 }
4704
4705 _defVars.vValue[TCOORD][0] = dt_max;
4706 }
4707 else if (isMesh2D(_pInfo.sCommand))
4708 {
4709 if (sFunc.find('{') != string::npos && !_pInfo.bDraw3D && !_pInfo.bDraw)
4711
4712 for (int x = 0; x < _pInfo.nSamples; x++)
4713 {
4714 if (x != 0)
4715 {
4718 else
4720 }
4721
4722 for (int y = 0; y < _pInfo.nSamples; y++)
4723 {
4726 else
4728
4729 vResults = _parser.Eval(_pInfo.nFunctions);
4730
4731 if ((size_t)_pInfo.nFunctions != vFuncMap.size())
4732 throw SyntaxError(SyntaxError::PLOT_ERROR, "", "");
4733
4734 for (size_t i = 0; i < vFuncMap.size(); i++)
4735 {
4736 m_manager.assets[vFuncMap[i]].writeAxis(_defVars.vValue[XCOORD][0].real(), x, XCOORD);
4737 m_manager.assets[vFuncMap[i]].writeAxis(_defVars.vValue[YCOORD][0].real(), y, YCOORD);
4738 m_manager.assets[vFuncMap[i]].writeData(vResults[i], 0, x, y);
4739 }
4740 }
4741 }
4742 }
4743 else if (isMesh3D(_pInfo.sCommand))
4744 {
4745 if (sFunc.find('{') != string::npos && !_pInfo.bDraw3D && !_pInfo.bDraw)
4747
4748 for (int x = 0; x < _pInfo.nSamples; x++)
4749 {
4750 if (x != 0)
4751 {
4754 else
4756 }
4757
4758 for (int y = 0; y < _pInfo.nSamples; y++)
4759 {
4762 else
4764
4765 for (int z = 0; z < _pInfo.nSamples; z++)
4766 {
4769 else
4771
4772 vResults = _parser.Eval(_pInfo.nFunctions);
4773
4774 if ((size_t)_pInfo.nFunctions != vFuncMap.size())
4775 throw SyntaxError(SyntaxError::PLOT_ERROR, "", "");
4776
4777 for (size_t i = 0; i < vFuncMap.size(); i++)
4778 {
4779 m_manager.assets[vFuncMap[i]].writeAxis(_defVars.vValue[XCOORD][0].real(), x, XCOORD);
4780 m_manager.assets[vFuncMap[i]].writeAxis(_defVars.vValue[YCOORD][0].real(), y, YCOORD);
4781 m_manager.assets[vFuncMap[i]].writeAxis(_defVars.vValue[ZCOORD][0].real(), z, ZCOORD);
4782 m_manager.assets[vFuncMap[i]].writeData(vResults[i], 0, x, y, z);
4783 }
4784 }
4785 }
4786 }
4787 }
4788 else if (isVect2D(_pInfo.sCommand))
4789 {
4791
4792 for (size_t k = 0; k < vFuncMap.size(); k++)
4793 {
4794 if (expressions[k].find('{') != string::npos && !_pInfo.bDraw3D && !_pInfo.bDraw)
4795 convertVectorToExpression(expressions[k], _option);
4796
4797 _parser.SetExpr(expressions[k]);
4798
4799 for (int x = 0; x < _pInfo.nSamples; x++)
4800 {
4802
4803 for (int y = 0; y < _pInfo.nSamples; y++)
4804 {
4806 vResults = _parser.Eval(_pInfo.nFunctions);
4807
4808 for (int i = 0; i < 2; i++)
4809 {
4810 m_manager.assets[vFuncMap[k]].writeAxis(_defVars.vValue[XCOORD][0].real(), x, XCOORD);
4811 m_manager.assets[vFuncMap[k]].writeAxis(_defVars.vValue[YCOORD][0].real(), y, YCOORD);
4812
4813 if (_pInfo.nFunctions <= i) // Always fill missing dimensions with zero
4814 m_manager.assets[vFuncMap[k]].writeData(0.0, i, x, y);
4815 else
4816 m_manager.assets[vFuncMap[k]].writeData(vResults[i], i, x, y);
4817 }
4818 }
4819 }
4820 }
4821 }
4822 else if (isVect3D(_pInfo.sCommand))
4823 {
4825
4826 for (size_t k = 0; k < vFuncMap.size(); k++)
4827 {
4828 if (expressions[k].find('{') != string::npos && !_pInfo.bDraw3D && !_pInfo.bDraw)
4829 convertVectorToExpression(expressions[k], _option);
4830
4831 _parser.SetExpr(expressions[k]);
4832
4833 for (int x = 0; x < _pInfo.nSamples; x++)
4834 {
4836
4837 for (int y = 0; y < _pInfo.nSamples; y++)
4838 {
4840
4841 for (int z = 0; z < _pInfo.nSamples; z++)
4842 {
4844 vResults = _parser.Eval(_pInfo.nFunctions);
4845
4846 for (int i = 0; i < 3; i++)
4847 {
4848 m_manager.assets[vFuncMap[k]].writeAxis(_defVars.vValue[XCOORD][0].real(), x, XCOORD);
4849 m_manager.assets[vFuncMap[k]].writeAxis(_defVars.vValue[YCOORD][0].real(), y, YCOORD);
4850 m_manager.assets[vFuncMap[k]].writeAxis(_defVars.vValue[ZCOORD][0].real(), z, ZCOORD);
4851
4852 if (_pInfo.nFunctions <= i) // Always fill missing dimensions with zero
4853 m_manager.assets[vFuncMap[k]].writeData(0.0, i, x, y, z);
4854 else
4855 m_manager.assets[vFuncMap[k]].writeData(vResults[i], i, x, y, z);
4856 }
4857 }
4858 }
4859 }
4860 }
4861 }
4862}
4863
4864
4879void Plot::fitPlotRanges(size_t nPlotCompose, bool bNewSubPlot)
4880{
4881 /* --> Darstellungsintervalle anpassen: Wenn nicht alle vorgegeben sind, sollten die fehlenden
4882 * passend berechnet werden. Damit aber kein Punkt auf dem oberen oder dem unteren Rahmen
4883 * liegt, vergroessern wir das Intervall um 5% nach oben und 5% nach unten <--
4884 * --> Fuer Vektor- und 3D-Plots ist das allerdings recht sinnlos <--
4885 */
4886 if (sFunc.length())
4887 {
4888 IntervalSet functionIntervals = m_manager.getFunctionIntervals();
4889
4890 if (isnan(functionIntervals[0].front())
4891 || isnan(functionIntervals[0].back())
4892 || isinf(functionIntervals[0].front())
4893 || isinf(functionIntervals[0].back()))
4894 {
4895 clearData();
4897 }
4898 }
4899
4901 size_t ivlID = PlotAssetManager::REAL;
4902 size_t ivlID3D = PlotAssetManager::REAL;
4903
4905 {
4906 ivlID = PlotAssetManager::REIM;
4907 ivlID3D = PlotAssetManager::REIM;
4908 }
4910 {
4911 ivlID = PlotAssetManager::IMAG;
4912 ivlID3D = PlotAssetManager::ABSREIM;
4913 }
4914
4916 && (!nPlotCompose || bNewSubPlot))
4917 {
4919 {
4920 if (sFunc.length())
4921 {
4924
4925 m_manager.weightedRange(ONLYLEFT, funcIntLeft[ivlID]);
4926 m_manager.weightedRange(ONLYRIGHT, funcIntRight[ivlID]);
4927
4928 if (m_manager.hasDataPlots())
4929 {
4930 // It might happen that all data plots are assigned to the secondary axis
4931 if (!isnan(dataRanges[YRANGE].front()))
4932 _pInfo.ranges[YRANGE] = _pInfo.ranges[YRANGE].combine(funcIntLeft[ivlID]);
4933 else
4934 _pInfo.ranges[YRANGE] = funcIntLeft[ivlID];
4935
4936 _pInfo.secranges[YRANGE] = _pInfo.secranges[YRANGE].combine(funcIntRight[ivlID]);
4937
4938 if (isCmplxPlane)
4940 }
4941 else
4942 {
4943 _pInfo.ranges[YRANGE] = funcIntLeft[ivlID];
4944 _pInfo.secranges[YRANGE] = funcIntRight[ivlID];
4945
4948
4949 if (isCmplxPlane)
4951 }
4952
4953 if ((isnan(funcIntLeft[ivlID].front()) || isnan(_pInfo.ranges[YRANGE].front())) && isnan(dataRanges[YRANGE].front()))
4955 }
4956
4958 ? 0.0 : -INFINITY));
4959
4960 if (isCmplxPlane)
4961 _pInfo.ranges[XRANGE].expand(1.1);
4962 }
4963 else if (isPlot1D(_pInfo.sCommand) && _pData.getGivenRanges() >= 2 && isCmplxPlane)
4964 {
4965 if (sFunc.length())
4966 {
4968
4969 m_manager.weightedRange(ALLRANGES, funcInt[ivlID]);
4970
4971 if (m_manager.hasDataPlots())
4972 {
4975 else
4977
4980 else
4982 }
4983 else
4984 {
4987 else
4989
4992 else
4994 }
4995 }
4996
4999 ? 0.0 : -INFINITY));
5000
5002 _pInfo.ranges[XRANGE].expand(1.1);
5003 }
5004 else if (isPlot3D(_pInfo.sCommand) && _pData.getGivenRanges() < 3)
5005 {
5006 if (sFunc.length())
5007 {
5008 for (int i = XRANGE; i <= ZRANGE; i++)
5009 {
5010 IntervalSet coordIntervals = m_manager.getFunctionIntervals(i);
5011
5012 m_manager.weightedRange(i, coordIntervals[ivlID]);
5013
5014 if (_pData.getGivenRanges() >= i + 1 && _pData.getRangeSetting(i))
5015 continue;
5016
5017 if (m_manager.hasDataPlots())
5018 {
5019 IntervalSet dataCoordIntervals = m_manager.getDataIntervals(i);
5020 _pInfo.ranges[i] = dataCoordIntervals[ivlID].combine(coordIntervals[ivlID]);
5021 }
5022 else
5023 _pInfo.ranges[i] = coordIntervals[ivlID];
5024
5027 || (_pData.getSettings(PlotData::INT_COORDS) != CARTESIAN && !i) ? 0.0 : -INFINITY));
5028 }
5029
5031 _pInfo.ranges[YRANGE].reset(0.0, _pInfo.ranges[YRANGE].max());
5032
5034 _pInfo.ranges[ZRANGE].reset(0.0, _pInfo.ranges[ZRANGE].max());
5035 }
5036 }
5037 else if (isMesh2D(_pInfo.sCommand) && _pData.getGivenRanges() < 3 && _pInfo.sCommand != "implot")
5038 {
5039 if (sFunc.length())
5040 {
5041 IntervalSet funcIntervals = m_manager.getFunctionIntervals();
5042 m_manager.weightedRange(ALLRANGES, funcIntervals[ivlID3D]);
5043 _pInfo.ranges[ZRANGE] = _pInfo.ranges[ZRANGE].combine(funcIntervals[ivlID3D]);
5044
5045 if (!m_manager.hasDataPlots())
5046 _pInfo.ranges[ZRANGE] = funcIntervals[ivlID3D];
5047 }
5048
5051 }
5052
5054 {
5057
5058 for (int i = XRANGE; i <= YRANGE; i++)
5060 }
5061 }
5062 else if (_pInfo.b2DVect && (!nPlotCompose || bNewSubPlot) && !(_pInfo.bDraw3D || _pInfo.bDraw))
5063 {
5064 if (sFunc.length())
5065 {
5066 if (_pData.getGivenRanges() < 3)
5067 {
5068 IntervalSet funcIntervals = m_manager.getFunctionIntervals();
5069 m_manager.weightedRange(ALLRANGES, funcIntervals[0]);
5070 _pInfo.ranges[ZRANGE] = funcIntervals[0];
5071 }
5072
5074 {
5075 _pInfo.ranges[YRANGE].reset(0.0, _pInfo.ranges[YRANGE].max());
5076 _pInfo.ranges[XRANGE].reset(0.0, _pInfo.ranges[XRANGE].max());
5077 }
5078 }
5079 }
5080
5082 {
5083 for (size_t i = XRANGE; i <= ZRANGE; i++)
5084 {
5085 if (_pData.getLogscale(i) && (i != ZRANGE || (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect)))
5086 {
5087 if ((_pInfo.ranges[i].min() <= 0 && _pInfo.ranges[i].max() <= 0) || _pData.getAxisScale(i) <= 0.0)
5088 {
5089 clearData();
5091 }
5092 else if (_pInfo.ranges[i].min() <= 0)
5093 _pInfo.ranges[i].reset(_pInfo.ranges[i].max() * 1e-3, _pInfo.ranges[i].max());
5094 }
5095 }
5096 }
5097}
5098
5099
5108{
5109 m_manager.assets.clear();
5110}
5111
5112
5123static void applyNiceAxis(Interval& ivl, bool isLogarithmic)
5124{
5125 if (isnan(ivl.front()))
5126 return;
5127
5128 double absmax = std::max(std::abs(ivl.min()), std::abs(ivl.max()));
5129 double dScale = intPower(10.0, std::ceil(std::log10(absmax)));
5130 double dMin = ivl.min() / dScale;
5131 double dMax = ivl.max() / dScale;
5132
5133 // This factor determines the number of "ticks" we'll
5134 // allow in the current interval. This default to 2
5135 double factor = 2.0; // 0 - 5 - 10
5136
5137 // Switch to a different factor based upon the current range
5138 // of the interval
5139 if (ivl.range() < 0.2 * dScale)
5140 factor = 20.0; // 0 - 0.5 - 1 - ... - 10
5141 else if (ivl.range() < 0.5 * dScale)
5142 factor = 10.0; // 0 - 1 - 2 - ... - 10
5143 else if (ivl.range() < 0.8 * dScale)
5144 factor = 5.0; // 0 - 2 - 4 - ... - 10
5145
5146 // <1.5 -> 1
5147 // <3 -> 2
5148 // <7 -> 5
5149 // <10 -> 10
5150
5151 // Calculate the new minimal and maximal interval boundaries
5152 dMin = std::floor(dMin * factor) / factor * dScale;
5153 dMax = std::ceil(dMax * factor) / factor * dScale;
5154
5155 // Logarithmic axes cannot be negative. We'll use the previously
5156 // selected lower boundary
5157 if (isLogarithmic && dMin <= 0.0)
5158 dMin = ivl.min();
5159
5160 ivl.reset(dMin, dMax);
5161}
5162
5163
5173{
5175 {
5176 size_t nLayers = 0;
5177
5178 // Create the x axis by summing up all data layers
5179 for (size_t i = 0; i < m_manager.assets.size(); i++)
5180 nLayers += m_manager.assets[i].getLayers();
5181
5182 _pInfo.ranges[XRANGE].reset(0, nLayers+1);
5183 }
5184
5185 // INSERT HERE AXIS LOGIC
5187 {
5188 for (size_t i = YRANGE; i <= ZRANGE; i++)
5189 {
5190 if (!_pData.getRangeSetting(i))
5192 }
5193 }
5195 {
5196 double range = _pInfo.ranges[XRANGE].range();
5197 double aspect = _pData.getSettings(PlotData::FLOAT_ASPECT);
5198
5199 for (size_t i = YRANGE; i <= ZRANGE; i++)
5200 {
5201 if (!_pData.getRangeSetting(i) && !isnan(_pInfo.ranges[i].front()))
5202 {
5203 double newRange = range / aspect - _pInfo.ranges[i].range();
5204 _pInfo.ranges[i].reset(_pInfo.ranges[i].min() - 0.5*newRange,
5205 _pInfo.ranges[i].max() + 0.5*newRange);
5206 }
5207 }
5208 }
5209
5212 else
5214
5217 else
5219
5222 else
5224
5226 {
5227 int nMinbars = -1;
5228
5229 for (size_t k = 0; k < m_manager.assets.size(); k++)
5230 {
5231 if (m_manager.assets[k].type == PT_DATA
5232 && (nMinbars == -1 || nMinbars > m_manager.assets[k].axes[XCOORD].nx))
5233 nMinbars = m_manager.assets[k].axes[XCOORD].nx;
5234 }
5235
5236 if (nMinbars < 2)
5237 nMinbars = 2;
5238
5240 _graph->SetRange('x',
5241 (_pInfo.ranges[XRANGE].max() - _pInfo.ranges[XRANGE].range() / (double)(2 * (nMinbars - 1))) / _pData.getAxisScale(XRANGE),
5242 (_pInfo.ranges[XRANGE].min() + _pInfo.ranges[XRANGE].range() / (double)(2 * (nMinbars - 1))) / _pData.getAxisScale(XRANGE));
5243 else
5244 _graph->SetRange('x',
5245 (_pInfo.ranges[XRANGE].min() - _pInfo.ranges[XRANGE].range() / (double)(2 * (nMinbars - 1))) / _pData.getAxisScale(XRANGE),
5246 (_pInfo.ranges[XRANGE].max() + _pInfo.ranges[XRANGE].range() / (double)(2 * (nMinbars - 1))) / _pData.getAxisScale(XRANGE));
5247
5248 if (_pInfo.sCommand == "plot3d")
5249 {
5251 _graph->SetRange('y',
5252 (_pInfo.ranges[YRANGE].max() - _pInfo.ranges[YRANGE].range() / (double)(2 * (nMinbars - 1))) / _pData.getAxisScale(YRANGE),
5253 (_pInfo.ranges[YRANGE].min() + _pInfo.ranges[YRANGE].range() / (double)(2 * (nMinbars - 1))) / _pData.getAxisScale(YRANGE));
5254 else
5255 _graph->SetRange('y',
5256 (_pInfo.ranges[YRANGE].min() - _pInfo.ranges[YRANGE].range() / (double)(2 * (nMinbars - 1))) / _pData.getAxisScale(YRANGE),
5257 (_pInfo.ranges[YRANGE].max() + _pInfo.ranges[YRANGE].range() / (double)(2 * (nMinbars - 1))) / _pData.getAxisScale(YRANGE));
5258 }
5259 }
5260
5261 if (!isnan(_pInfo.ranges[CRANGE].front()) && (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect))
5262 {
5263 if (_pData.getLogscale(CRANGE) && ((_pInfo.ranges[CRANGE].min() <= 0.0 && _pInfo.ranges[CRANGE].max() <= 0.0) || _pData.getAxisScale(CRANGE) <= 0.0))
5264 {
5265 clearData();
5267 }
5268 else if (_pData.getLogscale(CRANGE) && _pInfo.ranges[CRANGE].min() <= 0.0)
5269 {
5270 _graph->SetRange('c', _pInfo.ranges[CRANGE].max() * 1e-3 / _pData.getAxisScale(CRANGE),
5272 _pInfo.ranges[CRANGE].reset(_pInfo.ranges[CRANGE].max()*1e-3, _pInfo.ranges[CRANGE].max());
5273 }
5274 else if (_pData.getInvertion(CRANGE))
5276 else
5278 }
5279 else if (m_manager.hasDataPlots())
5280 {
5281 double dColorMin = dataRanges[ZRANGE].min() / _pData.getAxisScale(CRANGE);
5282 double dColorMax = dataRanges[ZRANGE].max() / _pData.getAxisScale(CRANGE);
5284
5285 m_manager.weightedRange(ZCOORD, zfuncIntervals[0]);
5286 double dMin = zfuncIntervals[0].min();
5287 double dMax = zfuncIntervals[0].max();
5288
5289 if (dMax > dColorMax && sFunc.length() && _pInfo.sCommand == "plot3d")
5290 dColorMax = dMax / _pData.getAxisScale(CRANGE);
5291
5292 if (dMin < dColorMin && sFunc.length() && _pInfo.sCommand == "plot3d")
5293 dColorMin = dMin / _pData.getAxisScale(CRANGE);
5294
5295 if (_pData.getLogscale(CRANGE) && (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect) && dColorMin <= 0.0 && dColorMax <= 0.0)
5296 {
5297 clearData();
5299 }
5300 else if (_pData.getLogscale(CRANGE) && (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect) && dColorMin <= 0.0)
5301 {
5302 dColorMin = dColorMax * 1e-3;
5303 _graph->SetRange('c', dColorMin, dColorMax + 0.05 * (dColorMax - dColorMin));
5304 _pInfo.ranges[CRANGE].reset(dColorMin, dColorMax + 0.05 * (dColorMax - dColorMin));
5305 }
5306 else if (_pData.getLogscale(CRANGE) && (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect))
5307 {
5308 _pInfo.ranges[CRANGE].reset(dColorMin*0.95, dColorMax*1.05);
5309 _graph->SetRange('c', _pInfo.ranges[CRANGE].min(), _pInfo.ranges[CRANGE].max());
5310 }
5311 else if (_pInfo.sCommand == "implot")
5312 {
5313 _graph->SetRange('c', 0, 255.0);
5314 _pInfo.ranges[CRANGE].reset(0.0, 255.0);
5315 }
5317 {
5318 _pInfo.ranges[CRANGE].reset(-M_PI, M_PI);
5319 _graph->SetRange('c', -M_PI, M_PI);
5320 }
5321 else
5322 {
5323 _pInfo.ranges[CRANGE].reset(dColorMin, dColorMax);
5324 _pInfo.ranges[CRANGE].expand(1.1);
5325 _graph->SetRange('c', _pInfo.ranges[CRANGE].min(), _pInfo.ranges[CRANGE].max());
5326 }
5327 }
5328 else
5329 {
5331 {
5333 _graph->SetRange('c', 1e-3, 1.05);
5334 else
5335 _graph->SetRange('c', -1.05, 1.05);
5336 }
5337 else if (_pInfo.b2DVect || _pInfo.b3DVect)
5338 {
5340 _graph->SetRange('c', 1e-3, 1.05);
5341 else
5342 _graph->SetRange('c', -0.05, 1.05);
5343 }
5344 else
5345 {
5346 IntervalSet funcIntervals = m_manager.getFunctionIntervals();
5347 m_manager.weightedRange(ALLRANGES, funcIntervals[0]);
5348 double dMin = funcIntervals[0].min();
5349 double dMax = funcIntervals[0].max();
5350
5352 && (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect)
5353 && ((dMin <= 0.0 && dMax) || _pData.getAxisScale(3) <= 0.0))
5354 {
5355 clearData();
5357 }
5358 else if (_pData.getLogscale(CRANGE) && (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect) && dMin <= 0.0)
5359 {
5360 _pInfo.ranges[CRANGE].reset(dMax * 1e-3 / _pData.getAxisScale(CRANGE),
5361 (dMax + 0.05 * (dMax - dMin)) / _pData.getAxisScale(CRANGE));
5362 }
5363 else if (_pData.getLogscale(CRANGE) && (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect))
5364 {
5365 _pInfo.ranges[CRANGE].reset(dMin * 0.95 / _pData.getAxisScale(CRANGE),
5366 dMax * 1.05 / _pData.getAxisScale(CRANGE));
5367 }
5369 _pInfo.ranges[CRANGE].reset(-M_PI, M_PI);
5370 else
5371 {
5372 _pInfo.ranges[CRANGE].reset((dMin - 0.05 * (dMax - dMin)) / _pData.getAxisScale(CRANGE),
5373 (dMax + 0.05 * (dMax - dMin)) / _pData.getAxisScale(CRANGE));
5374 }
5375 }
5376
5380
5381 _graph->SetRange('c', _pInfo.ranges[CRANGE].min(), _pInfo.ranges[CRANGE].max());
5382 }
5383 // --> Andere Parameter setzen (die i. A. von den bestimmten Ranges abghaengen) <--
5384 // --> Gitter-, Koordinaten- und Achsenbeschriftungen <--
5385 CoordSettings();
5386
5388 {
5390 _graph->SetRange('x', _pInfo.ranges[XRANGE].max(), _pInfo.ranges[XRANGE].min());
5391 else
5392 _graph->SetRange('x', _pInfo.ranges[XRANGE].min(), _pInfo.ranges[XRANGE].max());
5393
5395 _graph->SetRange('y', _pInfo.ranges[YRANGE].max(), _pInfo.ranges[YRANGE].min());
5396 else
5397 _graph->SetRange('y', _pInfo.ranges[YRANGE].min(), _pInfo.ranges[YRANGE].max());
5398
5400 _graph->SetRange('z', _pInfo.ranges[ZRANGE].max(), _pInfo.ranges[ZRANGE].min());
5401 else
5402 _graph->SetRange('z', _pInfo.ranges[ZRANGE].min(), _pInfo.ranges[ZRANGE].max());
5403
5405 {
5406 int nMinbars = -1;
5407
5408 for (size_t k = 0; k < m_manager.assets.size(); k++)
5409 {
5410 if (m_manager.assets[k].type == PT_DATA
5411 && (nMinbars == -1 || nMinbars > m_manager.assets[k].axes[XCOORD].nx))
5412 nMinbars = m_manager.assets[k].axes[XCOORD].nx;
5413 }
5414
5415 if (nMinbars < 2)
5416 nMinbars = 2;
5417
5419 _graph->SetRange('x',
5420 _pInfo.ranges[XRANGE].max() - _pInfo.ranges[XRANGE].range() / (double)(2 * (nMinbars - 1)),
5421 _pInfo.ranges[XRANGE].min() + _pInfo.ranges[XRANGE].range() / (double)(2 * (nMinbars - 1)));
5422 else
5423 _graph->SetRange('x',
5424 _pInfo.ranges[XRANGE].min() - _pInfo.ranges[XRANGE].range() / (double)(2 * (nMinbars - 1)),
5425 _pInfo.ranges[XRANGE].max() + _pInfo.ranges[XRANGE].range() / (double)(2 * (nMinbars - 1)));
5426
5427 if (_pInfo.sCommand == "plot3d")
5428 {
5430 _graph->SetRange('y',
5431 _pInfo.ranges[YRANGE].max() - _pInfo.ranges[YRANGE].range() / (double)(2 * (nMinbars - 1)),
5432 _pInfo.ranges[YRANGE].min() + _pInfo.ranges[YRANGE].range() / (double)(2 * (nMinbars - 1)));
5433 else
5434 _graph->SetRange('y',
5435 _pInfo.ranges[YRANGE].min() - _pInfo.ranges[YRANGE].range() / (double)(2 * (nMinbars - 1)),
5436 _pInfo.ranges[YRANGE].max() + _pInfo.ranges[YRANGE].range() / (double)(2 * (nMinbars - 1)));
5437 }
5438 }
5439
5440 if (!isnan(_pInfo.ranges[CRANGE].front()) && (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect))
5441 {
5442 if (_pData.getLogscale(CRANGE) && _pData.getRanges()[CRANGE].min() <= 0.0)
5443 _pInfo.ranges[CRANGE].reset(_pData.getRanges()[CRANGE].max()*1e-3, _pData.getRanges()[CRANGE].max());
5444 else
5446
5448 _graph->SetRange('c', _pInfo.ranges[CRANGE].max(), _pInfo.ranges[CRANGE].min());
5449 else
5450 _graph->SetRange('c', _pInfo.ranges[CRANGE].min(), _pInfo.ranges[CRANGE].max());
5451 }
5452 else if (m_manager.hasDataPlots())
5453 {
5454 double dColorMin = dataRanges[ZRANGE].min();
5455 double dColorMax = dataRanges[ZRANGE].max();
5457 m_manager.weightedRange(ZCOORD, zfuncIntervals[0]);
5458
5459 double dMin = zfuncIntervals[0].min();
5460 double dMax = zfuncIntervals[0].max();
5461
5462 if (dMax > dColorMax && sFunc.length() && _pInfo.sCommand == "plot3d")
5463 dColorMax = dMax;
5464 if (dMin < dColorMin && sFunc.length() && _pInfo.sCommand == "plot3d")
5465 dColorMin = dMin;
5466
5467 if (_pData.getLogscale(CRANGE) && (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect) && dColorMin <= 0.0 && dColorMax <= 0.0)
5468 {
5469 clearData();
5471 }
5472 else if (_pData.getLogscale(CRANGE) && (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect) && dColorMin <= 0.0)
5473 {
5474 dColorMin = dColorMax * 1e-3;
5475 _pInfo.ranges[CRANGE].reset(dColorMin, dColorMax + 0.05* (dColorMax - dColorMin));
5476 }
5477 else if (_pData.getLogscale(CRANGE) && (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect))
5478 _pInfo.ranges[CRANGE].reset(dColorMin * 0.05, dColorMax * 1.05);
5479 else
5480 {
5481 _pInfo.ranges[CRANGE].reset(dColorMin, dColorMax);
5482 _pInfo.ranges[CRANGE].expand(1.1);
5483 }
5484
5485 _graph->SetRange('c', _pInfo.ranges[CRANGE].min(), _pInfo.ranges[CRANGE].max());
5486 }
5487 else
5488 {
5489 IntervalSet funcIntervals = m_manager.getFunctionIntervals();
5490 m_manager.weightedRange(ALLRANGES, funcIntervals[0]);
5491
5492 double dMin = funcIntervals[0].min();
5493 double dMax = funcIntervals[0].max();
5494
5495 if (_pData.getLogscale(CRANGE) && (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect) && dMin <= 0.0 && dMax)
5496 {
5497 clearData();
5499 }
5500 else if (_pData.getLogscale(CRANGE) && (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect) && dMin <= 0.0)
5501 _pInfo.ranges[CRANGE].reset(dMax*1e-3, dMax + 0.05 * (dMax - dMin));
5502 else if (_pData.getLogscale(CRANGE) && (_pInfo.b2D || _pInfo.sCommand == "plot3d" || _pInfo.b3D || _pInfo.b3DVect))
5503 _pInfo.ranges[CRANGE].reset(dMin * 0.95, dMax * 1.05);
5504 else
5505 {
5506 _pInfo.ranges[CRANGE].reset(dMin, dMax);
5507 _pInfo.ranges[CRANGE].expand(1.1);
5508 }
5509
5510 _graph->SetRange('c', _pInfo.ranges[CRANGE].min(), _pInfo.ranges[CRANGE].max());
5511 }
5512 }
5513}
5514
5515
5524{
5525 if (_pData.getSettings(PlotData::LOG_COLORBAR) && (_pInfo.sCommand.substr(0, 4) == "grad" || _pInfo.sCommand.substr(0, 4) == "dens" || _pInfo.sCommand == "implot") && !_pInfo.b3D && !_pData.getSettings(PlotData::LOG_SCHEMATIC))
5526 {
5528 {
5529 _graph->SetRange('x', _pInfo.ranges[CRANGE].min()+1e-3, _pInfo.ranges[CRANGE].max()-1e-3);
5530 _graph->SetTicksVal('c', "--\\pi\n--\\pi/2\n0\n\\pi/2\n\\pi");
5531 _graph->SetRange('x', _pInfo.ranges[XRANGE].min(), _pInfo.ranges[XRANGE].max());
5532 }
5533
5534 if (_pData.getAxisScale(CRANGE) != 1.0)
5536
5537 // --> In diesem Fall haetten wir gerne eine Colorbar fuer den Farbwert <--
5539 {
5541 _graph->Colorbar(_pData.getColorSchemeLight("I>").c_str());
5542 else
5543 _graph->Colorbar(_pData.getColorScheme("I>").c_str());
5544 }
5545 else
5546 {
5548 _graph->Colorbar(_pData.getColorSchemeLight(">").c_str());
5549 else
5550 _graph->Colorbar(_pData.getColorScheme().c_str());
5551 }
5552
5553 if (_pData.getAxisScale(CRANGE) != 1.0)
5554 _graph->SetRange('c', _pInfo.ranges[CRANGE].min(), _pInfo.ranges[CRANGE].max());
5555 }
5557 && (_pInfo.sCommand.substr(0, 4) == "mesh"
5558 || _pInfo.sCommand.substr(0, 4) == "surf"
5559 || _pInfo.sCommand.substr(0, 4) == "cont"
5560 || _pInfo.sCommand.substr(0, 4) == "dens"
5561 || _pInfo.sCommand.substr(0, 4) == "grad"
5563 )
5564 )
5565 {
5567 {
5568 _graph->SetRange('x', _pInfo.ranges[CRANGE].min()+1e-3, _pInfo.ranges[CRANGE].max()-1e-3);
5569 _graph->SetTicksVal('c', "--\\pi\n--\\pi/2\n0\n\\pi/2\n\\pi");
5570 _graph->SetRange('x', _pInfo.ranges[XRANGE].min(), _pInfo.ranges[XRANGE].max());
5571 }
5572
5573 if (_pData.getAxisScale(CRANGE) != 1.0)
5575
5576 _graph->Colorbar(_pData.getColorScheme().c_str());
5577
5578 if (_pData.getAxisScale(CRANGE) != 1.0)
5579 _graph->SetRange('c', _pInfo.ranges[CRANGE].min(), _pInfo.ranges[CRANGE].max());
5580 }
5581}
5582
5583
5594{
5595 if (_pInfo.sCommand.substr(0, 4) == "mesh"
5596 || _pInfo.sCommand.substr(0, 4) == "surf"
5597 || _pInfo.sCommand.substr(0, 4) == "cont"
5598 || _pInfo.b3D
5599 || _pInfo.b3DVect
5601 || _pInfo.bDraw3D
5602 || _pInfo.bDraw
5604 {
5605 // --> Licht- und Transparenz-Effekte <--
5606 if (_pInfo.sCommand.substr(0, 4) == "surf"
5607 || (_pInfo.sCommand.substr(0, 4) == "dens" && _pInfo.sCommand.find("3d") != string::npos && !_pData.getSettings(PlotData::LOG_CONTPROJ))
5609 || _pInfo.bDraw3D
5610 || _pInfo.bDraw)
5611 {
5614 }
5615
5617 {
5618 _graph->Alpha(true);
5620 }
5621
5623 {
5624 _graph->Light(true);
5625
5627 {
5629 {
5630 _graph->AddLight(0, mglPoint(0, 0, 1), 'w', 0.35);
5631 _graph->AddLight(1, mglPoint(5, 30, 5), 'w', 0.15);
5632 _graph->AddLight(2, mglPoint(5, -30, 5), 'w', 0.06);
5633 }
5634 else
5635 {
5636 _graph->AddLight(0, mglPoint(0, 0, 1), 'w', 0.25);
5637 _graph->AddLight(1, mglPoint(5, 30, 5), 'w', 0.1);
5638 _graph->AddLight(2, mglPoint(5, -30, 5), 'w', 0.04);
5639 }
5640 }
5641 else
5642 {
5644 {
5645 _graph->AddLight(1, mglPoint(-5, 5, 1), 'w', 0.4);
5646 _graph->AddLight(2, mglPoint(-3, 3, 9), 'w', 0.1);
5647 _graph->AddLight(3, mglPoint(5, -5, 1), 'w', 0.1);
5648 }
5649 else
5650 {
5651 _graph->AddLight(1, mglPoint(-5, 5, 1), 'w', 0.2);
5652 _graph->AddLight(2, mglPoint(-3, 3, 9), 'w', 0.05);
5653 _graph->AddLight(3, mglPoint(5, -5, 1), 'w', 0.05);
5654 }
5655
5656 _graph->Light(0, false);
5657 }
5658 }
5659 }
5660}
5661
5662
5672void Plot::setLogScale(bool bzLogscale)
5673{
5674 // --> Logarithmische Skalierung; ein bisschen Fummelei <--
5676 {
5678 _graph->SetRanges(0.1, 10.0, 0.1, 10.0, 0.1, 10.0);
5679
5680 _graph->SetFunc(_pData.getLogscale(XRANGE) ? "lg(x)" : "",
5681 _pData.getLogscale(YRANGE) ? "lg(y)" : "",
5682 _pData.getLogscale(ZRANGE) && bzLogscale ? "lg(z)" : "",
5683 _pData.getLogscale(CRANGE) ? "lg(c)" : "");
5684 }
5685}
5686
5687
5701void Plot::directionalLight(double dPhi, double dTheta, int nId, char cColor, double dBrightness)
5702{
5703 mglPoint _mPoint(0.0, 0.0, 0.0);
5704 mglPoint _mDirection(_pInfo.ranges[XRANGE].middle(), _pInfo.ranges[YRANGE].middle(), _pInfo.ranges[ZRANGE].middle());
5705 double dNorm = hypot(_pInfo.ranges[XRANGE].range() / 2.0, _pInfo.ranges[YRANGE].range() / 2.0);
5706
5707 _mPoint.x = dNorm * cos(dPhi / 180.0 * M_PI + M_PI_4) * sin(dTheta / 180.0 * M_PI);
5708 _mPoint.y = dNorm * sin(dPhi / 180.0 * M_PI + M_PI_4) * sin(dTheta / 180.0 * M_PI);
5709 _mPoint.z = _pInfo.ranges[ZRANGE].max();
5710
5711 _mPoint += _mDirection;
5712
5713 if (_mPoint.x > _pInfo.ranges[XRANGE].max())
5714 _mPoint.x = _pInfo.ranges[XRANGE].max();
5715
5716 if (_mPoint.x < _pInfo.ranges[XRANGE].min())
5717 _mPoint.x = _pInfo.ranges[XRANGE].min();
5718
5719 if (_mPoint.y > _pInfo.ranges[YRANGE].max())
5720 _mPoint.y = _pInfo.ranges[YRANGE].max();
5721
5722 if (_mPoint.y < _pInfo.ranges[YRANGE].min())
5723 _mPoint.y = _pInfo.ranges[YRANGE].min();
5724
5725 _mDirection = _mDirection - _mPoint;
5726
5727 _graph->AddLight(nId, _mPoint, _mDirection, cColor, dBrightness);
5728 return;
5729}
5730
5731
5745mglPoint Plot::CalcCutBox(double dPhi, int nEdge, int nCoords, bool b3D)
5746{
5747 int z = ZCOORD;
5748 int r = XCOORD;
5749
5750 // Determine the coordinates, which correspond to X and Y
5751 if (!b3D)
5752 {
5753 switch (nCoords)
5754 {
5755 case POLAR_PZ:
5756 z = YCOORD;
5757 r = ZCOORD;
5758 break;
5759 case POLAR_RP:
5760 z = ZCOORD;
5761 r = XCOORD;
5762 break;
5763 case POLAR_RZ:
5764 z = YCOORD;
5765 r = XCOORD;
5766 break;
5767 case SPHERICAL_PT:
5768 r = ZCOORD;
5769 break;
5770 case SPHERICAL_RP:
5771 r = XCOORD;
5772 break;
5773 case SPHERICAL_RT:
5774 r = XCOORD;
5775 break;
5776 }
5777 }
5778
5779 // The cutting box depends on the rotation of the graph
5780 // and is oriented in a way that the cutted range is
5781 // always presented to the viewer.
5782 if (dPhi >= 0.0 && dPhi < 90.0)
5783 {
5784 if (!nEdge)
5785 {
5786 if (nCoords == CARTESIAN)
5787 return mglPoint(_pInfo.ranges[XRANGE].middle(),
5788 _pInfo.ranges[YRANGE].min() - 0.1 * fabs(_pInfo.ranges[YRANGE].min()),
5789 _pInfo.ranges[ZRANGE].min() - 0.1 * fabs(_pInfo.ranges[ZRANGE].min()));
5790 else if (nCoords == POLAR_PZ || nCoords == POLAR_RP || nCoords == POLAR_RZ)
5791 return createMglPoint(nCoords, 0.0, 1.5 * M_PI, _pInfo.ranges[z].min() - 0.1 * fabs(_pInfo.ranges[z].min()));
5792 else if (nCoords == SPHERICAL_PT || nCoords == SPHERICAL_RP || nCoords == SPHERICAL_RT)
5793 return createMglPoint(nCoords, 0.0, 1.5 * M_PI, 0.0, b3D);
5794 }
5795 else
5796 {
5797 if (nCoords == CARTESIAN)
5798 return mglPoint(_pInfo.ranges[XRANGE].max() + 0.1 * fabs(_pInfo.ranges[XRANGE].max()),
5799 _pInfo.ranges[YRANGE].middle(),
5800 _pInfo.ranges[ZRANGE].max() + 0.1 * fabs(_pInfo.ranges[ZRANGE].max()));
5801 else if (nCoords == POLAR_PZ || nCoords == POLAR_RP || nCoords == POLAR_RZ)
5802 return createMglPoint(nCoords, 1.1 * _pInfo.ranges[r].max(), 2.0 * M_PI, _pInfo.ranges[z].max() + 0.1 * fabs(_pInfo.ranges[z].max()), b3D);
5803 else if (nCoords == SPHERICAL_PT || nCoords == SPHERICAL_RP || nCoords == SPHERICAL_RT)
5804 return createMglPoint(nCoords, 1.1 * _pInfo.ranges[r].max(), 2.0 * M_PI, M_PI, b3D);
5805 }
5806 }
5807 else if (dPhi >= 90.0 && dPhi < 180.0)
5808 {
5809 if (!nEdge)
5810 {
5811 if (nCoords == CARTESIAN)
5812 return mglPoint(_pInfo.ranges[XRANGE].middle(),
5813 _pInfo.ranges[YRANGE].middle(),
5814 _pInfo.ranges[ZRANGE].min() - 0.1 * fabs(_pInfo.ranges[ZRANGE].min()));
5815 else if (nCoords == POLAR_PZ || nCoords == POLAR_RP || nCoords == POLAR_RZ)
5816 return createMglPoint(nCoords, 0.0, 0.0, _pInfo.ranges[z].min() - 0.1 * fabs(_pInfo.ranges[z].min()), b3D);
5817 else if (nCoords == SPHERICAL_PT || nCoords == SPHERICAL_RP || nCoords == SPHERICAL_RT)
5818 return createMglPoint(nCoords, 0.0, 0.0, 0.0, b3D);
5819 }
5820 else
5821 {
5822 if (nCoords == CARTESIAN)
5823 return mglPoint(_pInfo.ranges[XRANGE].max() + 0.1 * fabs(_pInfo.ranges[XRANGE].max()),
5824 _pInfo.ranges[YRANGE].max() + 0.1 * fabs(_pInfo.ranges[YRANGE].max()),
5825 _pInfo.ranges[ZRANGE].max() + 0.1 * fabs(_pInfo.ranges[ZRANGE].max()));
5826 else if (nCoords == POLAR_PZ || nCoords == POLAR_RP || nCoords == POLAR_RZ)
5827 return createMglPoint(nCoords, _pInfo.ranges[r].max() * 1.1, 0.5 * M_PI, _pInfo.ranges[z].max() + 0.1 * fabs(_pInfo.ranges[z].max()), b3D);
5828 else if (nCoords == SPHERICAL_PT || nCoords == SPHERICAL_RP || nCoords == SPHERICAL_RT)
5829 return createMglPoint(nCoords, 1.1 * _pInfo.ranges[r].max(), 0.5 * M_PI, M_PI, b3D);
5830 }
5831 }
5832 else if (dPhi >= 180.0 && dPhi < 270.0)
5833 {
5834 if (!nEdge)
5835 {
5836 if (nCoords == CARTESIAN)
5837 return mglPoint(_pInfo.ranges[XRANGE].min() - 0.1 * fabs(_pInfo.ranges[XRANGE].min()),
5838 _pInfo.ranges[YRANGE].middle(),
5839 _pInfo.ranges[ZRANGE].min() - 0.1 * fabs(_pInfo.ranges[ZRANGE].min()));
5840 else if (nCoords == POLAR_PZ || nCoords == POLAR_RP || nCoords == POLAR_RZ)
5841 return createMglPoint(nCoords, 0.0, 0.5 * M_PI, _pInfo.ranges[z].min() - 0.1 * fabs(_pInfo.ranges[z].min()), b3D);
5842 else if (nCoords == SPHERICAL_PT || nCoords == SPHERICAL_RP || nCoords == SPHERICAL_RT)
5843 return createMglPoint(nCoords, 0.0, 0.5 * M_PI, 0.0, b3D);
5844 }
5845 else
5846 {
5847 if (nCoords == CARTESIAN)
5848 return mglPoint(_pInfo.ranges[XRANGE].middle(),
5849 _pInfo.ranges[YRANGE].max() + 0.1 * fabs(_pInfo.ranges[YRANGE].max()),
5850 _pInfo.ranges[ZRANGE].max() + 0.1 * fabs(_pInfo.ranges[ZRANGE].max()));
5851 else if (nCoords == POLAR_PZ || nCoords == POLAR_RP || nCoords == POLAR_RZ)
5852 return createMglPoint(nCoords, 1.1 * _pInfo.ranges[r].max(), M_PI, _pInfo.ranges[z].max() + 0.1 * fabs(_pInfo.ranges[z].max()), b3D);
5853 else if (nCoords == SPHERICAL_PT || nCoords == SPHERICAL_RP || nCoords == SPHERICAL_RT)
5854 return createMglPoint(nCoords, 1.1 * _pInfo.ranges[r].max(), M_PI, M_PI, b3D);
5855 }
5856 }
5857 else
5858 {
5859 if (!nEdge)
5860 {
5861 if (nCoords == CARTESIAN)
5862 return mglPoint(_pInfo.ranges[XRANGE].min() - 0.1 * fabs(_pInfo.ranges[XRANGE].min()),
5863 _pInfo.ranges[YRANGE].min() - 0.1 * fabs(_pInfo.ranges[YRANGE].min()),
5864 _pInfo.ranges[ZRANGE].min() - 0.1 * fabs(_pInfo.ranges[ZRANGE].min()));
5865 else if (nCoords == POLAR_PZ || nCoords == POLAR_RP || nCoords == POLAR_RZ)
5866 return createMglPoint(nCoords, 0.0, M_PI, _pInfo.ranges[z].min() - 0.1 * fabs(_pInfo.ranges[z].min()), b3D);
5867 else if (nCoords == SPHERICAL_PT || nCoords == SPHERICAL_RP || nCoords == SPHERICAL_RT)
5868 return createMglPoint(nCoords, 0.0, M_PI, 0.0, b3D);
5869 }
5870 else
5871 {
5872 if (nCoords == CARTESIAN)
5873 return mglPoint(_pInfo.ranges[XRANGE].middle(),
5874 _pInfo.ranges[YRANGE].middle(),
5875 _pInfo.ranges[ZRANGE].max() + 0.1 * fabs(_pInfo.ranges[ZRANGE].max()));
5876 else if (nCoords == POLAR_PZ || nCoords == POLAR_RP || nCoords == POLAR_RZ)
5877 return createMglPoint(nCoords, 1.1 * _pInfo.ranges[r].max(), 1.5 * M_PI, _pInfo.ranges[z].max() + 0.1 * fabs(_pInfo.ranges[z].max()), b3D);
5878 else if (nCoords == SPHERICAL_PT || nCoords == SPHERICAL_RP || nCoords == SPHERICAL_RT)
5879 return createMglPoint(nCoords, 1.1 * _pInfo.ranges[r].max(), 1.5 * M_PI, M_PI, b3D);
5880 }
5881 }
5882
5883 return mglPoint(0);
5884}
5885
5886
5900mglPoint Plot::createMglPoint(int nCoords, double r, double phi, double theta, bool b3D)
5901{
5902 if (b3D)
5903 return mglPoint(r, phi, theta);
5904
5905 switch (nCoords)
5906 {
5907 case POLAR_PZ:
5908 return mglPoint(phi, theta, r);
5909 case POLAR_RP:
5910 return mglPoint(r, phi, theta);
5911 case POLAR_RZ:
5912 return mglPoint(r, theta, phi);
5913 case SPHERICAL_PT:
5914 return mglPoint(phi, theta, r);
5915 case SPHERICAL_RP:
5916 return mglPoint(r, phi, theta);
5917 case SPHERICAL_RT:
5918 return mglPoint(r, theta, phi);
5919 default:
5920 return mglPoint(r, phi, theta);
5921 }
5922
5923 return mglPoint();
5924}
5925
5926
5939double Plot::getProjBackground(double dPhi, int nEdge)
5940{
5941 if (dPhi >= 0.0 && dPhi < 90.0)
5942 {
5943 if (!nEdge)
5944 return _pInfo.ranges[XRANGE].min();
5945 else
5946 return _pInfo.ranges[YRANGE].max();
5947 }
5948 else if (dPhi >= 90.0 && dPhi < 180.0)
5949 {
5950 if (!nEdge)
5951 return _pInfo.ranges[XRANGE].min();
5952 else
5953 return _pInfo.ranges[YRANGE].min();
5954 }
5955 else if (dPhi >= 180.0 && dPhi < 270.0)
5956 {
5957 if (!nEdge)
5958 return _pInfo.ranges[XRANGE].max();
5959 else
5960 return _pInfo.ranges[YRANGE].min();
5961 }
5962 else
5963 {
5964 if (!nEdge)
5965 return _pInfo.ranges[XRANGE].max();
5966 else
5967 return _pInfo.ranges[YRANGE].max();
5968 }
5969
5970 return 0.0;
5971}
5972
5973
5983string Plot::getLegendStyle(const string& sLegend)
5984{
5986 {
5988 return sLegend.substr(0, 1) + "-";
5990 return "k" + sLegend.substr(1);
5991 else
5992 return sLegend;
5993 }
5994 else
5995 return sLegend;
5996}
5997
5998
6009mglData Plot::fmod(const mglData& _mData, double dDenominator)
6010{
6011 if (!getNN(_mData))
6012 return _mData;
6013
6014 mglData _mReturn(_mData.nx, _mData.ny, _mData.nz);
6015
6016 for (long int i = 0; i < getNN(_mData); i++)
6017 {
6018 _mReturn.a[i] = ::fmod(_mData.a[i], dDenominator);
6019 // Spezialfall fuer krummlinige Koordinaten: wandle negative Winkel in positive um
6020 if (_mReturn.a[i] < 0)
6021 _mReturn.a[i] += dDenominator;
6022 }
6023
6024 return _mReturn;
6025}
6026
6027
6038static bool hasSecAxisBox(const PlotData& _pData, const PlotInfo& _pInfo)
6039{
6040 return isPlot1D(_pInfo.sCommand)
6043 && (!isnan(_pData.getAddAxis(XCOORD).ivl.front()) || !isnan(_pData.getAddAxis(YCOORD).ivl.front()));
6044}
6045
6046
6055{
6057 {
6058 for (int i = XRANGE; i <= CRANGE; i++)
6059 {
6060 if (_pData.getTickTemplate(i).length())
6061 {
6062 if (i < 3)
6063 _graph->SetTickTempl('x' + i, _pData.getTickTemplate(i).c_str());
6064 else
6065 _graph->SetTickTempl('c', _pData.getTickTemplate(i).c_str());
6066 }
6067 else if (_pInfo.ranges[i].max() / _pData.getAxisScale(i) < 1e-2
6068 && _pInfo.ranges[i].max() / _pData.getAxisScale(i) >= 1e-3)
6069 {
6070 if (i < 3)
6071 _graph->SetTickTempl('x' + i, "%g");
6072 else
6073 _graph->SetTickTempl('c', "%g");
6074 }
6075
6076 if (_pData.getCustomTick(i).length())
6077 {
6078 int nCount = 1;
6079 mglData _mAxisRange;
6080
6081 if (i < 3)
6082 {
6083 for (unsigned int n = 0; n < _pData.getCustomTick(i).length(); n++)
6084 {
6085 if (_pData.getCustomTick(i)[n] == '\n')
6086 nCount++;
6087 }
6088
6089 _mAxisRange.Create(nCount);
6090
6091 // Ranges fuer customn ticks anpassen
6093 {
6094 if (!(_pInfo.b2D || _pInfo.b3D || _pInfo.sCommand == "plot3d" || _pInfo.b3DVect || _pInfo.b2DVect))
6095 {
6096 _pInfo.ranges[XRANGE].reset(0.0, 2.0);
6097 _pInfo.ranges[YRANGE].reset(0.0, _pInfo.ranges[YRANGE].max());
6098 }
6099 else if (_pInfo.sCommand.find("3d") != string::npos)
6100 {
6101 _pInfo.ranges[XRANGE].reset(0.0, _pInfo.ranges[XRANGE].max());
6102 _pInfo.ranges[YRANGE].reset(0.0, 2.0);
6103
6107 _pInfo.ranges[ZRANGE].reset(0.0, 1.0);
6108 }
6109 else if (_pInfo.b2DVect)
6110 {
6111 _pInfo.ranges[XRANGE].reset(0.0, _pInfo.ranges[XRANGE].max());
6112 _pInfo.ranges[YRANGE].reset(0.0, 2.0);
6113 }
6114 else
6115 {
6116 _pInfo.ranges[XRANGE].reset(0.0, 2.0);
6117 _pInfo.ranges[ZRANGE].reset(0.0, _pInfo.ranges[ZRANGE].max());
6118
6122 _pInfo.ranges[YRANGE].reset(0.0, 1.0);
6123 }
6124 }
6125
6126 if (nCount == 1)
6127 _mAxisRange.a[0] = _pInfo.ranges[i].middle();
6128 else
6129 {
6130 for (int n = 0; n < nCount; n++)
6131 {
6132 _mAxisRange.a[n] = _pInfo.ranges[i](n, nCount).real();
6133 }
6134 }
6135
6136 _graph->SetTicksVal('x' + i, _mAxisRange, fromSystemCodePage(_pData.getCustomTick(i)).c_str());
6137 }
6138 else
6139 {
6140 for (unsigned int n = 0; n < _pData.getCustomTick(i).length(); n++)
6141 {
6142 if (_pData.getCustomTick(i)[n] == '\n')
6143 nCount++;
6144 }
6145
6146 _mAxisRange.Create(nCount);
6147
6148 if (nCount == 1)
6149 _mAxisRange.a[0] = _pInfo.ranges[i].middle();
6150 else
6151 {
6152 for (int n = 0; n < nCount; n++)
6153 {
6154 _mAxisRange.a[n] = _pInfo.ranges[i](n, nCount).real();
6155 }
6156 }
6157
6158 _graph->SetTicksVal('c', _mAxisRange, fromSystemCodePage(_pData.getCustomTick(i)).c_str());
6159 }
6160 }
6161
6162 if (_pData.getTimeAxis(i).use)
6163 {
6164 if (i < 3)
6165 _graph->SetTicksTime('x' + i, 0, _pData.getTimeAxis(i).sTimeFormat.c_str());
6166 else
6167 _graph->SetTicksTime('c', 0, _pData.getTimeAxis(i).sTimeFormat.c_str());
6168 }
6169 }
6170
6174 {
6175 if (isPlot1D(_pInfo.sCommand)) // standard plot
6176 {
6178 {
6180 {
6182 {
6183 Axis _axis = _pData.getAddAxis(XCOORD);
6184 double dAspect = _pData.getSettings(PlotData::FLOAT_ASPECT);
6185
6186 if (_axis.sLabel.length())
6187 {
6188 _graph->SetRanges(_axis.ivl.min(), _axis.ivl.max(),
6189 _pInfo.ranges[YRANGE].min(), _pInfo.ranges[YRANGE].max());
6190 _graph->SetOrigin(_axis.ivl.max(), _pInfo.ranges[YRANGE].max() + _pInfo.ranges[YRANGE].range()*0.05);
6191 _graph->Axis("x", _axis.sStyle.c_str());
6192 _graph->Label('x', fromSystemCodePage("#" + _axis.sStyle + "{" + _axis.sLabel + "}").c_str(), 0);
6193 }
6194
6195 _axis = _pData.getAddAxis(YCOORD);
6196
6197 if (_axis.sLabel.length())
6198 {
6199 _graph->SetRanges(_pInfo.ranges[XRANGE].min(), _pInfo.ranges[XRANGE].max(),
6200 _axis.ivl.min(), _axis.ivl.max());
6201 _graph->SetOrigin(_pInfo.ranges[XRANGE].max() + _pInfo.ranges[XRANGE].range()*0.05 / dAspect, _axis.ivl.max());
6202
6203 _graph->Axis("y", _axis.sStyle.c_str());
6204 _graph->Label('y', fromSystemCodePage("#" + _axis.sStyle + "{" + _axis.sLabel + "}").c_str(), 0);
6205 }
6206
6207 _graph->SetRanges(_pInfo.ranges[XRANGE].min(), _pInfo.ranges[XRANGE].max(),
6208 _pInfo.ranges[YRANGE].min(), _pInfo.ranges[YRANGE].max(),
6209 _pInfo.ranges[ZRANGE].min(), _pInfo.ranges[ZRANGE].max());
6210 _graph->SetOrigin(_pInfo.ranges[XRANGE].min(), _pInfo.ranges[YRANGE].min());
6211 }
6212
6213 _graph->Axis("xy");
6214 }
6215 }
6216 else
6217 {
6220 {
6221 _graph->SetOrigin(_pInfo.ranges[XRANGE].max() / _pData.getAxisScale(XRANGE), 0.0);
6222 _graph->SetFunc(CoordFunc("x*cos(pi*y*$PS$)", _pData.getAxisScale(YCOORD)).c_str(),
6223 CoordFunc("x*sin(pi*y*$PS$)", _pData.getAxisScale(YCOORD)).c_str());
6224 _graph->SetRange('y', 0.0, APPR_TWO / _pData.getAxisScale(YCOORD));
6225 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max() / _pData.getAxisScale(XRANGE));
6226 }
6228 {
6229 _graph->SetOrigin(0.0, _pInfo.ranges[YCOORD].max() / _pData.getAxisScale(YCOORD));
6230 _graph->SetFunc(CoordFunc("y*cos(pi*x*$PS$)", _pData.getAxisScale(XRANGE)).c_str(),
6231 CoordFunc("y*sin(pi*x*$PS$)", _pData.getAxisScale(XRANGE)).c_str());
6232 _graph->SetRange('x', 0.0, APPR_TWO / _pData.getAxisScale(XRANGE));
6233 _graph->SetRange('y', 0.0, _pInfo.ranges[YCOORD].max() / _pData.getAxisScale(YCOORD));
6234 }
6235
6236 applyGrid();
6237
6240 {
6241 _graph->SetFunc("x*cos(y)", "x*sin(y)");
6242 _graph->SetRange('y', 0.0, 2.0 * M_PI);
6243 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max());
6244 }
6246 {
6247 _graph->SetFunc("y*cos(x)", "y*sin(x)");
6248 _graph->SetRange('x', 0.0, 2.0 * M_PI);
6249 _graph->SetRange('y', 0.0, _pInfo.ranges[YRANGE].max());
6250 }
6251
6253 || findParameter(_pInfo.sPlotParams, "xlabel", '=')
6254 || findParameter(_pInfo.sPlotParams, "ylabel", '=')
6255 || findParameter(_pInfo.sPlotParams, "zlabel", '='))
6256 {
6257 _graph->Label('x', fromSystemCodePage(_pData.getAxisLabel(XCOORD)).c_str(), 0.25);
6258
6261 _graph->Label('y', fromSystemCodePage(_pData.getAxisLabel(YCOORD)).c_str(), 0.0);
6262 else
6263 _graph->Label('y', fromSystemCodePage(_pData.getAxisLabel(ZCOORD)).c_str(), 0.0);
6264 }
6265
6267 _graph->SetOrigin(0.0, 0.0);
6268
6269 _pInfo.ranges[XRANGE].reset(0.0, 2.0*M_PI);
6270 _pInfo.ranges[YRANGE].reset(0.0, _pInfo.ranges[YRANGE].max());
6271 }
6272 }
6273 else if (isMesh3D(_pInfo.sCommand) || isVect3D(_pInfo.sCommand) || isPlot3D(_pInfo.sCommand)) // 3d-plots and plot3d and vect3d
6274 {
6278 {
6279 _graph->SetOrigin(_pInfo.ranges[XRANGE].max() / _pData.getAxisScale(), 0.0, _pInfo.ranges[ZRANGE].min() / _pData.getAxisScale(2));
6280 _graph->SetFunc(CoordFunc("x*cos(pi*y*$PS$)", _pData.getAxisScale(1)).c_str(),
6281 CoordFunc("x*sin(pi*y*$PS$)", _pData.getAxisScale(1)).c_str(), "z");
6282 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max() / _pData.getAxisScale());
6283 _graph->SetRange('y', 0.0, 1.9999999 / _pData.getAxisScale(1));
6284 _graph->SetRange('z', _pInfo.ranges[ZRANGE].min() / _pData.getAxisScale(2),
6285 _pInfo.ranges[ZRANGE].max() / _pData.getAxisScale(2));
6286
6288 _graph->Axis();
6289 else
6290 {
6291 _graph->SetTickLen(1e-20);
6292 _graph->Axis("_");
6293 }
6294
6295 _graph->Box();
6296
6298 _graph->Grid("xyzt", _pData.getFineGridStyle().c_str());
6299 else if (_pData.getSettings(PlotData::INT_GRID) == 1)
6300 _graph->Grid("xyzt", _pData.getGridStyle().c_str());
6301 else if (_pData.getSettings(PlotData::INT_GRID) == 2)
6302 {
6303 _graph->Grid("xyzt!", _pData.getGridStyle().c_str());
6304 _graph->Grid("xyzt", _pData.getFineGridStyle().c_str());
6305 }
6306
6307 _graph->SetFunc("x*cos(y)", "x*sin(y)", "z");
6308 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max());
6309 _graph->SetRange('y', 0.0, 2.0 * M_PI);
6310 _graph->SetRange('z', _pInfo.ranges[ZRANGE].min(), _pInfo.ranges[ZRANGE].max());
6311
6313 || findParameter(_pInfo.sPlotParams, "xlabel", '=')
6314 || findParameter(_pInfo.sPlotParams, "ylabel", '=')
6315 || findParameter(_pInfo.sPlotParams, "zlabel", '='))
6316 {
6317 _graph->Label('x', fromSystemCodePage(_pData.getAxisLabel(ZCOORD)).c_str(), -0.5);
6318 _graph->Label('y', fromSystemCodePage(_pData.getAxisLabel(XCOORD)).c_str(), (_pData.getRotateAngle(1) - 225.0) / 180.0);
6319 _graph->Label('z', fromSystemCodePage(_pData.getAxisLabel(YCOORD)).c_str(), 0.0);
6320 }
6321
6323 _graph->SetOrigin(0.0, 0.0, _pInfo.ranges[ZRANGE].min());
6324
6325 _pInfo.ranges[XRANGE].reset(0.0, _pInfo.ranges[XRANGE].max());
6326 _pInfo.ranges[YRANGE].reset(0.0, 2.0*M_PI);
6327
6328 }
6332 {
6333 _graph->SetOrigin(_pInfo.ranges[XRANGE].max() / _pData.getAxisScale(), 0.0, 0.5 / _pData.getAxisScale(2));
6334 _graph->SetFunc(CoordFunc("x*cos(pi*y*$PS$)*sin(pi*z*$TS$)", _pData.getAxisScale(1), _pData.getAxisScale(2)).c_str(),
6335 CoordFunc("x*sin(pi*y*$PS$)*sin(pi*z*$TS$)", _pData.getAxisScale(1), _pData.getAxisScale(2)).c_str(),
6336 CoordFunc("x*cos(pi*z*$PS$)", 1.0, _pData.getAxisScale(2)).c_str());
6337 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max() / _pData.getAxisScale());
6338 _graph->SetRange('y', 0.0, 1.9999999 / _pData.getAxisScale(1));
6339 _graph->SetRange('z', 0.0, 0.9999999 / _pData.getAxisScale(2));
6340
6342 _graph->Axis();
6343 else
6344 {
6345 _graph->SetTickLen(1e-20);
6346 _graph->Axis("_");
6347 }
6348
6349 _graph->Box();
6350
6352 _graph->Grid("xyzt", _pData.getFineGridStyle().c_str());
6353 else if (_pData.getSettings(PlotData::INT_GRID) == 1)
6354 _graph->Grid("xyzt", _pData.getGridStyle().c_str());
6355 else if (_pData.getSettings(PlotData::INT_GRID) == 2)
6356 {
6357 _graph->Grid("xyzt!", _pData.getGridStyle().c_str());
6358 _graph->Grid("xyzt", _pData.getFineGridStyle().c_str());
6359 }
6360
6361 _graph->SetFunc("x*cos(y)*sin(z)", "x*sin(y)*sin(z)", "x*cos(z)");
6362 _graph->SetOrigin(_pInfo.ranges[XRANGE].max(), 0.0, 0.5 * M_PI);
6363 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max());
6364 _graph->SetRange('y', 0.0, 2.0 * M_PI);
6365 _graph->SetRange('z', 0.0, 1.0 * M_PI);
6366
6368 || findParameter(_pInfo.sPlotParams, "xlabel", '=')
6369 || findParameter(_pInfo.sPlotParams, "ylabel", '=')
6370 || findParameter(_pInfo.sPlotParams, "zlabel", '='))
6371 {
6372 _graph->Label('x', fromSystemCodePage(_pData.getAxisLabel(ZCOORD)).c_str(), -0.4);
6373 _graph->Label('y', fromSystemCodePage(_pData.getAxisLabel(XCOORD)).c_str(), (_pData.getRotateAngle(1) - 225.0) / 180.0);
6374 _graph->Label('z', fromSystemCodePage(_pData.getAxisLabel(YCOORD)).c_str(), -0.9); // -0.4
6375 }
6376
6378 _graph->SetOrigin(0.0, 0.0, 0.5 * M_PI);
6379
6380 _pInfo.ranges[XRANGE].reset(0.0, _pInfo.ranges[XRANGE].max());
6381 _pInfo.ranges[YRANGE].reset(0.0, 2.0*M_PI);
6382 _pInfo.ranges[ZRANGE].reset(0.0, M_PI);
6383 }
6384 else
6385 {
6387 _graph->Axis("xyz");
6388 }
6389 }
6390 else if (isVect2D(_pInfo.sCommand)) // vect
6391 {
6393 {
6394 _graph->SetOrigin(_pInfo.ranges[XRANGE].max() / _pData.getAxisScale(), 0.0);
6395 _graph->SetFunc(CoordFunc("x*cos(pi*y*$PS$)", _pData.getAxisScale(1)).c_str(),
6396 CoordFunc("x*sin(pi*y*$PS$)", _pData.getAxisScale(1)).c_str());
6397 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max() / _pData.getAxisScale());
6398 _graph->SetRange('y', 0.0, 1.9999999 / _pData.getAxisScale(1));
6399
6401 _graph->Axis("xy");
6402 else
6403 {
6404 _graph->SetTickLen(1e-20);
6405 _graph->Axis("xy_");
6406 }
6407
6408 _graph->Box();
6409
6411 _graph->Grid("xyzt", _pData.getFineGridStyle().c_str());
6412
6413 _graph->SetFunc("x*cos(y)", "x*sin(y)");
6414 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max());
6415 _graph->SetRange('y', 0.0, 2.0 * M_PI);
6416
6418 || findParameter(_pInfo.sPlotParams, "xlabel", '=')
6419 || findParameter(_pInfo.sPlotParams, "ylabel", '=')
6420 || findParameter(_pInfo.sPlotParams, "zlabel", '='))
6421 {
6422 _graph->Label('x', fromSystemCodePage(_pData.getAxisLabel(ZCOORD)).c_str(), 0.0);
6423 _graph->Label('y', fromSystemCodePage(_pData.getAxisLabel(XCOORD)).c_str(), 0.25);
6424 }
6425
6426 _pInfo.ranges[XRANGE].reset(0.0, _pInfo.ranges[XRANGE].max());
6427 _pInfo.ranges[YRANGE].reset(0.0, 2.0*M_PI);
6428 }
6430 _graph->Axis("xy");
6431 }
6432 else // 2d plots
6433 {
6435 {
6436 case POLAR_PZ:
6437 {
6438 _graph->SetOrigin(0.0,
6441 _graph->SetFunc(CoordFunc("z*cos(pi*x*$PS$)", _pData.getAxisScale(XRANGE)).c_str(),
6442 CoordFunc("z*sin(pi*x*$PS$)", _pData.getAxisScale(XRANGE)).c_str(), "y");
6443
6444 _graph->SetRange('x', 0.0, APPR_TWO / _pData.getAxisScale(XRANGE));
6445 _graph->SetRange('y', _pInfo.ranges[YRANGE].min() / _pData.getAxisScale(YRANGE),
6447 _graph->SetRange('z', 0.0, _pInfo.ranges[ZRANGE].max() / _pData.getAxisScale(ZRANGE));
6448
6449 applyGrid();
6450
6451 _graph->SetFunc("z*cos(x)", "z*sin(x)", "y");
6452
6453 _graph->SetRange('x', 0.0, 2.0 * M_PI);
6454 _graph->SetRange('y', _pInfo.ranges[YRANGE].min(), _pInfo.ranges[YRANGE].max());
6455 _graph->SetRange('z', 0.0, _pInfo.ranges[ZRANGE].max());
6456
6457 _pInfo.ranges[XRANGE].reset(0.0, 2.0*M_PI);
6458 _pInfo.ranges[ZRANGE].reset(0.0, _pInfo.ranges[ZRANGE].max());
6459 break;
6460 }
6461 case POLAR_RP:
6462 {
6463 _graph->SetOrigin(_pInfo.ranges[XRANGE].max() / _pData.getAxisScale(XRANGE),
6464 0.0,
6466 _graph->SetFunc(CoordFunc("x*cos(pi*y*$PS$)", _pData.getAxisScale(YRANGE)).c_str(),
6467 CoordFunc("x*sin(pi*y*$PS$)", _pData.getAxisScale(YRANGE)).c_str(), "z");
6468
6469 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max() / _pData.getAxisScale(XRANGE));
6470 _graph->SetRange('y', 0.0, APPR_TWO / _pData.getAxisScale(YRANGE));
6471 _graph->SetRange('z', _pInfo.ranges[ZRANGE].min() / _pData.getAxisScale(ZRANGE),
6473
6474 applyGrid();
6475
6476 _graph->SetFunc("x*cos(y)", "x*sin(y)", "z");
6477
6478 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max());
6479 _graph->SetRange('y', 0.0, 2.0 * M_PI);
6480 _graph->SetRange('z', _pInfo.ranges[ZRANGE].min(), _pInfo.ranges[ZRANGE].max());
6481
6482 _pInfo.ranges[XRANGE].reset(0.0, _pInfo.ranges[XRANGE].max());
6483 _pInfo.ranges[YRANGE].reset(0.0, 2.0 * M_PI);
6484 break;
6485 }
6486 case POLAR_RZ:
6487 {
6488 _graph->SetOrigin(_pInfo.ranges[XRANGE].max() / _pData.getAxisScale(XRANGE),
6490 0.0);
6491 _graph->SetFunc(CoordFunc("x*cos(pi*z*$PS$)", _pData.getAxisScale(ZRANGE)).c_str(),
6492 CoordFunc("x*sin(pi*z*$PS$)", _pData.getAxisScale(ZRANGE)).c_str(), "y");
6493
6494 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max() / _pData.getAxisScale(XRANGE));
6495 _graph->SetRange('y', _pInfo.ranges[YRANGE].min() / _pData.getAxisScale(YRANGE),
6497 _graph->SetRange('z', 0.0, APPR_TWO / _pData.getAxisScale(ZRANGE));
6498
6499 applyGrid();
6500
6501 _graph->SetFunc("x*cos(z)", "x*sin(z)", "y");
6502
6503 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max());
6504 _graph->SetRange('y', _pInfo.ranges[YRANGE].min(), _pInfo.ranges[YRANGE].max());
6505 _graph->SetRange('z', 0.0, 2.0 * M_PI);
6506
6507 _pInfo.ranges[XRANGE].reset(0.0, _pInfo.ranges[XRANGE].max());
6508 _pInfo.ranges[ZRANGE].reset(0.0, 2.0*M_PI);
6509 break;
6510 }
6511 case SPHERICAL_PT:
6512 {
6513 _graph->SetOrigin(0.0,
6514 0.5 / _pData.getAxisScale(YRANGE),
6516 _graph->SetFunc(CoordFunc("z*cos(pi*x*$PS$)*sin(pi*y*$TS$)", _pData.getAxisScale(XRANGE), _pData.getAxisScale(YRANGE)).c_str(),
6517 CoordFunc("z*sin(pi*x*$PS$)*sin(pi*y*$TS$)", _pData.getAxisScale(XRANGE), _pData.getAxisScale(YRANGE)).c_str(),
6518 CoordFunc("z*cos(pi*y*$TS$)", 1.0, _pData.getAxisScale(YRANGE)).c_str());
6519
6520 _graph->SetRange('x', 0.0, APPR_TWO / _pData.getAxisScale(XRANGE));
6521 _graph->SetRange('y', 0.0, APPR_ONE / _pData.getAxisScale(YRANGE));
6522 _graph->SetRange('z', 0.0, _pInfo.ranges[ZRANGE].max() / _pData.getAxisScale(ZRANGE));
6523
6524 applyGrid();
6525
6526 _graph->SetFunc("z*cos(x)*sin(y)", "z*sin(x)*sin(y)", "z*cos(y)");
6527 _graph->SetOrigin(0.0, 0.5 * M_PI, _pInfo.ranges[ZRANGE].max());
6528 _graph->SetRange('x', 0.0, 2.0 * M_PI);
6529 _graph->SetRange('y', 0.0, 1.0 * M_PI);
6530 _graph->SetRange('z', 0.0, _pInfo.ranges[ZRANGE].max());
6531
6532 _pInfo.ranges[XRANGE].reset(0.0, 2.0*M_PI);
6533 _pInfo.ranges[YRANGE].reset(0.0, M_PI);
6534 _pInfo.ranges[ZRANGE].reset(0.0, _pInfo.ranges[ZRANGE].max());
6535 break;
6536 }
6537 case SPHERICAL_RP:
6538 {
6539 _graph->SetOrigin(_pInfo.ranges[XRANGE].max() / _pData.getAxisScale(XRANGE),
6540 0.0,
6541 0.5 / _pData.getAxisScale(ZRANGE));
6542 _graph->SetFunc(CoordFunc("x*cos(pi*y*$PS$)*sin(pi*z*$TS$)", _pData.getAxisScale(YRANGE), _pData.getAxisScale(ZRANGE)).c_str(),
6543 CoordFunc("x*sin(pi*y*$PS$)*sin(pi*z*$TS$)", _pData.getAxisScale(YRANGE), _pData.getAxisScale(ZRANGE)).c_str(),
6544 CoordFunc("x*cos(pi*z*$TS$)", 1.0, _pData.getAxisScale(ZRANGE)).c_str());
6545
6546 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max() / _pData.getAxisScale(XRANGE));
6547 _graph->SetRange('y', 0.0, APPR_TWO / _pData.getAxisScale(YRANGE));
6548 _graph->SetRange('z', 0.0, APPR_ONE / _pData.getAxisScale(ZRANGE));
6549
6550 applyGrid();
6551
6552 _graph->SetFunc("x*cos(y)*sin(z)", "x*sin(y)*sin(z)", "x*cos(z)");
6553 _graph->SetOrigin(_pInfo.ranges[XRANGE].max(), 0.0, 0.5 * M_PI);
6554 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max());
6555 _graph->SetRange('y', 0.0, 2.0 * M_PI);
6556 _graph->SetRange('z', 0.0, 1.0 * M_PI);
6557
6558 _pInfo.ranges[XRANGE].reset(0.0, _pInfo.ranges[XRANGE].max());
6559 _pInfo.ranges[YRANGE].reset(0.0, 2.0 * M_PI);
6560 _pInfo.ranges[ZRANGE].reset(0.0, M_PI);
6561 break;
6562 }
6563 case SPHERICAL_RT:
6564 {
6565 _graph->SetOrigin(_pInfo.ranges[XRANGE].max() / _pData.getAxisScale(XRANGE),
6566 0.5 / _pData.getAxisScale(YRANGE),
6567 0.0);
6568 _graph->SetFunc(CoordFunc("x*cos(pi*z*$PS$)*sin(pi*y*$TS$)", _pData.getAxisScale(ZRANGE), _pData.getAxisScale(YRANGE)).c_str(),
6569 CoordFunc("x*sin(pi*z*$PS$)*sin(pi*y*$TS$)", _pData.getAxisScale(ZRANGE), _pData.getAxisScale(YRANGE)).c_str(),
6570 CoordFunc("x*cos(pi*y*$TS$)", 1.0, _pData.getAxisScale(YRANGE)).c_str());
6571
6572 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max() / _pData.getAxisScale(XRANGE));
6573 _graph->SetRange('y', 0.0, APPR_ONE / _pData.getAxisScale(YRANGE));
6574 _graph->SetRange('z', 0.0, APPR_TWO / _pData.getAxisScale(ZRANGE));
6575
6576 applyGrid();
6577
6578 _graph->SetFunc("x*cos(z)*sin(y)", "x*sin(z)*sin(y)", "x*cos(y)");
6579 _graph->SetOrigin(_pInfo.ranges[XRANGE].max(), 0.5 * M_PI, 0.0);
6580 _graph->SetRange('x', 0.0, _pInfo.ranges[XRANGE].max());
6581 _graph->SetRange('y', 0.0, 1.0 * M_PI);
6582 _graph->SetRange('z', 0.0, 2.0 * M_PI);
6583
6584 _pInfo.ranges[XRANGE].reset(0.0, _pInfo.ranges[XRANGE].max());
6585 _pInfo.ranges[YRANGE].reset(0.0, M_PI);
6586 _pInfo.ranges[ZRANGE].reset(0.0, 2.0*M_PI);
6587 break;
6588 }
6589 default:
6590 {
6592 {
6593 // Change this settings only, if a density plot is requested
6594 if (_pInfo.sCommand == "dens" || _pInfo.sCommand == "density")
6595 {
6596 _graph->SetOrigin(_pInfo.ranges[XRANGE].min(),
6597 _pInfo.ranges[YRANGE].min(),
6598 _pInfo.ranges[ZRANGE].max());
6599 }
6600
6601 _graph->Axis();
6602 }
6603 }
6604 }
6605
6607 || findParameter(_pInfo.sPlotParams, "xlabel", '=')
6608 || findParameter(_pInfo.sPlotParams, "ylabel", '=')
6609 || findParameter(_pInfo.sPlotParams, "zlabel", '='))
6610 {
6614 }
6615 }
6616 }
6618 {
6619 if (_pInfo.ranges[XRANGE].isInside(0.0)
6620 && _pInfo.ranges[YRANGE].isInside(0.0)
6621 && _pInfo.ranges[ZRANGE].isInside(0.0)
6622 && _pInfo.nMaxPlotDim > 2 //(sCommand.find("3d") != string::npos || (_pInfo.b2D && sCommand != "dens"))
6623 )
6624 {
6625 _graph->SetOrigin(0.0, 0.0, 0.0);
6626
6628 _graph->Axis("AKDTVISO");
6629 else
6630 {
6631 _graph->SetTickLen(1e-20);
6632 _graph->SetTicks('x', -5, 1);
6633 _graph->SetTicks('y', -5, 1);
6634 _graph->SetTicks('z', -5, 1);
6635 _graph->Axis("AKDTVISO_");
6636 }
6637 }
6638 else if (_pInfo.ranges[XRANGE].isInside(0.0)
6639 && _pInfo.ranges[YRANGE].isInside(0.0)
6640 && _pInfo.nMaxPlotDim <= 2 //(sCommand.find("3d") == string::npos && !(_pInfo.b2D && sCommand != "dens"))
6641 )
6642 {
6643 _graph->SetOrigin(0.0,
6644 0.0,
6645 _pInfo.sCommand == "dens" || _pInfo.sCommand == "density" ? _pInfo.ranges[ZRANGE].max() : 0.0);
6646
6648 _graph->Axis("AKDTVISO");
6649 else
6650 {
6651 _graph->SetTickLen(1e-20);
6652 _graph->SetTicks('x', -5, 1);
6653 _graph->SetTicks('y', -5, 1);
6654 _graph->Axis("AKDTVISO_");
6655 }
6656 }
6657 else if (_pInfo.nMaxPlotDim == 3)
6658 {
6659 // Set the origin to zero where possible
6660 _graph->SetOrigin(_pInfo.ranges[XRANGE].isInside(0.0) ? 0.0 : _pInfo.ranges[XRANGE].min(),
6661 _pInfo.ranges[YRANGE].isInside(0.0) ? 0.0 : _pInfo.ranges[YRANGE].min(),
6662 _pInfo.ranges[ZRANGE].isInside(0.0) ? 0.0 : _pInfo.ranges[ZRANGE].min());
6663
6665 _graph->Axis("AKDTVISO");
6666 else
6667 {
6668 _graph->SetTickLen(1e-20);
6669 _graph->SetTicks('x', -5, 1);
6670 _graph->SetTicks('y', -5, 1);
6671 _graph->SetTicks('z', -5, 1);
6672 _graph->Axis("AKDTVISO_");
6673 }
6674
6675 }
6676 else if (_pInfo.nMaxPlotDim <= 2)
6677 {
6678 bool isDens = _pInfo.sCommand == "dens" || _pInfo.sCommand == "density";
6679
6680 // Set the origin to zero where possible
6681 _graph->SetOrigin(_pInfo.ranges[XRANGE].isInside(0.0) ? 0.0 : _pInfo.ranges[XRANGE].min(),
6682 _pInfo.ranges[YRANGE].isInside(0.0) ? 0.0 : _pInfo.ranges[YRANGE].min(),
6683 isDens ? _pInfo.ranges[ZRANGE].max() : NAN);
6684
6686 _graph->Axis("AKDTVISO");
6687 else
6688 {
6689 _graph->SetTickLen(1e-20);
6690 _graph->SetTicks('x', -5, 1);
6691 _graph->SetTicks('y', -5, 1);
6692 _graph->Axis("AKDTVISO_");
6693 }
6694 }
6695 }
6696 else if (_pData.getOrigin(XCOORD) != 0.0
6697 || _pData.getOrigin(YCOORD) != 0.0
6698 || _pData.getOrigin(ZCOORD) != 0.0)
6699 {
6700 if (_pInfo.ranges[XRANGE].isInside(_pData.getOrigin(XCOORD))
6701 && _pInfo.ranges[YRANGE].isInside(_pData.getOrigin(YCOORD))
6702 && _pInfo.ranges[ZRANGE].isInside(_pData.getOrigin(ZCOORD))
6703 && _pInfo.nMaxPlotDim > 2)
6704 {
6705 _graph->SetOrigin(_pData.getOrigin(XCOORD),
6708
6710 _graph->Axis("AKDTVISO");
6711 else
6712 {
6713 _graph->SetTickLen(1e-20);
6714 _graph->SetTicks('x', -5, 1);
6715 _graph->SetTicks('y', -5, 1);
6716 _graph->SetTicks('z', -5, 1);
6717 _graph->Axis("AKDTVISO_");
6718 }
6719 }
6720 else if (_pInfo.ranges[XRANGE].isInside(_pData.getOrigin(XCOORD))
6721 && _pInfo.ranges[YRANGE].isInside(_pData.getOrigin(YCOORD))
6722 && _pInfo.nMaxPlotDim <= 2)
6723 {
6724 _graph->SetOrigin(_pData.getOrigin(XCOORD),
6726
6728 _graph->Axis("AKDTVISO");
6729 else
6730 {
6731 _graph->SetTickLen(1e-20);
6732 _graph->SetTicks('x', -5, 1);
6733 _graph->SetTicks('y', -5, 1);
6734 _graph->Axis("AKDTVISO_");
6735 }
6736 }
6737 else if (_pInfo.nMaxPlotDim == 3)
6738 {
6739 double or_x = _pData.getOrigin(XCOORD);
6740 double or_y = _pData.getOrigin(YCOORD);
6741 double or_z = _pData.getOrigin(ZCOORD);
6742
6743 // Set the origin to the desired point where possible
6744 _graph->SetOrigin(_pInfo.ranges[XRANGE].isInside(or_x) ? or_x : _pInfo.ranges[XRANGE].min(),
6745 _pInfo.ranges[YRANGE].isInside(or_y) ? or_y : _pInfo.ranges[YRANGE].min(),
6746 _pInfo.ranges[ZRANGE].isInside(or_z) ? or_z : _pInfo.ranges[ZRANGE].min());
6747
6749 _graph->Axis("AKDTVISO");
6750 else
6751 {
6752 _graph->SetTickLen(1e-20);
6753 _graph->SetTicks('x', -5, 1);
6754 _graph->SetTicks('y', -5, 1);
6755 _graph->SetTicks('z', -5, 1);
6756 _graph->Axis("AKDTVISO_");
6757 }
6758 }
6759 else if (_pInfo.nMaxPlotDim <= 2)
6760 {
6761 double or_x = _pData.getOrigin(XCOORD);
6762 double or_y = _pData.getOrigin(YCOORD);
6763
6764 // Set the origin to the desired point where possible
6765 _graph->SetOrigin(_pInfo.ranges[XRANGE].isInside(or_x) ? or_x : _pInfo.ranges[XRANGE].min(),
6766 _pInfo.ranges[YRANGE].isInside(or_y) ? or_y : _pInfo.ranges[YRANGE].min());
6767
6769 _graph->Axis("AKDTVISO");
6770 else
6771 {
6772 _graph->SetTickLen(1e-20);
6773 _graph->SetTicks('x', -5, 1);
6774 _graph->SetTicks('y', -5, 1);
6775 _graph->Axis("AKDTVISO_");
6776 }
6777 }
6778 }
6779 else if (_pInfo.ranges[XRANGE].isInside(0.0)
6780 && _pInfo.ranges[YRANGE].isInside(0.0)
6781 && _pInfo.ranges[ZRANGE].isInside(0.0)
6782 && _pInfo.nMaxPlotDim > 2)
6783 {
6784 _graph->SetOrigin(0.0, 0.0, 0.0);
6785
6787 _graph->Axis("AKDTVISO");
6788 else
6789 {
6790 _graph->SetTickLen(1e-20);
6791 _graph->SetTicks('x', -5, 1);
6792 _graph->SetTicks('y', -5, 1);
6793 _graph->SetTicks('z', -5, 1);
6794 _graph->Axis("AKDTVISO_");
6795 }
6796 }
6797 else if (_pInfo.ranges[XRANGE].isInside(0.0)
6798 && _pInfo.ranges[YRANGE].isInside(0.0)
6799 && _pInfo.nMaxPlotDim <= 2)
6800 {
6801 _graph->SetOrigin(0.0,
6802 0.0,
6803 _pInfo.sCommand == "dens" || _pInfo.sCommand == "density" ? _pInfo.ranges[ZRANGE].max() : 0.0);
6804
6806 _graph->Axis("AKDTVISO");
6807 else
6808 {
6809 _graph->SetTickLen(1e-20);
6810 _graph->SetTicks('x', -5, 1);
6811 _graph->SetTicks('y', -5, 1);
6812 _graph->Axis("AKDTVISO_");
6813 }
6814 }
6815 else if (_pInfo.nMaxPlotDim > 2)
6816 {
6817 _graph->SetOrigin(_pInfo.ranges[XRANGE].min(),
6818 _pInfo.ranges[YRANGE].min(),
6819 _pInfo.ranges[ZRANGE].min());
6820
6822 _graph->Axis("AKDTVISO");
6823 else
6824 {
6825 _graph->SetTickLen(1e-20);
6826 _graph->SetTicks('x', -5, 1);
6827 _graph->SetTicks('y', -5, 1);
6828 _graph->SetTicks('z', -5, 1);
6829 _graph->Axis("AKDTVISO_");
6830 }
6831 }
6832 else
6833 {
6834 _graph->SetOrigin(_pInfo.ranges[XRANGE].min(),
6835 _pInfo.ranges[YRANGE].min(),
6836 _pInfo.sCommand == "dens" || _pInfo.sCommand == "density" ? _pInfo.ranges[ZRANGE].max() : _pInfo.ranges[ZRANGE].min());
6837
6839 _graph->Axis("AKDTVISO");
6840 else
6841 {
6842 _graph->SetTickLen(1e-20);
6843 _graph->SetTicks('x', -5, 1);
6844 _graph->SetTicks('y', -5, 1);
6845 _graph->SetTicks('z', -5, 1);
6846 _graph->Axis("AKDTVISO_");
6847 }
6848 }
6849 }
6850
6852 {
6853 if (_pData.getSettings(PlotData::INT_GRID) && !_pInfo.b2DVect && !_pInfo.b3DVect) // Standard-Grid
6854 {
6856 _graph->Grid("xyzt", _pData.getGridStyle().c_str());
6857 else if (_pData.getSettings(PlotData::INT_GRID) == 2)
6858 {
6859 _graph->Grid("xyzt!", _pData.getGridStyle().c_str());
6860 _graph->Grid("xyzt", _pData.getFineGridStyle().c_str());
6861 }
6862 }
6863 else if (_pData.getSettings(PlotData::INT_GRID)) // Vektor-Grid
6864 _graph->Grid("xyzt", _pData.getFineGridStyle().c_str());
6865
6867 {
6869 _graph->Box();
6870 else
6871 _graph->Box("k", false);
6872 }
6873
6874 // --> Achsen beschriften <--
6877 || findParameter(_pInfo.sPlotParams, "xlabel", '=')
6878 || findParameter(_pInfo.sPlotParams, "ylabel", '=')
6879 || findParameter(_pInfo.sPlotParams, "zlabel", '=')))
6880 {
6884 }
6885 }
6886}
6887
6888
6899double Plot::getLabelPosition(int nCoord)
6900{
6902 {
6904 return 0.0;
6905 else
6906 return 1.1;
6907 }
6908 else
6909 {
6910 const int RCOORD = XCOORD;
6911 const int PHICOORD = YCOORD;
6912 const int THETACOORD = ZCOORD;
6913 int nCoordMap[] = {RCOORD, PHICOORD, ZCOORD};
6914
6915 double dCoordPos[] = {-0.5, (_pData.getRotateAngle(1) - 225.0) / 180.0, 0.0};
6916
6918 {
6919 dCoordPos[RCOORD] = -0.4;
6920 dCoordPos[THETACOORD] = -0.9;
6921 }
6922
6924 {
6925 case POLAR_PZ:
6926 nCoordMap[XCOORD] = PHICOORD;
6927 nCoordMap[YCOORD] = ZCOORD;
6928 nCoordMap[ZCOORD] = RCOORD;
6929 break;
6930 case POLAR_RP:
6931 nCoordMap[XCOORD] = RCOORD;
6932 nCoordMap[YCOORD] = PHICOORD;
6933 nCoordMap[ZCOORD] = ZCOORD;
6934 break;
6935 case POLAR_RZ:
6936 nCoordMap[XCOORD] = RCOORD;
6937 nCoordMap[YCOORD] = ZCOORD;
6938 nCoordMap[ZCOORD] = PHICOORD;
6939 break;
6940 case SPHERICAL_PT:
6941 nCoordMap[XCOORD] = PHICOORD;
6942 nCoordMap[YCOORD] = THETACOORD;
6943 nCoordMap[ZCOORD] = RCOORD;
6944 break;
6945 case SPHERICAL_RP:
6946 nCoordMap[XCOORD] = RCOORD;
6947 nCoordMap[YCOORD] = PHICOORD;
6948 nCoordMap[ZCOORD] = THETACOORD;
6949 break;
6950 case SPHERICAL_RT:
6951 nCoordMap[XCOORD] = RCOORD;
6952 nCoordMap[YCOORD] = THETACOORD;
6953 nCoordMap[ZCOORD] = PHICOORD;
6954 break;
6955 default:
6956 return 0.0;
6957 }
6958
6959 return dCoordPos[nCoordMap[nCoord]];
6960 }
6961}
6962
6963
6972{
6974 _graph->Axis(); //U
6975 else
6976 {
6977 _graph->SetTickLen(1e-20);
6978 _graph->Axis("_");
6979 }
6980
6984 _graph->Box();
6985
6987 _graph->Grid("xyzt", _pData.getGridStyle().c_str());
6988 else if (_pData.getSettings(PlotData::INT_GRID) == 2)
6989 {
6990 _graph->Grid("xyzt!", _pData.getGridStyle().c_str());
6991 _graph->Grid("xyzt", _pData.getFineGridStyle().c_str());
6992 }
6993}
6994
6995
7008string Plot::CoordFunc(const std::string& sFuncDef, double dPhiScale, double dThetaScale)
7009{
7010 string sParsedFunction = sFuncDef;
7011
7012 if (dPhiScale == 1.0)
7013 {
7014 while (sParsedFunction.find("$PS$") != string::npos)
7015 sParsedFunction.replace(sParsedFunction.find("$PS$"), 4, "1");
7016 }
7017 else
7018 {
7019 while (sParsedFunction.find("$PS$") != string::npos)
7020 sParsedFunction.replace(sParsedFunction.find("$PS$"), 4, "(" + toString(dPhiScale, 5) + ")");
7021 }
7022
7023 if (dThetaScale == 1.0)
7024 {
7025 while (sParsedFunction.find("$TS$") != string::npos)
7026 sParsedFunction.replace(sParsedFunction.find("$TS$"), 4, "1");
7027 }
7028 else
7029 {
7030 while (sParsedFunction.find("$TS$") != string::npos)
7031 sParsedFunction.replace(sParsedFunction.find("$TS$"), 4, "(" + toString(dThetaScale, 5) + ")");
7032 }
7033
7034 return sParsedFunction;
7035}
7036
7037
7048{
7049 string sColours;
7050
7051 for (int i = 0; i < nNum; i++)
7052 {
7053 sColours += _pInfo.sLineStyles[_pInfo.nStyle];
7054
7055 if (i + 1 < nNum)
7057 }
7058
7059 return sColours;
7060}
7061
7062
7075bool Plot::checkMultiPlotArray(unsigned int nMultiPlot[2], unsigned int& nSubPlotMap, unsigned int nPlotPos, unsigned int nCols, unsigned int nLines)
7076{
7077 // cols, lines
7078 if (nPlotPos + nCols - 1 >= (nPlotPos / nMultiPlot[0] + 1)*nMultiPlot[0])
7079 return false;
7080
7081 if (nPlotPos / nMultiPlot[0] + nLines - 1 >= nMultiPlot[1])
7082 return false;
7083
7084 unsigned int nCol0, nLine0, pos;
7085 nCol0 = nPlotPos % nMultiPlot[0];
7086 nLine0 = nPlotPos / nMultiPlot[0];
7087
7088 for (unsigned int i = 0; i < nLines; i++)
7089 {
7090 for (unsigned int j = 0; j < nCols; j++)
7091 {
7092 pos = 1;
7093 pos <<= ((nCol0 + j) + nMultiPlot[0] * (nLine0 + i));
7094
7095 if (pos & nSubPlotMap)
7096 return false;
7097 }
7098 }
7099
7100 for (unsigned int i = 0; i < nLines; i++)
7101 {
7102 for (unsigned int j = 0; j < nCols; j++)
7103 {
7104 pos = 1;
7105 pos <<= ((nCol0 + j) + nMultiPlot[0] * (nLine0 + i));
7106 nSubPlotMap |= pos;
7107 }
7108 }
7109
7110 return true;
7111}
7112
7113
7114
This class is defined to abstrahize the determination of the correct data object and the calculation ...
Definition: dataaccess.hpp:38
Indices & getIndices()
Returns a reference to the stored indices.
Definition: dataaccess.cpp:196
void evalIndices()
Evaluates open end indices using the identified data object size.
Definition: dataaccess.cpp:141
bool isCluster() const
Determines, whether the data access references a cluster.
Definition: dataaccess.cpp:209
std::string & getDataObject()
Returns a reference to the data object identifier.
Definition: dataaccess.cpp:170
std::vector< size_t > getDataGridDimensions() const
Covenience wrapper method for the global function.
Definition: dataaccess.cpp:222
This class extends the std::vector for endlessness.
Definition: structures.hpp:838
This class implements the function definition managing instance.
Definition: define.hpp:74
bool call(std::string &sExpr, int nRecursion=0)
This function searches for known custom definitions in the passed expression and replaces them with t...
Definition: define.cpp:801
This class encapsulates the mglGraph object during transmission from the kernel to the GUI.
This class represents a single interval in code providing reading access functionality.
Definition: interval.hpp:34
Interval combine(const Interval &_ivl) const
Returns the (continous) interval, which contains this and the passed interval.
Definition: interval.cpp:466
double range() const
Return the real inteval range of this interval.
Definition: interval.cpp:265
void reset(const std::string &sDef)
Reset the interval with a new definition.
Definition: interval.cpp:402
mu::value_type front() const
Return the first element in the interval.
Definition: interval.cpp:187
double max() const
Return the maximal element in the interval.
Definition: interval.cpp:252
double min() const
Return the minimal element in the interval.
Definition: interval.cpp:239
std::string get(const std::string &sMessage, const std::vector< std::string > &vTokens) const
This member function returns the language string for the passed language identifier and replaces all ...
Definition: language.cpp:292
This class represents the central memory managing instance. It will handle all tables and clusters,...
std::string getTopHeadLineElement(int _i, const std::string &_sTable) const
int getLines(StringView sTable, bool _bFull=false) const
bool isTable(const std::string &sTable) const
This member function returns, whether the passed table name corresponds to a known table.
bool containsTables(const std::string &sExpression)
This member function detects, whether a table is used in the current expression.
bool isValid() const
Evaluates, whether there's at least a single non-empty table.
bool updateDimensionVariables(StringView sTableName)
This member function updates the dimension variables for the selected table to be used in expressions...
bool containsTablesOrClusters(const std::string &sCmdLine)
This member function evaluates, whether the passed command line contains tables or clusters.
int getCols(StringView sTable, bool _bFull=false) const
int getColElements(const VectorIndex &cols, const std::string &_sTable) const
Returns the maximal number of elements in the selected column range.
size_t size() const
This member function returns the size of the internal memory buffer as items.
Definition: cluster.cpp:356
Cluster & getCluster(StringView sCluster)
This member function returns a reference to the cluster indicated by the passed cluster identifier.
Definition: cluster.cpp:2077
bool isCluster(StringView sCluster) const
This member function returns true, if the passed cluster identifier can be found in the internal map.
Definition: cluster.cpp:2041
StringParserRetVal evalAndFormat(std::string &sLine, std::string &sCache, bool bSilent=false, bool bCheckAssertions=false)
This public member function evaluates the passed string expression and formats the results for the co...
void getStringValues(std::string &sLine)
This public member function resolves all string variable occurences and replaces them with their valu...
bool setItemGraph(GraphHelper *_helper, int windowItemID)
Updates the graph in the custom window.
WindowInformation getWindowInformation(size_t windowId)
This public member function will return the window information stored in the internal map....
size_t createWindow(GraphHelper *graph)
This public member function will create a window object containing the passed graph.
static NumeReKernel * getInstance()
This static member function returns a a pointer to the singleton instance of the kernel.
Definition: kernel.hpp:221
NumeRe::StringParser & getStringParser()
Definition: kernel.hpp:286
NumeRe::WindowManager & getWindowManager()
Definition: kernel.hpp:331
static void printPreFmt(const std::string &__sLine, bool printingEnabled=true)
This member function appends the pre- formatted string to the buffer and informs the terminal that we...
Definition: kernel.cpp:2683
void weightedRange(int coord, Interval &ivl) const
This member function does the "undefined data point" magic, where the range of the plot is chosen so ...
Definition: plotasset.cpp:636
IntervalSet getDataIntervals(int coord=ALLRANGES) const
Returns the intervals fitting to all selected data.
Definition: plotasset.cpp:532
IntervalSet getFunctionIntervals(int coord=ALLRANGES) const
Returns the intervals fitting to all selected data.
Definition: plotasset.cpp:546
bool hasDataPlots() const
Returns true, if the manager contains some data plots.
Definition: plotasset.cpp:666
void applyCoordSys(CoordinateSystem coords, size_t every=1)
Apply the necessary transformation for the selected coordinate system to the managed assets.
Definition: plotasset.cpp:688
void normalize(int t_animate)
Normalize the managed data to be below 1 (or the starting amplitude in an animation).
Definition: plotasset.cpp:489
std::vector< PlotAsset > assets
Definition: plotasset.hpp:193
This class contains all the plot settings usable by the plotting algorithm.
Definition: plotdata.hpp:42
std::string getColorSchemeMedium(const std::string &_sAddOpt="") const
Definition: plotdata.hpp:312
bool getInvertion(int i=0) const
Definition: plotdata.hpp:238
@ STR_BACKGROUND
Definition: plotdata.hpp:129
@ STR_FILENAME
Definition: plotdata.hpp:138
@ STR_PLOTTITLE
Definition: plotdata.hpp:145
@ STR_LINESIZES
Definition: plotdata.hpp:142
@ STR_BACKGROUNDCOLORSCHEME
Definition: plotdata.hpp:130
@ STR_POINTSTYLES
Definition: plotdata.hpp:146
bool getRangeSetting(int i=0) const
Definition: plotdata.hpp:230
int getAnimateSamples() const
Definition: plotdata.hpp:283
std::string getGridStyle() const
Definition: plotdata.hpp:343
void setFileName(std::string _sFileName)
Change the output file name.
Definition: plotdata.cpp:2411
std::string getCustomTick(int nAxis=0) const
Definition: plotdata.hpp:416
const std::vector< Line > & getHLines() const
Definition: plotdata.hpp:353
const std::vector< Line > & getVLines() const
Definition: plotdata.hpp:358
std::string getColors() const
Definition: plotdata.hpp:322
@ INT_LEGENDPOSITION
Definition: plotdata.hpp:105
@ INT_LEGENDSTYLE
Definition: plotdata.hpp:106
@ INT_COORDS
Definition: plotdata.hpp:102
@ INT_COMPLEXMODE
Definition: plotdata.hpp:100
@ INT_LIGHTING
Definition: plotdata.hpp:107
@ INT_AXIS
Definition: plotdata.hpp:99
@ INT_SAMPLES
Definition: plotdata.hpp:109
@ INT_SIZE_X
Definition: plotdata.hpp:110
@ INT_SIZE_Y
Definition: plotdata.hpp:111
@ INT_CONTLINES
Definition: plotdata.hpp:101
@ INT_HIGHRESLEVEL
Definition: plotdata.hpp:104
unsigned short getSlices(unsigned int nDir=0) const
Definition: plotdata.hpp:299
std::string getAxisLabel(size_t axis) const
Return the axis label associated to the selected axis.
Definition: plotdata.cpp:2521
const int * getTargetGUI() const
Definition: plotdata.hpp:403
std::string getLineStyles() const
Definition: plotdata.hpp:336
@ FLOAT_TEXTSIZE
Definition: plotdata.hpp:122
@ FLOAT_ALPHAVAL
Definition: plotdata.hpp:117
@ FLOAT_ASPECT
Definition: plotdata.hpp:118
@ FLOAT_HBARS
Definition: plotdata.hpp:120
@ FLOAT_PERSPECTIVE
Definition: plotdata.hpp:121
@ FLOAT_BARS
Definition: plotdata.hpp:119
IntervalSet & getRanges()
Definition: plotdata.hpp:205
double getAxisScale(int i=0) const
Definition: plotdata.hpp:246
TimeAxis getTimeAxis(unsigned int i=0) const
Definition: plotdata.hpp:393
void setGlobalComposeParams(const std::string &__sCmd)
Definition: plotdata.hpp:195
double getOrigin(int nDir=0) const
Definition: plotdata.hpp:291
void setParams(const std::string &__sCmd, int nType=ALL)
Identifies parameters and values in the passed parameter string and updates the selected type of the ...
Definition: plotdata.cpp:233
std::string getAxisbind(unsigned int i) const
Definition: plotdata.hpp:260
bool getSettings(LogicalPlotSetting setting) const
Definition: plotdata.hpp:210
int getGivenRanges() const
Definition: plotdata.hpp:268
@ SUPERGLOBAL
Definition: plotdata.hpp:57
std::string getColorScheme(const std::string &_sAddOpt="") const
Definition: plotdata.hpp:307
@ LOG_CRUST
Definition: plotdata.hpp:76
@ LOG_YERROR
Definition: plotdata.hpp:83
@ LOG_TABLE
Definition: plotdata.hpp:92
@ LOG_PARAMETRIC
Definition: plotdata.hpp:86
@ LOG_REGION
Definition: plotdata.hpp:88
@ LOG_FIXEDLENGTH
Definition: plotdata.hpp:79
@ LOG_SILENTMODE
Definition: plotdata.hpp:90
@ LOG_CONTPROJ
Definition: plotdata.hpp:75
@ LOG_XERROR
Definition: plotdata.hpp:82
@ LOG_COLORMASK
Definition: plotdata.hpp:71
@ LOG_COLORBAR
Definition: plotdata.hpp:70
@ LOG_STEPPLOT
Definition: plotdata.hpp:91
@ LOG_ALPHAMASK
Definition: plotdata.hpp:64
@ LOG_PIPE
Definition: plotdata.hpp:87
@ LOG_AREA
Definition: plotdata.hpp:66
@ LOG_CLOUDPLOT
Definition: plotdata.hpp:69
@ LOG_BOXPLOT
Definition: plotdata.hpp:68
@ LOG_ORTHOPROJECT
Definition: plotdata.hpp:85
@ LOG_INTERPOLATE
Definition: plotdata.hpp:81
@ LOG_SCHEMATIC
Definition: plotdata.hpp:89
@ LOG_FLOW
Definition: plotdata.hpp:80
@ LOG_CONNECTPOINTS
Definition: plotdata.hpp:72
@ LOG_ALPHA
Definition: plotdata.hpp:63
@ LOG_CONTLABELS
Definition: plotdata.hpp:74
@ LOG_DRAWPOINTS
Definition: plotdata.hpp:78
@ LOG_OPENIMAGE
Definition: plotdata.hpp:84
@ LOG_CONTFILLED
Definition: plotdata.hpp:73
@ LOG_CUTBOX
Definition: plotdata.hpp:77
void deleteData(bool bGraphFinished=false)
Delete the internal per-plot data (i.e. weak reset).
Definition: plotdata.cpp:2011
double getRotateAngle(int _i=0) const
Definition: plotdata.hpp:278
Axis getAddAxis(unsigned int i=0) const
Definition: plotdata.hpp:363
std::string getTickTemplate(int nAxis=0) const
Definition: plotdata.hpp:408
std::string getColorSchemeLight(const std::string &_sAddOpt="") const
Definition: plotdata.hpp:317
void setAddAxis(unsigned int i, const Interval &_ivl)
Definition: plotdata.hpp:376
void setLocalComposeParams(const std::string &__sCmd)
Definition: plotdata.hpp:200
std::string getFineGridStyle() const
Definition: plotdata.hpp:348
bool getLogscale(size_t i) const
Definition: plotdata.hpp:273
This class handles the complete plotting process.
Definition: plotting.hpp:47
void createStdPlot(size_t nPlotCompose, size_t nPlotComposeSize)
This member function wraps the creation of all one-dimensional plots (e.g. line or point plots).
Definition: plotting.cpp:1388
double getProjBackground(double dPhi, int nEdge=0)
This member function determines the positions for the projected density and contour maps,...
Definition: plotting.cpp:5939
void applyPlotSizeAndQualitySettings()
This member function determines output size and quality on the plotting target and the plotting param...
Definition: plotting.cpp:854
void determinePlottingDimensions(const std::string &sPlotCommand)
This member function determines the maximal plotting dimension of the passed command.
Definition: plotting.cpp:475
mglPoint CalcCutBox(double dPhi, int nEdge=0, int nCoords=0, bool b3D=false)
This member function calculates the two coordinates in space, which describe the cutting box....
Definition: plotting.cpp:5745
void setStyles()
This member function prepares the line and point styles based upon the currently used parameters.
Definition: plotting.cpp:3228
Plot(const Plot &)=delete
void create2dDrawing(std::vector< std::string > &vDrawVector)
This member function handles the creation of all two-dimensional drawings.
Definition: plotting.cpp:2167
std::string sFunc
Definition: plotting.hpp:54
~Plot()
Plot class destructor.
Definition: plotting.cpp:457
IntervalSet secDataRanges
Definition: plotting.hpp:52
bool bOutputDesired
Definition: plotting.hpp:53
size_t createSubPlotSet(bool &bAnimateVar, std::vector< std::string > &vPlotCompose, size_t nSubPlotStart, size_t nMultiplots[2], size_t &nSubPlots, size_t &nSubPlotMap)
This member function handles the creation of a single subplot, which may be a single plot or part of ...
Definition: plotting.cpp:515
IntervalSet dataRanges
Definition: plotting.hpp:51
std::string constructDataLegendElement(std::string &sColumnIndices, const std::string &sTableName)
This member function is used to construct special legend elements.
Definition: plotting.cpp:4285
std::string CoordFunc(const std::string &sFuncDef, double dPhiScale=1.0, double dThetaScale=1.0)
This member function is used to create a coordinate function for the coordinate system,...
Definition: plotting.cpp:7008
FunctionDefinitionManager & _functions
Definition: plotting.hpp:61
void create3dPlot()
This member function handles the creation of all three-dimensional plots.
Definition: plotting.cpp:1794
void filename(size_t nPlotComposeSize, size_t nPlotCompose)
This member function creates a default plot file name based upon the currently used plotting command.
Definition: plotting.cpp:3146
std::vector< short > m_types
Definition: plotting.hpp:50
double getLabelPosition(int nCoord)
This member function determines the position of the axis label, which depends on whether a box surrou...
Definition: plotting.cpp:6899
mu::Parser & _parser
Definition: plotting.hpp:59
std::string sOutputName
Definition: plotting.hpp:55
void applyLighting()
This member function applies the light effects to two- or three-dimensional plots....
Definition: plotting.cpp:5593
void extractDataValues(const std::vector< std::string > &vDataPlots)
Creates the internal mglData objects and fills them with the data values from the MemoryManager class...
Definition: plotting.cpp:3663
void displayMessage(bool bAnimateVar)
This member function writes a message to the terminal indicating that the algorithm is currently work...
Definition: plotting.cpp:3475
Settings & _option
Definition: plotting.hpp:60
PlotAssetManager m_manager
Definition: plotting.hpp:49
void fillData(double dt_max, int t_animate)
This member function calculates the plotting data points from usual expressions.
Definition: plotting.cpp:4589
PlotData & _pData
Definition: plotting.hpp:62
long getNN(const mglData &_mData)
This member function is a helper to return the number of data points located in the passed mglData ob...
Definition: plotting.cpp:3130
std::string expandStyleForCurveArray(const std::string &sCurrentStyle, bool expand)
This protected member function expands a style string into 9 style string with different luminosities...
Definition: plotting.cpp:3287
std::string getLegendStyle(const std::string &sLegend)
This member function prepares the legend strings to fit the selected legend style (only colours or on...
Definition: plotting.cpp:5983
bool plotstd3d(mglData _mData[3], mglData _mData2[3], const short nType)
This member function creates an actual single three-dimensional trajectory.
Definition: plotting.cpp:3014
void passRangesToGraph()
This member function informs the mglGraph object about the new plotting interval ranges.
Definition: plotting.cpp:5172
void setLogScale(bool bzLogscale)
This member function handles the complex logscale logic applied to the coordinate system of the plot.
Definition: plotting.cpp:5672
size_t countValidElements(const mglData &_mData)
This member function counts the valid data points in the passed mglData object.
Definition: plotting.cpp:4336
void applyColorbar()
This member function applies the colour bar to the plot.
Definition: plotting.cpp:5523
mglPoint createMglPoint(int nCoords, double r, double phi, double theta, bool b3D=false)
This member function creates a mglPoint instance depending on the chosen coordinate system.
Definition: plotting.cpp:5900
void CoordSettings()
This member function applies axes and axis labels to the graph.
Definition: plotting.cpp:6054
std::vector< std::string > separateFunctionsAndData()
This member function separates the functions from the data plots and returns a vector containing the ...
Definition: plotting.cpp:3590
mglGraph * _graph
Definition: plotting.hpp:65
void directionalLight(double dPhi, double dTheta, int nId, char cColor='w', double dBrightness=0.5)
This member function calculates the light source depending on the orientation of the graph....
Definition: plotting.cpp:5701
void create3dDrawing(std::vector< std::string > &vDrawVector)
This member function handles the creation of all three-dimensional drawings.
Definition: plotting.cpp:2430
void defaultRanges(size_t nPlotCompose, bool bNewSubPlot)
This member function applies the default ranges to the plotting ranges.
Definition: plotting.cpp:4428
void createStd3dPlot(size_t nPlotCompose, size_t nPlotComposeSize)
This member function wraps the creation of all trajectory-like plots (plots describing a series of po...
Definition: plotting.cpp:2797
void clearData()
Clearing member function for allocated memory on the heap.
Definition: plotting.cpp:5107
MemoryManager & _data
Definition: plotting.hpp:58
bool plot2d(mglData &_mData, mglData &_mData2, mglData *_mAxisVals, mglData &_mContVec)
This member function creates an actual single two-dimensional plot based upon the current plotting co...
Definition: plotting.cpp:1233
void create2dPlot(size_t nPlotCompose, size_t nPlotComposeSize)
This member function wraps the creation of all all two-dimensional plots (e.g. surface or density plo...
Definition: plotting.cpp:1101
void fitPlotRanges(size_t nPlotCompose, bool bNewSubPlot)
This member function fits the remaining plotting ranges for the calculated interval of data points.
Definition: plotting.cpp:4879
PlotInfo _pInfo
Definition: plotting.hpp:64
std::string composeColoursForBarChart(long int nNum)
This member function creates a special colour string, which is used for bar charts,...
Definition: plotting.cpp:7047
mglData fmod(const mglData &_mData, double dDenominator)
This member function applies a floating point modulo operator on the data set.
Definition: plotting.cpp:6009
bool createPlotOrAnimation(size_t nPlotCompose, size_t nPlotComposeSize, bool bNewSubPlot, bool bAnimateVar, std::vector< std::string > &vDrawVector, const std::vector< std::string > &vDataPlots)
This member function creates the plot or animation selected by the plotting command.
Definition: plotting.cpp:929
GraphHelper * createGraphHelper()
Definition: plotting.hpp:122
void create3dVect()
This member function handles the creation of all three-dimensional vector fields.
Definition: plotting.cpp:2076
void evaluateSubplot(std::string &sCmd, size_t nMultiplots[2], size_t &nSubPlots, size_t &nSubPlotMap)
This member function evaluates the subplot command in a plot composition and determines,...
Definition: plotting.cpp:3318
void create2dVect()
This member function handles the creation of all two-dimensional vector fields.
Definition: plotting.cpp:2122
void applyGrid()
This member function applies the grid with the selected styles to the plot.
Definition: plotting.cpp:6971
size_t nLegends
Definition: plotting.hpp:56
bool checkMultiPlotArray(unsigned int nMultiPlot[2], unsigned int &nSubPlotMap, unsigned int nPlotPos, unsigned int nCols, unsigned int nLines)
This member function checks, whether the selected subplot position is still empty.
Definition: plotting.cpp:7075
void prepareMemory()
This member function prepares the memory array in the PlotData class instance to fit the desired plot...
Definition: plotting.cpp:4361
void createDataLegends()
This member function creates the legend strings for the data plots.
Definition: plotting.cpp:4042
bool plotstd(mglData &_mData, mglData &_mAxisVals, mglData _mData2[2], const short nType)
This member function creates an actual single one-dimensional plot based upon the current plotting co...
Definition: plotting.cpp:1675
This class manages the setting values of the internal (kernel) settings of this application.
Definition: settings.hpp:663
bool systemPrints() const
Returns, whether system messages shall be printed to the terminal.
Definition: settings.hpp:1140
bool isDraftMode() const
Returns, whether the plotting draft mode is enabled.
Definition: settings.hpp:902
Common exception class for all exceptions thrown in NumeRe.
Definition: error.hpp:32
@ DATAPOINTS_CANNOT_BE_MODIFIED_WHILE_PLOTTING
Definition: error.hpp:95
@ INVALID_WINDOW_ID
Definition: error.hpp:140
@ NO_DATA_AVAILABLE
Definition: error.hpp:160
@ CANNOT_PLOT_STRINGS
Definition: error.hpp:74
@ INVALID_DATA_ACCESS
Definition: error.hpp:125
@ INVALID_SUBPLOT_INDEX
Definition: error.hpp:134
@ INVALID_WINDOW_ITEM_ID
Definition: error.hpp:141
@ NUMBER_OF_FUNCTIONS_NOT_MATCHING
INSERT HERE.
Definition: error.hpp:186
@ FUNCTION_ERROR
Definition: error.hpp:110
@ UNMATCHED_PARENTHESIS
Definition: error.hpp:224
@ PLOTDATA_IS_NAN
Definition: error.hpp:188
@ INVALID_INDEX
Definition: error.hpp:129
@ PLOT_ERROR
Definition: error.hpp:189
@ WRONG_PLOT_INTERVAL_FOR_LOGSCALE
Definition: error.hpp:228
static size_t invalid_position
Definition: error.hpp:235
VectorIndex subidx(size_t pos, size_t nLen=std::string::npos) const
This member function returns a subset of the internal stored index just like the std::string::substr(...
Definition: structures.hpp:238
void prepend(const std::vector< int > &vVector)
This function will prepend the passed vector before the beginning of the index vector....
Definition: structures.hpp:491
int last() const
This member function returns the last index value, which can be reached by the values stored internal...
Definition: structures.hpp:693
size_t size() const
This member function returns the size of the indices stored in this class.
Definition: structures.hpp:314
bool isOpenEnd() const
This member function determines, whether the internal index set has an open end.
Definition: structures.hpp:614
void setRange(int nMin, int nMax)
This member function can be used to force the indices stored internally to be in a defined interval....
Definition: structures.hpp:712
std::string to_string() const
This member function converts the vector indexes contents into a human-readable string representation...
Definition: structures.hpp:770
int & front()
This member function returns a reference to the first index value stored internally.
Definition: structures.hpp:640
size_t numberOfNodes() const
This member function returns the number of nodes describing the index set, which is stored internally...
Definition: structures.hpp:340
void SetExpr(StringView a_sExpr)
Set the expression. Triggers first time calculation thus the creation of the bytecode and scanning of...
value_type Eval()
Single-value wrapper around the vectorized overload of this member function.
Mathematical expressions parser.
Definition: muParser.h:51
mu::value_type getDataFromObject(const std::string &sObject, long long int i, long long int j, bool isCluster)
This function returns the data from the selected object and switches automatically between tables and...
DataAccessParser getAccessParserForPlotAndFit(StringView sExpression)
This function will return the access parser instance for the current expression validate,...
string getDataElements(string &sLine, Parser &_parser, MemoryManager &_data, const Settings &_option, int options)
Searches the passed string for calls to any table or cluster and replaces them with internal vectors ...
Definition: dataaccess.cpp:276
bool isNotEmptyExpression(const string &sExpr)
This function checks, whether the passed expression is non-empty (i.e. it contains more than white sp...
Language _lang
Definition: kernel.cpp:39
std::string fromSystemCodePage(std::string)
Transforms the system code page to the internal one.
std::string toSystemCodePage(std::string)
Converts an internal to an external string. Does nothing currently.
size_t findVariableInExpression(const std::string &sExpr, const std::string &sVarName, size_t nPosStart)
This function searches for the selected variable in the passed string and returns the position of the...
unsigned int getMatchingParenthesis(const StringView &)
Returns the position of the closing parenthesis.
Definition: tools.cpp:414
std::complex< double > intPower(const std::complex< double > &, int)
This function calculates the power of a value with the specialization that the exponent is an integer...
Definition: tools.cpp:3640
@ STATUS_RUNNING
CONSTCD14 std::enable_if< detail::no_overflow< Period, typenameTo::period >::value, To >::type floor(const std::chrono::duration< Rep, Period > &d)
Definition: date.h:1251
CONSTCD11 std::chrono::duration< Rep, Period > abs(std::chrono::duration< Rep, Period > d)
Definition: date.h:1317
CONSTCD14 To ceil(const std::chrono::duration< Rep, Period > &d)
Definition: date.h:1302
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:251
bool isnan(const value_type &v)
Definition: muParserDef.h:379
std::vector< double > real(const std::vector< value_type > &vVec)
bool isinf(const value_type &v)
Definition: muParserDef.h:374
string promptForUserInput(const string &__sCommand)
This function is invoked, if a prompt operator ("??") was found in a string.
void convertVectorToExpression(string &sLine, const Settings &_option)
This function replaces vector expressions with their corresponding multi- expression equation.
@ ALLRANGES
Definition: plotasset.hpp:180
@ ONLYLEFT
Definition: plotasset.hpp:181
@ ONLYRIGHT
Definition: plotasset.hpp:182
@ AXIS_NONE
Definition: plotdef.hpp:72
@ AXIS_NICE
Definition: plotdef.hpp:74
@ AXIS_EQUAL
Definition: plotdef.hpp:75
@ CPLX_PLANE
Definition: plotdef.hpp:35
@ CPLX_REIM
Definition: plotdef.hpp:34
@ TRANGE
Definition: plotdef.hpp:54
@ XRANGE
Definition: plotdef.hpp:50
@ CRANGE
Definition: plotdef.hpp:53
@ YRANGE
Definition: plotdef.hpp:51
@ ZRANGE
Definition: plotdef.hpp:52
@ PT_NONE
Definition: plotdef.hpp:25
@ PT_FUNCTION
Definition: plotdef.hpp:26
@ PT_DATA
Definition: plotdef.hpp:27
CoordinateSystem
Definition: plotdef.hpp:59
@ POLAR_RP
Definition: plotdef.hpp:62
@ POLAR_RZ
Definition: plotdef.hpp:63
@ SPHERICAL_RP
Definition: plotdef.hpp:65
@ POLAR_PZ
Definition: plotdef.hpp:61
@ SPHERICAL_RT
Definition: plotdef.hpp:66
@ SPHERICAL_PT
Definition: plotdef.hpp:64
@ CARTESIAN
Definition: plotdef.hpp:60
PlotCoords
Definition: plotdef.hpp:40
@ TCOORD
Definition: plotdef.hpp:44
@ ZCOORD
Definition: plotdef.hpp:43
@ XCOORD
Definition: plotdef.hpp:41
@ YCOORD
Definition: plotdef.hpp:42
#define APPR_TWO
Definition: plotting.cpp:94
static bool isVect3D(const std::string &sCommand)
Definition: plotting.cpp:71
static void writeTiff(mglGraph *_graph, const string &sOutputName)
This static function uses wxWidgets functionality to add TIFF exporting support to MathGL.
Definition: plotting.cpp:199
mglData duplicatePoints(const mglData &_mData)
This static function is a fix for the MathGL bug, which connects points outside of the data range.
Definition: plotting.cpp:157
static bool isVect2D(const std::string &sCommand)
Definition: plotting.cpp:66
std::string removeQuotationMarks(const std::string &)
This function simply removes the surrounding quotation marks.
mglGraph _fontData
Definition: kernel.cpp:40
DefaultVariables _defVars
static bool isMesh3D(const std::string &sCommand)
Definition: plotting.cpp:56
static bool isPlot1D(const std::string &sCommand)
Definition: plotting.cpp:35
static bool isPlot3D(const std::string &sCommand)
Definition: plotting.cpp:40
#define STYLES_COUNT
Definition: plotting.cpp:95
#define APPR_ONE
Definition: plotting.cpp:93
static void applyNiceAxis(Interval &ivl, bool isLogarithmic)
Apply the needed interval modification to switch to an optical "nice" and well readable interval.
Definition: plotting.cpp:5123
static mglData scaleSecondaryToPrimaryInterval(const mglData &_mData, const Interval &ivl, const Interval &secIvl)
Simple helper function for Plot::createStdPlot.
Definition: plotting.cpp:1372
static bool isMesh2D(const std::string &sCommand)
Definition: plotting.cpp:45
static bool hasSecAxisBox(const PlotData &_pData, const PlotInfo &_pInfo)
Static helper function to determine, whether a box is needed due to secondary axes.
Definition: plotting.cpp:6038
static bool isDraw(const std::string &sCommand)
Definition: plotting.cpp:76
static bool has3DView(const std::string &sCommand)
Definition: plotting.cpp:81
void createPlot(std::string &sCmd, MemoryManager &_data, mu::Parser &_parser, Settings &_option, FunctionDefinitionManager &_functions, PlotData &_pData)
Wrapper function for creating plots. Will create an instance of the Plot class, which will handle the...
Definition: plotting.cpp:113
#define min(a, b)
Definition: resampler.cpp:34
#define M_PI
Definition: resampler.cpp:47
#define max(a, b)
Definition: resampler.cpp:30
void StripSpaces(std::string &)
Removes leading and trailing white spaces and tabulator characters.
int findParameter(const std::string &sCmd, const std::string &sParam, const char cFollowing)
This function searches the passed parameter in the passed command string. If something is found,...
Definition: tools.cpp:113
std::string getNextArgument(std::string &sArgList, bool bCut)
Definition: tools.cpp:2294
Structure for the axes in plots.
Definition: interval.hpp:120
Interval ivl
Definition: interval.hpp:123
std::string sStyle
Definition: interval.hpp:122
std::string sLabel
Definition: interval.hpp:121
Structure for the four standard variables.
mu::value_type vValue[4][4]
This structure is central for managing the indices of a table or cluster read or write data access....
VectorIndex col
VectorIndex row
This class represents a set of intervals used together for calculations and simulations.
Definition: interval.hpp:84
void setNames(const std::vector< std::string > &vNames)
Set the interval names.
Definition: interval.cpp:677
std::vector< Interval > intervals
Definition: interval.hpp:85
Structure for the horizontal and vertical lines in plots.
Definition: interval.hpp:107
unsigned int nPos
std::string sString
This class is used by the window manager to handle the information of an opened window and to store i...
A single plot data asset to be plotted. Contains the data, its axes and its type.
Definition: plotasset.hpp:37
This structure governs the needed parameters for plotting.
Definition: plotinfo.hpp:34
bool bDraw3D
Definition: plotinfo.hpp:42
bool bDraw
Definition: plotinfo.hpp:41
std::vector< std::string > sLineStyles
Definition: plotinfo.hpp:50
unsigned int nMaxPlotDim
Definition: plotinfo.hpp:48
std::string sCommand
Definition: plotinfo.hpp:43
IntervalSet ranges
Definition: plotinfo.hpp:35
int nFunctions
Definition: plotinfo.hpp:49
bool b3DVect
Definition: plotinfo.hpp:40
bool b2D
Definition: plotinfo.hpp:37
bool b3D
Definition: plotinfo.hpp:38
std::string sPlotParams
Definition: plotinfo.hpp:44
IntervalSet secranges
Definition: plotinfo.hpp:36
bool b2DVect
Definition: plotinfo.hpp:39
int nStyle
Definition: plotinfo.hpp:46
int nextStyle() const
Returns the ID of the next style.
Definition: plotinfo.hpp:67
std::vector< std::string > sConPointStyles
Definition: plotinfo.hpp:53
std::vector< std::string > sPointStyles
Definition: plotinfo.hpp:52
int nStyleMax
Definition: plotinfo.hpp:47
std::vector< std::string > sContStyles
Definition: plotinfo.hpp:51
int nSamples
Definition: plotinfo.hpp:45
bool use
Definition: interval.hpp:134
std::string sTimeFormat
Definition: interval.hpp:133
long long int intCast(const std::complex< double > &)
Casts the real part of the complex number to an integer and avoids rounding errors.
Definition: tools.cpp:1824
std::string toString(int)
Converts an integer to a string without the Settings bloat.
Match findCommand(StringView sCmd, const std::string &sCommand)
This function is very important for the command handler.
Definition: tools.cpp:1275
bool addLegends(string &sExpr)
This function adds the missing legend strings to the expressions in the passed string.
Definition: tools.cpp:1875
string getArgAtPos(const string &sCmd, unsigned int nPos, int extraction)
Extracts a options value at the selected position and applies automatic parsing, if necessary.
Definition: tools.cpp:1598
std::string replaceToTeX(const std::string &sString, bool replaceForTeXFile)
Replace the special tokens with their TeX counterparts, so that they can be handled by a LaTeX interp...
Definition: tools.cpp:753
void writeTeXMain(const string &sTeXFile)
Definition: tools.cpp:1449
bool isInQuotes(StringView sExpr, unsigned int nPos, bool bIgnoreVarParser)
Checks, whether the position in the passed expression is part of a string literal.
Definition: tools.cpp:1672
std::string LineBreak(std::string sOutput, const Settings &_option, bool bAllowDashBreaks, int nFirstIndent, int nIndent)
This function takes a string, splits it into multiple lines if it is too long and returns the result.
Definition: tools.cpp:2205
EndlessVector< string > getAllIndices(string sArgList)
Splits up the complete index list and returns them as an EndlessVector.
Definition: tools.cpp:2384
EndlessVector< StringView > getAllArguments(StringView sArgList)
Splits up the complete argument list and returns them as an EndlessVector.
Definition: tools.cpp:2346