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.
433 lines
11 KiB
433 lines
11 KiB
/***************************************************************************
|
|
QSSegment.cpp
|
|
-------------------
|
|
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. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
|
|
#include "qssegment.h"
|
|
#include "qsdrv.h"
|
|
#include "qscurve.h"
|
|
#include "qsaxes.h"
|
|
#include <assert.h>
|
|
|
|
QSSegment::QSSegment()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
QSSegment::~QSSegment()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
int QSSegment::startDraw( const QSCurve *parent )
|
|
{
|
|
m_parent = parent;
|
|
m_drv = m_parent->parentAxes()->run_gDriver();
|
|
return 0;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSegment::initPass( int )
|
|
{
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------//
|
|
//------------------------------------------------------------//
|
|
// LINES
|
|
//------------------------------------------------------------//
|
|
|
|
QSSLines::QSSLines()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
QSSLines::~QSSLines()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
int QSSLines::startDraw( const QSCurve *parent )
|
|
{
|
|
QSSegment::startDraw( parent );
|
|
return 1;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSLines::initPass( int )
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSLines::drawSegment( int nr, const QSPt2f& pos, const QSPt2f&, const QSGLine& l, const QSGFill&, const QSGArrow&, const QSGArrow& )
|
|
// dorobic strzalki i xmin i xmax
|
|
{
|
|
QSPt2f curr = m_parent->dataToWorld( pos );
|
|
m_drv->setLine( m_curr_line ); m_curr_line = l;
|
|
if ( nr == 0 ) m_drv->beginPolyline2(curr);
|
|
else m_drv->drawPolylineTo2(curr);
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSLines::endPass()
|
|
{
|
|
m_drv->endPolyline2();
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSLines::stopDraw()
|
|
{
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------//
|
|
// BARS
|
|
//------------------------------------------------------------//
|
|
|
|
QSSBars::QSSBars()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
QSSBars::~QSSBars()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
int QSSBars::startDraw( const QSCurve *parent )
|
|
{
|
|
assert( parent );
|
|
QSSegment::startDraw( parent );
|
|
m_zero_level = m_parent->dataToWorld( m_parent->zeroPoint() ).y;
|
|
return 1;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSBars::initPass( int )
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSBars::drawSegment( int nr, const QSPt2f& pos, const QSPt2f&, const QSGLine& l, const QSGFill& f, const QSGArrow&, const QSGArrow& )
|
|
{
|
|
m_drv->setLine( m_curr_line );
|
|
m_drv->setFill( m_curr_fill );
|
|
m_curr_line = l;
|
|
m_curr_fill = f;
|
|
draw_bar( nr, m_parent->dataToWorld(pos) );
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSBars::endPass()
|
|
{
|
|
draw_bar( 2, QSPt2f(m_prev.x+2.0*(m_prev.x-m_prevx),0.0) );
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSBars::draw_bar( int nr, const QSPt2f& pos )
|
|
{
|
|
double currx = 0.0;
|
|
if ( nr ) {
|
|
currx = (pos.x-m_prev.x)/2.0 + m_prev.x;
|
|
if ( nr == 1 ) m_prevx = m_prev.x - (pos.x-m_prev.x)/2.0;
|
|
QSPt2f inpts[4];
|
|
inpts[0].set( m_prevx, m_zero_level );
|
|
inpts[1].set( currx, m_zero_level );
|
|
inpts[2].set( currx, m_prev.y );
|
|
inpts[3].set( m_prevx, m_prev.y );
|
|
m_drv->drawPoly2( inpts, 4 );
|
|
}
|
|
|
|
m_prevx = currx;
|
|
m_prev = pos;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSBars::stopDraw()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
// VECTORS
|
|
//------------------------------------------------------------//
|
|
|
|
QSSFigures::QSSFigures( Style style )
|
|
{
|
|
m_style = style;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
QSSFigures::~QSSFigures()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
int QSSFigures::startDraw( const QSCurve *parent )
|
|
{
|
|
assert( parent );
|
|
QSSegment::startDraw( parent );
|
|
return 1;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSFigures::initPass( int )
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSFigures::drawSegment( int, const QSPt2f& pos, const QSPt2f& delta, const QSGLine& l, const QSGFill& f, const QSGArrow& a1, const QSGArrow& a2 )
|
|
{
|
|
QSPt2f p1;
|
|
QSPt2f p2;
|
|
if ( m_style == Flux ) {
|
|
QSPt2f delta2 = QSPt2f( delta.x/2.0, delta.y/2.0 );
|
|
p1 = m_parent->dataToWorld( pos-delta2 );
|
|
p2 = m_parent->dataToWorld( pos+delta2 );
|
|
} else {
|
|
p1 = m_parent->dataToWorld( pos );
|
|
p2 = m_parent->dataToWorld( pos+delta );
|
|
}
|
|
|
|
m_drv->setLine( l );
|
|
if ( m_style == Vectors || m_style == Flux ) {
|
|
m_drv->drawArrow2( p1, p2, a1, a2 );
|
|
}
|
|
else if ( m_style == Ellipses ) {
|
|
m_drv->setFill( f );
|
|
m_drv->drawEllipse2( p1, p2 );
|
|
}
|
|
else if ( m_style == Rectangles ) {
|
|
m_drv->setFill( f );
|
|
m_drv->drawRect2( p1, p2 );
|
|
}
|
|
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSFigures::endPass()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSFigures::stopDraw()
|
|
{
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------//
|
|
// Polys
|
|
//------------------------------------------------------------//
|
|
|
|
QSSPolys::QSSPolys( Style style )
|
|
{
|
|
m_style = style;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
QSSPolys::~QSSPolys()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
int QSSPolys::startDraw( const QSCurve *parent )
|
|
{
|
|
assert( parent );
|
|
QSSegment::startDraw( parent );
|
|
m_zero_level = m_parent->dataToWorld( m_parent->zeroPoint() ).y;
|
|
return ( m_style == Ribbon ? 3 : 2 );
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSPolys::initPass( int init_pass )
|
|
{
|
|
m_pass = init_pass;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSPolys::drawSegment( int nr, const QSPt2f& pos, const QSPt2f& delta, const QSGLine& l, const QSGFill& f, const QSGArrow&, const QSGArrow& )
|
|
{
|
|
QSPt2f p1;
|
|
QSPt2f p2;
|
|
if ( m_style == Ribbon ) {
|
|
p1 = m_parent->dataToWorld( pos-delta );
|
|
p2 = m_parent->dataToWorld( pos+delta );
|
|
} else {
|
|
p1 = m_parent->dataToWorld( pos );
|
|
p2 = QSPt2f( p1.x, m_zero_level );
|
|
}
|
|
|
|
// first draw filled area
|
|
if ( m_pass==0 && nr ) {
|
|
QSPt2f inpts[4];
|
|
inpts[0] = m_prev1;
|
|
inpts[1] = m_prev2;
|
|
inpts[2] = p2;
|
|
inpts[3] = p1;
|
|
m_drv->setLine(QSGLine::invisibleLine);
|
|
m_drv->setFill( m_curr_fill );
|
|
m_drv->drawPoly2( inpts, 4 );
|
|
}
|
|
// draw upper or lower line
|
|
else if ( m_pass != 0 ) {
|
|
QSPt2f pos1;
|
|
QSPt2f pos2;
|
|
if ( m_pass == 1 ) { pos1 = m_prev1; pos2 = p1; }
|
|
if ( m_pass == 2 ) { pos1 = m_prev2; pos2 = p2; }
|
|
m_drv->setLine( m_curr_line );
|
|
if ( nr == 0 ) m_drv->beginPolyline2( pos2 );
|
|
else m_drv->drawPolylineTo2( pos2 );
|
|
}
|
|
m_curr_fill = f;
|
|
m_curr_line = l;
|
|
m_prev1 = p1;
|
|
m_prev2 = p2;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSPolys::endPass()
|
|
{
|
|
if ( m_pass == 1 || m_pass == 2 ) m_drv->endPolyline2();
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSPolys::stopDraw()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
//------------------------------------------------------------//
|
|
// STAIRS
|
|
//------------------------------------------------------------//
|
|
|
|
QSSStairs::QSSStairs( Style style )
|
|
{
|
|
m_style = style;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
QSSStairs::~QSSStairs()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
int QSSStairs::startDraw( const QSCurve *parent )
|
|
{
|
|
assert( parent );
|
|
QSSegment::startDraw( parent );
|
|
return 1;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSStairs::initPass( int )
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSStairs::drawSegment( int nr, const QSPt2f& pos, const QSPt2f&, const QSGLine& l, const QSGFill&, const QSGArrow&, const QSGArrow& )
|
|
{
|
|
QSPt2f pts[3];
|
|
QSPt2f curr = m_parent->dataToWorld( pos );
|
|
if ( nr == 0 ) {
|
|
m_prev_prev = m_prev = curr;
|
|
m_drv->beginPolyline2( curr );
|
|
} else {
|
|
get_stair( curr, pts );
|
|
m_drv->setLine( curr_line );
|
|
m_drv->drawPolylineTo2( pts[1] );
|
|
m_drv->drawPolylineTo2( pts[2] );
|
|
}
|
|
|
|
curr_line = l;
|
|
m_prev_prev = m_prev;
|
|
m_prev = curr;
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSStairs::endPass()
|
|
{
|
|
QSPt2f pts[3];
|
|
m_drv->setLine( curr_line );
|
|
get_stair( m_prev, pts );
|
|
m_drv->drawPolylineTo2( pts[1] );
|
|
m_drv->endPolyline2();
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSStairs::get_stair( const QSPt2f& pos, QSPt2f pts[3] )
|
|
{
|
|
switch( m_style ) {
|
|
case Left:
|
|
pts[0] = m_prev;
|
|
pts[1] = QSPt2f( m_prev.x, pos.y );
|
|
pts[2] = pos;
|
|
break;
|
|
case Middle:
|
|
pts[0] = QSPt2f( m_prev_prev.x + (m_prev.x-m_prev_prev.x)/2.0, m_prev.y );
|
|
pts[1] = QSPt2f( m_prev.x + (pos.x-m_prev.x)/2.0, m_prev.y );
|
|
pts[2] = QSPt2f( m_prev.x + (pos.x-m_prev.x)/2.0, pos.y );
|
|
break;
|
|
case Right:
|
|
pts[0] = m_prev;
|
|
pts[1] = QSPt2f( pos.x, m_prev.y );
|
|
pts[2] = pos;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------//
|
|
|
|
void QSSStairs::stopDraw()
|
|
{
|
|
}
|
|
|
|
|