Logo Search packages:      
Sourcecode: octplot version File versions  Download package

line_plotter.cpp

// Copyright (C) 2005 Shai Ayal <shaiay@users.sourceforge.net>
//  
// 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.
//  
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//  
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//  

#include "line_plotter.h"
#include "gl2ps.h"

line_plotter& line_plotter::Instance()
{
  static line_plotter lp;
  return lp;
}

// markers should all fit within a box who's corners are 
// (-0.5,-0.5)-(0.5,0.5)
GLuint line_plotter::make_marker(Radio& marker, marker_part part)
{
  // first see if this marker is already defined

  std::string mname;
  if(part == face)
    mname = "F" + marker();
  else
    mname = "E" + marker();
  
  MarkerIter result = Markers.find( marker() );
  if( result != Markers.end())
    return result->second;

  GLuint listIndex;
  // first, ignore all markers w/o fill
  if( mname == "F+" ||
      mname == "F*" ||
      mname == "F." ||  
      mname == "Fx" ) {
    listIndex = 0;
  }
  else {
    listIndex = glGenLists(1);
    glNewList(listIndex,GL_COMPILE);
  }

  if(mname=="E+") {
    glBegin(GL_LINES);
    glVertex2f(-0.5,0);
    glVertex2f(0.5,0);
    glVertex2f(0,-0.5);
    glVertex2f(0,0.5);
    glEnd();
  }
  else if(mname[1]=='o') {
    if(mname[0]=='E') glBegin(GL_LINE_LOOP);
    else glBegin(GL_POLYGON);
    const double pi      = 3.14159265358979;
    const int segs = 20;
    for(int i=0;i<segs;i++) glVertex2f(sin(2*pi/segs*i)/2,cos(2*pi/segs*i)/2);
    glEnd();
  }
  else if(mname=="E*") {
    const double sqrt2d4 = 0.35355339059327;
    glBegin(GL_LINES);
    glVertex2f(-0.5,0);
    glVertex2f(0.5,0);
    glVertex2f(0,-0.5);
    glVertex2f(0,0.5);
    glVertex2f(-sqrt2d4,-sqrt2d4);
    glVertex2f(+sqrt2d4,+sqrt2d4);
    glVertex2f(-sqrt2d4,+sqrt2d4);
    glVertex2f(+sqrt2d4,-sqrt2d4);
    glEnd();
  }
  else if(mname=="E.") {
    glBegin(GL_POLYGON);
    glVertex2f(-0.1,-0.1);
    glVertex2f(-0.1,0.1);
    glVertex2f(0.1,0.1);
    glVertex2f(0.1,-0.1);
    glEnd();
  }
  else if(mname[1]=='d') {
    if(mname[0]=='E') glBegin(GL_LINE_LOOP);
    else glBegin(GL_POLYGON);
    glVertex2f(0,0.5);
    glVertex2f(0.5,0);
    glVertex2f(0,-0.5);
    glVertex2f(-0.5,0);
    glEnd();
  }
  else if(mname[1]=='s') {
    if(mname[0]=='E') glBegin(GL_LINE_LOOP);
    else glBegin(GL_POLYGON);
    glVertex2f(-0.5,0.5);
    glVertex2f(0.5,0.5);
    glVertex2f(0.5,-0.5);
    glVertex2f(-0.5,-0.5);
    glEnd();
  }
  else if(mname[1]=='^') {
    if(mname[0]=='E') glBegin(GL_LINE_LOOP);
    else glBegin(GL_POLYGON);
    glVertex2f(0,0.5);
    glVertex2f(0.5,-0.5);
    glVertex2f(-0.5,-0.5);
    glEnd();
  }
  else if(mname[1]=='v') {
    if(mname[0]=='E') glBegin(GL_LINE_LOOP);
    else glBegin(GL_POLYGON);
    glVertex2f(0,-0.5);
    glVertex2f(-0.5,0.5);
    glVertex2f(0.5,0.5);
    glEnd();
  }
  else if(mname[1]=='>') {
    if(mname[0]=='E') glBegin(GL_LINE_LOOP);
    else glBegin(GL_POLYGON);
    glVertex2f(0.5,0);
    glVertex2f(-0.5,0.5);
    glVertex2f(-0.5,-0.5);
    glEnd();
  }
  else if(mname[1]=='<') {
    if(mname[0]=='E') glBegin(GL_LINE_LOOP);
    else glBegin(GL_POLYGON);
    glVertex2f(-0.5,0);
    glVertex2f(0.5,-0.5);
    glVertex2f(0.5,0.5);
    glEnd();
  }
  else {//if(mname=="x") {
    glBegin(GL_LINES);
    glVertex2f(-0.5,-0.5);
    glVertex2f(0.5,0.5);
    glVertex2f(-0.5,0.5);
    glVertex2f(0.5,-0.5);
    glEnd();
  }

  if(listIndex) glEndList();
  Markers[mname] = listIndex;
    
  return listIndex;
}

void line_plotter::plot(Matrix& xdata,
                  Matrix& ydata,
                  Radio&  linestyle,
                  Color*  color,
                  double  linewidth,
                  Color&  markerfacecolor,
                  Color&  markeredgecolor,
                  Radio&  marker,
                  double  markersize,
                  Axes*   axes,
                  bool    printing,
                  bool    loop,
                  bool    legend)
{
  
  Radio& xscale = ::Get<Radio>(axes,"xscale");
  Radio& yscale = ::Get<Radio>(axes,"yscale");
  double obz = object_z;

  if(linestyle()!="-" && linestyle()!="none" && color->IsColor()) {
    glEnable(GL_LINE_STIPPLE);

    if(linestyle()==":")  glLineStipple(1, 0x6666);
    else if(linestyle()=="--") glLineStipple(2, 0xF0F0);
    else if(linestyle()=="-.") glLineStipple(2, 0x6F6F);
    else glLineStipple(1, 0xFFFF);
    if(printing) gl2psEnable(GL2PS_LINE_STIPPLE);
  }
 
  if(linestyle()!="none" && color->IsColor()) {
    color->SetColor();
    glLineWidth(linewidth);
    if(printing) gl2psLineWidth( linewidth );
    if(xdata.nc()*xdata.nr())
    {
      if(xscale()=="linear" && yscale()=="linear") {
      plot_helper lp(xdata(0),ydata(0),obz,loop);
      for(long i=1; i<xdata.nc()*xdata.nr(); i++) 
        lp.add_point(xdata(i),ydata(i),obz);
      }
      else {
      plot_helper lp(LOGIT(xdata(0),xscale()=="log"),
                  LOGIT(ydata(0),yscale()=="log"),
                   obz,loop);
      for(long i=1; i<xdata.nc()*xdata.nr(); i++) {
        lp.add_point(LOGIT(xdata(i),xscale()=="log"),
                   LOGIT(ydata(i),yscale()=="log"),
                   obz);
      }
      }
    }
    else {
      if(xscale()=="normal" && yscale()=="normal") {
      plot_helper lp(1.0,ydata(0),obz,loop);
      for(long i=1; i<ydata.nc()*ydata.nr(); i++) 
        lp.add_point(static_cast<double>(i+1),ydata(i),obz);
      }
      else {
      plot_helper lp(LOGIT(1,xscale()=="log"),
                  LOGIT(ydata(0),yscale()=="log"),
                   obz,loop);
      for(long i=1; i<ydata.nc()*ydata.nr(); i++) {
        lp.add_point(LOGIT(i+1,xscale()=="log"),
                   LOGIT(ydata(i),yscale()=="log"),
                   obz);
      }
      }
    }
  }

  if(linestyle()!="-" && linestyle()!="none" && color->IsColor()) {
    glDisable(GL_LINE_STIPPLE);
    if(printing) gl2psDisable(GL2PS_LINE_STIPPLE);
  }

  if(marker()!="none") {
    GLuint marker_edge=make_marker(marker,edge);
    GLuint marker_face=make_marker(marker,face);
   
    ocpl::Real dx,dy;
    axes->GetPixel(dx,dy);

    long init = legend ? 1 : 0;
    long stop = legend ? ydata.len() -1 : ydata.len();
    for(long i=init; i<stop; i++) {
      // handle NaN's
      double x,y;
      y = LOGIT(ydata(i),yscale()=="log");
      if(xdata.nc()*xdata.nr()) 
            x = LOGIT(xdata(i),xscale()=="log");
      else  
            x = LOGIT(i+1,xscale()=="log");
      
      if( isnan(y) || isnan(x) ) continue;

      glPushMatrix();
      glTranslatef(x,y,0);
      glScalef(markersize*dx,markersize*dy,1);
      if(marker_face && markerfacecolor.SetColor()) {
        glTranslatef(0,0,markerf_z);
        glCallList(marker_face);
        glTranslatef(0,0,-markerf_z);
      }
      markeredgecolor.SetColor();
      glTranslatef(0,0,markere_z);
      glCallList(marker_edge);
      glPopMatrix();
    }
  }

}

Generated by  Doxygen 1.6.0   Back to index