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

/***************************************************************************
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()
{
}