regular_grid.cpp
来自「ncbi源码」· C++ 代码 · 共 306 行
CPP
306 行
/* * =========================================================================== * PRODUCTION $Log: regular_grid.cpp,v $ * PRODUCTION Revision 1000.3 2004/06/01 20:49:34 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.7 * PRODUCTION * =========================================================================== *//* $Id: regular_grid.cpp,v 1000.3 2004/06/01 20:49:34 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Authors: Andrey Yazhuk * * File Description: * */#include <ncbi_pch.hpp>#include <gui/graph/regular_grid.hpp>#include <math.h>BEGIN_NCBI_SCOPE#define DEF_MIN_CELL_SIZE 30#define DEF_MAX_CELL_SIZE 75const int CRegularGridGen::ms_StepK[] = { 2, 5, 10 };CRegularGridGen::CRegularGridGen(): m_MinCellSize(DEF_MIN_CELL_SIZE), m_MaxCellSize(DEF_MAX_CELL_SIZE),// m_XScaleType(eDec), m_YScaleType(eDec), m_IntegerX(false), m_IntegerY(false), m_bHorz(true), m_Start(0), m_Finish(0), m_Step(0){}CRegularGridGen::~CRegularGridGen(){}/*void CRegularGridGen::SetScaleType(EScaleType TypeX, EScaleType TypeY){ m_XScaleType = TypeX; m_YScaleType = TypeY;}*/void CRegularGridGen::SetIntegerMode(bool IntegerX, bool IntegerY) { m_IntegerX = IntegerX; m_IntegerY = IntegerY; }void CRegularGridGen::EnableOneBased(bool en_x, bool en_y){ m_OneBasedX = en_x; m_OneBasedY = en_y;}// set limitations on the CellSize in pixelsvoid CRegularGridGen::SetCellLimits(int Min, int Max){ m_MinCellSize = Min; m_MaxCellSize = Max;}void CRegularGridGen::GenerateGrid(CGlPane* pGraphPane, bool bHorz){ m_bHorz = bHorz; bool bInteger = m_bHorz ? m_IntegerX : m_IntegerY; TModelRect rcVisible = pGraphPane->GetVisibleRect(); m_Start = m_bHorz ? rcVisible.Left() : rcVisible.Bottom(); m_Finish = m_bHorz ? rcVisible.Right() : rcVisible.Top(); m_Step = 1; if(m_Finish > m_Start) { double BaseStep = SelectBaseStep(m_Start, m_Finish); double MinCell = m_bHorz ? pGraphPane->UnProjectWidth(m_MinCellSize) : pGraphPane->UnProjectHeight(m_MinCellSize); double MaxCell = m_bHorz ? pGraphPane->UnProjectWidth(m_MaxCellSize) : pGraphPane->UnProjectHeight(m_MaxCellSize); m_Step = SelectScreenStep(BaseStep, MinCell, MaxCell); if(bInteger && m_Step < 1.0) m_Step = 1.0; double BaseOrigin = ceil(m_Start / m_Step) - 1; BaseOrigin *= m_Step; if((bHorz && m_OneBasedX) || (! bHorz && m_OneBasedY)) { BaseOrigin++; } m_Start = BaseOrigin; } else { //range Start - Finish is empty, make it negtaive (not iterable) m_Finish = m_Start - 1; }}CRegularGridGen::const_iterator CRegularGridGen::begin() const{ return const_iterator(m_Start, m_Finish, m_Step);}CRegularGridGen::const_iterator CRegularGridGen::end() const{ return const_iterator();}// function calculates "sensible" step for representing labels, drawing gris etc. on graphs// minV and MaxV define range of values to be represented// it is assumed that desired number of "ticks" ( BaseStep is a difference between two neighbour ticks)// should be between 8 and 20.double CRegularGridGen::SelectBaseStep(double MinV, double MaxV ){ double Range = MaxV - MinV; double logRange = log10(Range); logRange = ceil(logRange) - 1; double Step = pow(10.0, logRange); // selcting BaseStep as step divided by 1, 2 or 5 double BaseStep = Step; double nTicks = Range / BaseStep; int i=0; while( nTicks < 8 ) { BaseStep = Step / ms_StepK[i++]; nTicks = Range / BaseStep; } return BaseStep;}void CRegularGridGen::RoundRangeToStep(double& Start, double& Finish, double Step ){ double V = Start; V = floor(V / Step) * Step; Start = V; V = Finish; V = ceil(V / Step) * Step; Finish = V;}// Scale = Pixels per Unit// return optimal step values calculated on the basis of given BaseStep, MinStep and MaxStep //(corresponding to min and max cell size in pixels respectively)double CRegularGridGen::SelectScreenStep(double BaseStep, double MinStep, double MaxStep ){ if ((BaseStep >= MinStep && BaseStep <= MaxStep) || (MinStep == MaxStep)) return BaseStep; else { // BaseStep has a form M * pow(10, P), where P is power double Power = log10(BaseStep); double P = ceil(Power) -1; double pow10P = pow(10.0, P); double M = BaseStep / pow10P; if (M >= 10) { M /= 10; pow10P *= 10; } int oldK = 1, K = 1, Index = 0; if(BaseStep < MinStep) // increasing BaseStep to make it more then minPix { double minK = MinStep / pow10P; while (K < minK) { if(Index <2) K = oldK * ms_StepK[Index++]; else { K = oldK = oldK * 10; Index = 0; } } BaseStep = pow10P * K; } else if (BaseStep > MaxStep) { // decreasing BaseStep to make it less then maxPix pow10P *= 10; double maxK = pow10P / MaxStep; while (K < maxK) { if(Index <2) K = oldK * ms_StepK[Index++]; else { K = oldK = oldK * 10; Index = 0; } } BaseStep = pow10P / K; } return BaseStep; }}CRegularGridRenderer::CRegularGridRenderer(): m_bCentering(false), m_Color(0.8f, 0.8f, 0.8f){}void CRegularGridRenderer::Render(CGlPane* pAreaPane, CGlPane* pGraphPane, CRegularGridGen* pGenerator){ // in order for CGlPane::Project() to work we need to initilize graph pane pGraphPane->OpenOrtho(); pGraphPane->Close(); pAreaPane->OpenPixels(); TVPRect rcVP = pGraphPane->GetViewport(); double vpBottom = rcVP.Bottom(); double vpTop = rcVP.Top(); double vpLeft = rcVP.Left(); double vpRight = rcVP.Right(); glColorC(m_Color); glLineWidth(1.0); glBegin(GL_LINES); double d = m_bCentering ? 0.5 : 0.0; // horizontal grid (vert. lines) pGenerator->GenerateGrid(pGraphPane, true); ITERATE(CRegularGridGen, it, *pGenerator) { double X = *it + d; int vpX = pGraphPane->ProjectX(X); if (vpX >= vpLeft && vpX <= vpRight) { glVertex2d(vpX, vpBottom); glVertex2d(vpX, vpTop); } } // vertical grid (horz. lines) pGenerator->GenerateGrid(pGraphPane, false); ITERATE(CRegularGridGen, it, *pGenerator) { double Y = *it + d; int vpY = pGraphPane->ProjectY(Y); if (vpY >= vpBottom && vpY <= vpTop) { glVertex2d(vpLeft, vpY); glVertex2d(vpRight, vpY); } } glEnd(); pAreaPane->Close();}END_NCBI_SCOPE/* * =========================================================================== * $Log: regular_grid.cpp,v $ * Revision 1000.3 2004/06/01 20:49:34 gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.7 * * Revision 1.7 2004/05/21 22:27:42 gorelenk * Added PCH ncbi_pch.hpp * * Revision 1.6 2004/03/19 14:56:43 gorelenk * Fixed compilation errors on MSVC 7.10 * * Revision 1.5 2003/11/17 20:30:05 yazhuk * Added support one-based grids and centering * * Revision 1.4 2003/08/14 17:57:45 yazhuk * Deleted CRegularGrid class * * Revision 1.3 2003/08/11 16:10:57 yazhuk * Compilation fixes for GCC * * Revision 1.2 2003/08/08 15:59:36 yazhuk * Comments added * * =========================================================================== */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?