You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
380 lines
12 KiB
380 lines
12 KiB
/***************************************************************************
|
|
qscontour.h
|
|
-------------------
|
|
begin : 01-January-2000
|
|
copyright : (C) 2000 by Kamil Dobkowski
|
|
email : kamildobk@poczta.onet.pl
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
|
|
#ifndef QSCONTOUR_H
|
|
#define QSCONTOUR_H
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
#include"qsaxes.h"
|
|
#include"qsplot.h"
|
|
#include<math.h>
|
|
|
|
|
|
/**
|
|
* \brief Abstract base class for contour datasets.
|
|
*
|
|
* Draws contours. It contains a pure virtual functions which must be
|
|
* reimplemented to get it to work.
|
|
* @author Kamil Dobkowski
|
|
*/
|
|
class QSContour : public QSPlot2D
|
|
{
|
|
Q_OBJECT
|
|
Q_PROPERTY( bool contourFills READ contourFills WRITE setContourFills )
|
|
Q_PROPERTY( bool contourLines READ contourLines WRITE setContourLines )
|
|
Q_PROPERTY( bool contourLabels READ contourLabels WRITE setContourLabels )
|
|
Q_PROPERTY( double labelSpacing READ labelSpacing WRITE setLabelSpacing )
|
|
|
|
public:
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
QSContour(QSAxes* parent, const char * name=0);
|
|
/**
|
|
* Destructor.
|
|
*/
|
|
virtual ~QSContour();
|
|
|
|
void setContourFills( bool visible );
|
|
void setContourLines( bool visible );
|
|
void setContourLabels( bool visible );
|
|
void setLabelSpacing( double labelSpacing );
|
|
|
|
bool contourFills() const { return m_fills; }
|
|
bool contourLines() const { return m_lines; }
|
|
bool contourLabels() const { return m_labels; }
|
|
double labelSpacing() const { return m_label_spacing; }
|
|
|
|
virtual QString posInfo( QSPt2f& pos );
|
|
virtual bool isClicked( const QSPt2f& pos );
|
|
virtual QSPt2f legendItemSize( QSDrv *drv );
|
|
virtual void drawLegendItem( const QSPt2f& pos, QSDrv *drv );
|
|
|
|
virtual void loadStateFromStream( QDataStream& stream, QSObjectFactory *factory );
|
|
virtual void saveStateToStream( QDataStream& stream, QSObjectFactory *factory );
|
|
/**
|
|
* See QSGraphicalData::setPoint()
|
|
*/
|
|
enum PointElement { PointMark = 0 };
|
|
/**
|
|
* See QSGraphicalData::setLine()
|
|
*/
|
|
enum LineElement { Grid = 0 };
|
|
|
|
protected:
|
|
|
|
/**
|
|
* See getTriangle()
|
|
*/
|
|
static const double EPS_VALUE;
|
|
|
|
virtual void allocRuntimeData();
|
|
virtual void freeRuntimeData();
|
|
virtual bool start();
|
|
/**
|
|
* This will be called until it returns true and can be reimplemented for
|
|
* some in the background stuff.
|
|
*/
|
|
virtual bool prepare() { return true; }
|
|
virtual bool step();
|
|
virtual void end();
|
|
/**
|
|
* Returns a total number of triangles.
|
|
*/
|
|
virtual int triangles() = 0;
|
|
/**
|
|
* Returns triangle number 'number'.
|
|
* The first edge is between pts[0] and pts[1]
|
|
* the second one is between pts[1] and pts[2]
|
|
* the third one is between pts[2] and pts[0]
|
|
* point z values must not be equal to level. If there is such point add EPS_VALUE
|
|
* to its z coordinate.
|
|
* see: getNeighboutingTriangle()
|
|
*/
|
|
virtual void getTriangle( int number, QSPt3f pts[3], double level = -10.0 ) = 0;
|
|
/**
|
|
* Returns if there is a neighbouring triangle. In 'number' and 'edge'
|
|
* returns a neighbouring triangle and edge of triangle 'number' and edge 'edge'.
|
|
*/
|
|
virtual bool getNeighbouringTriangle( int *number, int *edge ) = 0;
|
|
/**
|
|
* Returns a number of a triangle which contains the point 'pos' if any or -1.
|
|
* Used by 'isClicked' and 'posInfo' subroutines.
|
|
* Nothing really nessesary
|
|
*/
|
|
virtual int triangleAtPos( const QSPt2f& pos ) = 0;
|
|
/**
|
|
* Returns info about the vertex 'v' of the triangle 't'.
|
|
* Nothing really nessesary
|
|
*/
|
|
virtual QString vertexInfo( int t, int v, QSPt2f& pos ) = 0;
|
|
/**
|
|
* Draw grid ( lines connecting data points )
|
|
*/
|
|
virtual void drawGrid() = 0;
|
|
/**
|
|
* Draw point marks
|
|
*/
|
|
virtual void drawPoints() = 0;
|
|
/**
|
|
* Reimplement this to return true if the contour is drawn over rectangle grid.
|
|
* The getRectangle() method should be reimplemented too in this case. Rectangles
|
|
* are assumed be divided into four triangles. Rectangle 0 contains triangles 0-3,
|
|
* rectangle 1 contains triangles 4-7 etc ...
|
|
*/
|
|
virtual bool rectangleGrid() const { return false; }
|
|
/**
|
|
* Reimplement this to return rectangle coordinates if the contour is drawn over rectangle grid.
|
|
* The rectangleGrid() method should be reimplemented too in this case. Rectangles
|
|
* are assumed be divided into four triangles. Rectangle 0 contains triangles 0-3,
|
|
* rectangle 1 contains triangles 4-7 etc ... The function id provided for efficiency only.
|
|
* Whole rectangles ( four triangles ) will be processed in a single step during drawing.
|
|
*/
|
|
virtual void getRectangle( int triangleNumber, QSPt3f pts[4] ) {}
|
|
|
|
|
|
private:
|
|
bool m_labels;
|
|
bool m_fills;
|
|
bool m_lines;
|
|
double m_label_spacing;
|
|
struct contour_runtime_data;
|
|
struct contour_levels_data;
|
|
struct contour_runtime_data *d;
|
|
|
|
void init_triangle_buffer();
|
|
void call_prepare();
|
|
void start_drawing_fills();
|
|
void drawing_fills();
|
|
void start_drawing_grid();
|
|
void drawing_grid();
|
|
void start_drawing_lines();
|
|
void drawing_lines();
|
|
void start_drawing_labels();
|
|
void drawing_labels();
|
|
void start_drawing_points();
|
|
void drawing_points();
|
|
|
|
void calculate_levels_data( contour_levels_data *data );
|
|
void free_levels_data( contour_levels_data *data );
|
|
void start_contour( const QSPt3f& p1, const QSPt3f& p2, int level );
|
|
void draw_contour( const QSPt3f& p1, const QSPt3f& p2, int level );
|
|
void end_contour( int level );
|
|
void draw_line_buffer( int level );
|
|
|
|
void cut_polygon( double level, const QSPt3f *pts, int npts,
|
|
QSPt3f *above_pts, int *above_npts,
|
|
QSPt3f *under_pts, int *under_npts,
|
|
QSPt3f *cross_line = NULL, int *cross_npts = NULL );
|
|
inline double distance( const QSPt2f& p1, const QSPt2f& p2 );
|
|
int find_level_greater_than( double value );
|
|
void flush_rectangle_buffer();
|
|
bool draw_rectangle( const QSPt3f pts[4] );
|
|
};
|
|
|
|
|
|
inline double QSContour::distance( const QSPt2f& p1, const QSPt2f& p2 )
|
|
{
|
|
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------------------------//
|
|
|
|
|
|
/**
|
|
* \brief Dataset : Draws contours over gridded data.
|
|
*
|
|
* Data format is described in QSGriddedContour::Channels . See also QSAxes::plotAdd() .
|
|
* @author Kamil Dobkowski
|
|
*/
|
|
class QSGriddedContour : public QSContour
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
/**
|
|
* Descriptive names of data channels. See QSData::setMatrix().
|
|
* Data contains Z values,
|
|
* XVector ( optional ) contains x coordinates of a grid, YVector ( optional ) contains y coordinates of a grid.
|
|
* cols(XVector) == cols(Data) and rows(YVector) == rows(Data), both vectors must be monotone.
|
|
*/
|
|
enum Channels {
|
|
XVector = 0,
|
|
YVector = 1, // Column vector, monotone. Size 1 x h+1
|
|
Data = 2
|
|
};
|
|
/**
|
|
* Destructor.
|
|
*/
|
|
QSGriddedContour(QSAxes* parent, const char * name=0);
|
|
/**
|
|
* Destructor.
|
|
*/
|
|
virtual ~QSGriddedContour();
|
|
virtual ColumnType columnType( int channel, int column ) const;
|
|
virtual QString channelVariable( int channel ) const;
|
|
virtual void loadStateFromStream( QDataStream& stream, QSObjectFactory *factory );
|
|
virtual void saveStateToStream( QDataStream& stream, QSObjectFactory *factory );
|
|
|
|
protected:
|
|
virtual bool getAxisRange( QSAxis *axis, double& min, double& max );
|
|
virtual void dataChanged( int channel = -1 );
|
|
virtual void allocRuntimeData();
|
|
virtual void freeRuntimeData();
|
|
virtual int triangles();
|
|
virtual void getTriangle( int number, QSPt3f pts[3], double level = -10.0 );
|
|
virtual bool getNeighbouringTriangle( int *number, int *edge );
|
|
virtual int triangleAtPos( const QSPt2f& pos );
|
|
virtual QString vertexInfo( int t, int v, QSPt2f& pos );
|
|
virtual void drawGrid();
|
|
virtual void drawPoints();
|
|
virtual bool rectangleGrid() const { return true; }
|
|
virtual void getRectangle( int triangleNumber, QSPt3f pts[4] );
|
|
|
|
private:
|
|
double m_dmin;
|
|
double m_dmax;
|
|
bool m_evalid;
|
|
void calculate_data_range();
|
|
double xvector( int col );
|
|
double yvector( int row );
|
|
struct gridded_contour_runtime_data;
|
|
gridded_contour_runtime_data *d;
|
|
void load_mesh_into_buffer( int triangleNumber );
|
|
};
|
|
|
|
//------------------------------------------------------------------------------------------------------------------//
|
|
|
|
|
|
/**
|
|
* \brief Dataset: Draws contours over non-gridded data.
|
|
*
|
|
* Data format is described in QSNonGriddedContour::Channels . See also QSAxes::plotAdd() .
|
|
* @author Kamil Dobkowski
|
|
*/
|
|
class QSNonGriddedContour : public QSContour
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
/**
|
|
* Descriptive names of data channels. See QSData::setMatrix().
|
|
* VXCoords, VYCoord, VZCoord must have a one column and the same number of rows.
|
|
* VXCoord contains x coordinates, VYCords contains y coordinates, and VZCoord contains z coordinates.
|
|
* The same row in all those matrices defines a one data point, so we have rows(VXCoord) data points.
|
|
* Triangles must have three columns and must contain indices to rows in Coord matrices, so one index
|
|
* defines one point. One row in Triangles defines a one traingle. Such matrix can be calculated by
|
|
* triangulating the given set of points, Traiangles is required because this object just can't draw
|
|
* contour using only data points.
|
|
*/
|
|
enum Channels {
|
|
VXCoord = 0,
|
|
VYCoord = 1,
|
|
VZCoord = 2,
|
|
Triangles = 3 // size 3 x number of triangles
|
|
};
|
|
/**
|
|
* Destructor.
|
|
*/
|
|
QSNonGriddedContour(QSAxes* parent, const char * name=0);
|
|
/**
|
|
* Destructor.
|
|
*/
|
|
virtual ~QSNonGriddedContour();
|
|
virtual ColumnType columnType( int channel, int column ) const;
|
|
virtual QString channelVariable( int channel ) const;
|
|
virtual void loadStateFromStream( QDataStream& stream, QSObjectFactory *factory );
|
|
virtual void saveStateToStream( QDataStream& stream, QSObjectFactory *factory );
|
|
|
|
protected:
|
|
virtual bool getAxisRange( QSAxis *axis, double& min, double& max );
|
|
virtual void dataChanged( int channel = -1 );
|
|
virtual bool prepare();
|
|
virtual void allocRuntimeData();
|
|
virtual void freeRuntimeData();
|
|
virtual int triangles();
|
|
virtual void getTriangle( int number, QSPt3f pts[3], double level = -10.0 );
|
|
virtual bool getNeighbouringTriangle( int *number, int *edge );
|
|
virtual int triangleAtPos( const QSPt2f& pos );
|
|
virtual QString vertexInfo( int t, int v, QSPt2f& pos );
|
|
virtual void drawGrid();
|
|
virtual void drawPoints();
|
|
|
|
private:
|
|
bool m_evalid;
|
|
double m_xmax;
|
|
double m_ymax;
|
|
double m_zmax;
|
|
double m_xmin;
|
|
double m_ymin;
|
|
double m_zmin;
|
|
int *m_neighbours[3];
|
|
struct non_gridded_contour_runtime_data;
|
|
non_gridded_contour_runtime_data *d;
|
|
QSPt3f point( int index );
|
|
void search_for_neighbours();
|
|
void make_visible_triangles_list();
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|