⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fl_cartesian.cpp

📁 MSP430FG437 SPO2 Source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// Cartesian.H,v 0.9
//
// Copyright 2000 by Roman Kantor.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public License
// version 2 as published by the Free Software Foundation.
//
// This library is distributed  WITHOUT ANY WARRANTY;
// WITHOUT even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.


#include "Fl_Cartesian.H"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <FL/fl_draw.H>
#include <FL/Fl.H>
#include <FL/Fl_Group.H>




static const int		CANVAS_BORDER = 0;                //gap between the graphics and surrounding"box"
static const int        AXIS_BORDER = 0;                  //gap between axis drawing(i.e.axis line) and its "box"
static const int        MINOR_INTERVAL = 0;               //0 stands for automatic choice in default_*_intervals array
static const int        MINOR_SEPARATION = 18;            
static const int        MAJOR_STEP = 5;
static const int        LABEL_STEP = 10;
static const int        LABEL_SIZE = CA_DEFAULT_LABEL_SIZE;
static const Fl_Font    LABEL_FONT = FL_HELVETICA;


static const int MAX_LABEL_FORMAT = 16;
static const int MAX_LABEL_LENGTH = 32;


static const int NO_LIN_DEFAULTS=3;
static const double default_lin_intervals[NO_LIN_DEFAULTS] = {1, 2, 5};
static const int default_lin_major_steps[NO_LIN_DEFAULTS] = {5, 5, 2};
static const int default_lin_label_steps[NO_LIN_DEFAULTS] = {10, 5, 4};

static const int NO_LOG_DEFAULTS = 3;
static const double default_log_intervals[NO_LOG_DEFAULTS] = {1, 2, 5};
static const int default_log_major_steps[NO_LOG_DEFAULTS] = {5, 5, 2};
static const int default_log_label_steps[NO_LOG_DEFAULTS] = {10, 5, 2};



/// float drawings for more precise placement (especialy for PS output for Fl_Device!) /////

static inline void ca_rect(double x, double y, double w, double h){
	fl_begin_loop();
	fl_vertex(x,y);
	fl_vertex(x+w,y);
	fl_vertex(x+w,y+h);
	fl_vertex(x,y+h);
	fl_end_loop();
};

static inline void ca_rectf(double x, double y, double w, double h){
	fl_begin_polygon();
	fl_vertex(x,y);
	fl_vertex(x+w,y);
	fl_vertex(x+w,y+h);
	fl_vertex(x,y+h);
	fl_end_polygon();
};

static inline void ca_loop(double x1, double y1, double x2, double y2, double x3, double y3){
	fl_begin_loop();
	fl_vertex(x1,y1); fl_vertex(x2,y2); fl_vertex(x3,y3);
	fl_end_loop();
};

static inline void ca_polygon(double x1, double y1, double x2, double y2, double x3, double y3){
	fl_begin_polygon();
	fl_vertex(x1,y1); fl_vertex(x2,y2); fl_vertex(x3,y3);
	fl_end_polygon();
};

static inline void ca_loop(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4){
	fl_begin_loop();
	fl_vertex(x1,y1); fl_vertex(x2,y2); fl_vertex(x3,y3); fl_vertex(x4,y4);
	fl_end_loop();
};

static inline void ca_polygon(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4){
	fl_begin_polygon();
	fl_vertex(x1,y1); fl_vertex(x2,y2); fl_vertex(x3,y3); fl_vertex(x4,y4);
	fl_end_polygon();
};

static inline void ca_text(const char  *label, double x, double y){
	fl_draw(label,(int)(x+.5),(int)(y+.5));
};
static inline void ca_point(double x, double y){
	fl_point((int)(x+.5),(int)(y+.5));
};

/*
static inline void ca_pie(double x, double y, double w, double h, double a1, double a2){
	fl_pie((int)(x+.5), (int)(y+.5),(int)(w+.5),(int)(h+.5),0,270.0);
};
*/

static inline void ca_filled_circle(double x, double y, double r){
	fl_begin_polygon();
	//fl_arc(x,y,r,0,360);
	fl_circle(x,y,r);
	fl_end_polygon();
};

static inline void ca_text(const char  *label, double x, double y, double w, double h, Fl_Align align){
	fl_draw(label, (int)(x+.5), (int)(y+.5), (int)(w+.5), (int)(h+.5), align);
};






////////////////////    Ca_Axis_    ////////////////////////////

void Ca_Axis_::minimum(double x){
    min_=x;
    if(!valid_){
        max_=x;
        valid_=1;
    }
    damage(CA_DAMAGE_ALL);
    canvas_->damage(CA_DAMAGE_ALL);
	update();

};

void Ca_Axis_::maximum(double x){
    max_=x;
    if(!valid_){
        min_=x;
        valid_=1;
    }
    damage(CA_DAMAGE_ALL);
    canvas_->damage(CA_DAMAGE_ALL);
	update();

};


int Ca_Axis_::update(){

    double _k=k_;
	double _q=q_;
    min_pos_=min_pos();
    max_pos_=max_pos();
    if (min_==max_)
        k_=0;
    else
		if(scale_ & CA_LOG){
			k_=(max_pos_-min_pos_)/(log(max_)-log(min_));
			q_=min_pos_-k_*log(min_);
		}else{
			k_=(max_pos_-min_pos_)/(max_-min_);
			q_=min_pos_;
		}

    if((_k!=k_)||(_q!=q_))
        return 1;
    else
        return 0;
};

void Ca_Axis_::rescale_move(int when, double  x){
    
	
    if((when&CA_WHEN_MAX)&&(x>max_)){
		if(scale_ & CA_LOG)
			min_ *=x/max_;
		else
			min_ += x-max_;
		max_=x;
        damage(CA_DAMAGE_ALL);
        canvas_->damage(CA_DAMAGE_ALL);
        
    }
    if((when&CA_WHEN_MIN)&&(x<min_)){
		if(scale_ & CA_LOG)
			max_ *=x/min_;
        else
			max_ -= min_-x;
        min_=x;
        damage(CA_DAMAGE_ALL);
        canvas_->damage(CA_DAMAGE_ALL);
    }
    valid_=1;
};

double Ca_Axis_::position(double value){

    if (k_==0) return (min_pos_+max_pos_)/2;
	if(scale_ & CA_LOG)
		return (int)(q_+k_*log(value));
	else
		return min_pos_+k_*(value-min_);
};

double Ca_Axis_::value(double pos){
    if (max_==min_)
        return min_;
	if(scale_ & CA_LOG)
		return exp(min_ +(pos-q_)/k_);
	else
		return (min_ +(pos-min_pos_)/k_);
};



int Ca_Axis_::next_tick(int &tick_index, double &tick_value, int &tick_order, double &interval ){
        

	////////// I know snakes are evil creatures, but sometimes they work so there is such a serpent....
	////////// How many if...else can be in in a function? this is going to be a record in the G. book of r.

	static int number_per_order;
    double _tick_interval;
    double minor_number_;


	if(scale_ & CA_LOG){   /////////////     begin logarithmic   /////////////////
		if (!interval){
            tick_order=(int)(floor(log10(min_)));
            if (tick_interval_!=0){
                interval=fabs(tick_interval_);
                number_per_order=(int)floor(10/interval+0.5);
            }else{
                number_per_order=(int)(abs(min_pos_-max_pos_)/(tick_separation_*log10(max_/min_)));
                if(number_per_order<=1){
                    label_step_=major_step_=3;
                    tick_order = 3*(tick_order/3);
                    interval=1;
                    number_per_order=0;
                }else{
                    int _no_per_o=number_per_order;
                    for(int i=NO_LOG_DEFAULTS-1;i>=0;i--){
                        major_step_=default_log_major_steps[i];
                        label_step_=default_log_label_steps[i];
                        interval=default_log_intervals[i];
                        number_per_order=(int)floor(10/interval+0.5);
                        if((10/interval)>=_no_per_o)
                            break;
                    }
                }
            }
            tick_index=number_per_order;
            tick_order--;
            tick_value=pow(10,tick_order);
            interval*=tick_value;
            
            if(!number_per_order){
                tick_order--;
                tick_value /=10;
                tick_index=1;
            }else
                tick_value *=10;
            return 1;
        }else{
            if (tick_value>(max_)){
                tick_index-=1;
                return 0;
            }else{
                if(number_per_order){
                    if(tick_index==number_per_order){
                        tick_order++;
                        interval*=10;
                        if(number_per_order<10){
                            tick_index=1;
                            tick_value=interval;
                        }else{
                            tick_index=2;
                            tick_value=2*interval;
                        }
                    }else{
                        tick_value +=interval;
                        tick_index++;
                    }
                }else{
                    tick_order++;
                    tick_index++;
                    tick_value *=10;
                }
                return 1;
            }
        }

	}else{     ///////////////     begin linear       //////////////////////
        if (!interval){
            minor_number_= (double)abs(min_pos_-max_pos_)/(double)tick_separation_;
            _tick_interval=tick_interval_;
            if (tick_interval_<0){
                interval=_tick_interval=-_tick_interval;
                tick_order=(int)floor(log10(_tick_interval));
            }else{
                if(_tick_interval!=0){
                    tick_order=(int)floor(log10(fabs(max_-min_)/minor_number_));
                    interval= pow(10,tick_order) * _tick_interval;
                }else
                    for(int i=NO_LIN_DEFAULTS-1;i>=0;i--){
                        tick_order=(int)floor(log10(fabs(max_-min_)/minor_number_));
                        interval= pow(10,tick_order)*(_tick_interval=default_lin_intervals[i]);
                        major_step_=default_lin_major_steps[i];
                        label_step_=default_lin_label_steps[i];
                        if(((max_-min_)/interval)>=minor_number_)
                            break;
                    }
            }
            tick_value = floor(minimum()/interval);
            tick_value *= interval;
            tick_index=(int) floor((tick_value /interval)+0.5);
            return 1;
        }else{
            if (tick_value>(max_)){
                tick_index=-1;
                return 0;
            }else{
                tick_value +=interval;
                tick_index++;
                return 1;
            }
        }
	}		/////   Uf, this is the end of the leg-less beast!   //////
};



void Ca_Axis_::rescale(int when, double  x){
    if(!valid_){
        max_=x;
        min_=x;
        damage(CA_DAMAGE_ALL);
        canvas_->damage(CA_DAMAGE_ALL);
        valid_=1;
        return;
    }

    if((when&CA_WHEN_MAX)&&(x>max_)){
        max_=x;
        damage(CA_DAMAGE_ALL);
        canvas_->damage(CA_DAMAGE_ALL);
    }
    if((when&CA_WHEN_MIN)&&(x<min_)){
        min_=x;
        damage(CA_DAMAGE_ALL);
        canvas_->damage(CA_DAMAGE_ALL);
    }
};

Ca_Axis_::Ca_Axis_(int x, int y, int w, int h, const char * label)
	:Fl_Box(x,y,w,h,label),
	scale_(CA_LIN), valid_(0), label_format_(0),
	minor_grid_color_(FL_BLACK), major_grid_color_(FL_BLACK), label_grid_color_(FL_BLACK),
	minor_grid_style_(FL_SOLID), major_grid_style_(FL_SOLID), label_grid_style_(FL_SOLID),
	minor_grid_width_(0), major_grid_width_(0), label_grid_width_(0), 
	minor_grid_dashes_(0), major_grid_dashes_(0),label_grid_dashes_(0),
	grid_visible_(0), tick_interval_(MINOR_INTERVAL), tick_separation_(MINOR_SEPARATION),
	tick_length_(0), tick_width_(0), major_step_(MAJOR_STEP),label_step_(LABEL_STEP),
	axis_align_(CA_BOTTOM),label_font_face_(FL_HELVETICA), label_font_size_(LABEL_SIZE),
	min_(0),max_(0),min_pos_(0),max_pos_(0),border_(AXIS_BORDER),axis_color_(FL_BLACK)
	
{
	box(FL_NO_BOX);
    canvas_=Ca_Canvas::current();
    previous_axis_=canvas_->last_axis_;
    canvas_->last_axis_=this;
	labelsize(LABEL_SIZE);
};

Ca_Axis_::~Ca_Axis_(){
	
	if(!canvas_)return;
    if (canvas_->last_axis_==this)
        canvas_->last_axis_=previous_axis_;
    else{
        Ca_Axis_ *axis=canvas_->last_axis_;
        while(axis){
            if(axis->previous_axis_==this){
                axis->previous_axis_=previous_axis_;
                break;
            }
			axis=axis->previous_axis_;
		}
    };
};



///////////////////////  Ca_X_Axis  ///////////////////////////////////////////////

int Ca_X_Axis::min_pos(){
	if(scale_&CA_REV)
		return canvas_->x()+canvas_->w()-canvas_->border()+Fl::box_dx(canvas_->box())-Fl::box_dw(canvas_->box());
	else
		return canvas_->x()+canvas_->border()+Fl::box_dx(canvas_->box());
};

int Ca_X_Axis::max_pos(){
	if(scale_&CA_REV)
		return canvas_->x()+canvas_->border()+Fl::box_dx(canvas_->box());
	else
		return canvas_->x()+canvas_->w()-canvas_->border()+Fl::box_dx(canvas_->box())-Fl::box_dw(canvas_->box());
		
};
		

void Ca_X_Axis::draw(){
    int tick_index=-1;
    double tick_value;
    int tick_order;//, tick_number;
    double _interval=0;
    const char * label_format=label_format_;
    if(damage()|FL_DAMAGE_ALL)
        draw_label();
    if (damage()&(FL_DAMAGE_ALL|CA_DAMAGE_ALL)){
        update();
		if (box()==FL_NO_BOX){
            fl_color(parent()->color());
            fl_rectf(x(),y(),w(),h());
        }else
			draw_box();
        if(!valid_) return;
        fl_font(label_font_face_,label_font_size_);
        int a, b, l1, l2, m1, m2, l ,_y,_w,_h; //temporary coordinates for ticks
        double _pos,_x;
        fl_clip(x()+Fl::box_dx(box()),y()+Fl::box_dy(box()),w()-Fl::box_dw(box()),h()-Fl::box_dh(box()));
		fl_color(axis_color_);
        a=y()+Fl::box_dh(box())+border_;
        b=a+h()-Fl::box_dh(box())-2*border_;
		
        switch(axis_align_ & CA_ALIGNMENT){
            case CA_BOTTOM:
                l=l1=m1=a;
				if(axis_align_&CA_NO_TICS)
					m2=m1;
				else
					if (tick_length_)
						m2=m1+tick_length_;
					else
						m2=m1+label_font_size_;
                l2=(m1+m2)/2;
                break;
            case CA_TOP:
                l=l2=m2=b-1;
				if(axis_align_&CA_NO_TICS)
					m1=m2;
				else
					if (tick_length_)
						m1=m2-tick_length_;
					else
						m1=m2-label_font_size_;
                l1=(m1+m2)/2;
                break;
            case CA_CENTER:
                m1=a;
                m2=b;
                l=(a+b)/2;
                l1=(a+l)/2;
                l2=(l+b)/2;
                break;
            default:
                m1=0;
                m2=0;
                l=0;
                l1=0;
                l2=0;
                break;
        }
		fl_line_style(FL_SOLID|FL_CAP_FLAT,tick_width_);
        if(axis_align_ & CA_LINE){
			fl_begin_line();
			fl_vertex(min_pos(),l);
			fl_vertex(max_pos(),l);
			fl_vertex(canvas_->x()+Fl::box_dx(canvas_->box()),l);
			fl_vertex(canvas_->x()+canvas_->w()+Fl::box_dx(canvas_->box())-Fl::box_dw(canvas_->box()),l);
			//fl_vertex(x()+border_,l);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -