phylo_tree_force.cpp
来自「ncbi源码」· C++ 代码 · 共 228 行
CPP
228 行
/* * =========================================================================== * PRODUCTION $Log: phylo_tree_force.cpp,v $ * PRODUCTION Revision 1000.0 2004/06/01 21:31:04 gouriano * PRODUCTION PRODUCTION: IMPORTED [GCC34_MSVC7] Dev-tree R1.4 * PRODUCTION * =========================================================================== *//* $Id: phylo_tree_force.cpp,v 1000.0 2004/06/01 21:31:04 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: Vladimir Tereshkov * * File Description: * Force tree layout */#include <ncbi_pch.hpp>#include <corelib/ncbistl.hpp>#include <gui/opengl/glhelpers.hpp>#include <gui/graph/igraph_utils.hpp>#include <gui/widgets/phylo_tree/phylo_tree_render.hpp>#include <gui/widgets/phylo_tree/phylo_tree_force.hpp>#include <FL/Fl.H>#include <math.h>BEGIN_NCBI_SCOPECPhyloForce::CPhyloForce(){ // default values m_SpringLength = 40; m_Stiffness = 100; m_ElectricalRepulsion = 100; m_Increment = 0.1; m_Initialized = false;}CPhyloForce::~CPhyloForce(){}void CPhyloForce::x_Layout(CPhyloTreeDataSource& ds){ bool distMode = m_bDistMode; m_bDistMode = false; CPhyloRadial::x_Layout(ds); m_bDistMode = distMode; m_Hash = ds.GetHash(); Int4 leafs = ds.GetSize(); Int4 width = ds.GetWidth(); m_xStep = (m_DimX - m_LeftMargin - m_RightMargin) / width; m_yStep = (m_DimY - m_TopMargin - m_BottomMargin) / (leafs-1); m_Radius = sqrt(m_xStep*m_xStep + m_yStep*m_yStep)/2; m_StartDegree = 0.0; m_ParentDegree = 0.0; if (ds.GetNormDistance() > 0){ m_NormDistance = m_ElectricalRepulsion / ds.GetNormDistance(); } for (int i=0; i<100; i++) x_Calculate(ds.GetTree()); // changing raster - x_Calculate for sure changed size in unpredictable way TModelRect newRect = ds.GetBoundRect(); m_RasterRect.Init(newRect.Left() - m_RightMargin, newRect.Top() - m_TopMargin, newRect.Right() + m_RightMargin, newRect.Bottom() + m_BottomMargin); }void CPhyloForce::x_Render(CGlPane& pane, CPhyloTreeDataSource& ds){ pane.OpenOrtho(); x_DrawTree( ds.GetTree() ); pane.Close(); }void CPhyloForce:: x_Calculate(CPhyloTreeNode * node){ double xForce = 0; double yForce = 0; double distance; double xSpring = 0; double ySpring = 0; double xRepulsion = 0; double yRepulsion = 0; double adjX; double adjY; double thisX = node->XY().first; double thisY = node->XY().second; // two forces calculating at a same time for (CPhyloTreeDataSource::TNodeHash::iterator vx=m_Hash.begin(); vx!=m_Hash.end(); vx++){ CPhyloTreeNode * vertex = vx->second; // skip itself if (vertex == node) continue; adjX = vertex->XY().first; adjY = vertex->XY().second; // repulsion forces calculation distance = sqrt((adjX - thisX)*(adjX - thisX) + (adjY - thisY)*(adjY - thisY)); if( distance == 0 ) distance = 0.0001; // if (m_bDistMode){ // m_ElectricalRepulsion = vertex->GetDistance() * m_NormDistance; //} xRepulsion += ( m_ElectricalRepulsion / distance ) * (( thisX - adjX ) / ( distance )); yRepulsion += ( m_ElectricalRepulsion / distance ) * (( thisY - adjY ) / ( distance )); // if vertex is adjucent, calculate spring force if ((vertex->GetParent() && (vertex->GetParent()->GetValue()==node)) || (node->GetParent() && (node->GetParent()->GetValue()==vertex))){ xSpring += m_Stiffness * log( distance / m_SpringLength ) * (( thisX - adjX ) / ( distance )); ySpring += m_Stiffness * log( distance / m_SpringLength ) * (( thisY - adjY ) / ( distance )); } } // resulting force xForce = -xSpring + xRepulsion; yForce = -ySpring + yRepulsion; // altering positions node->XY().first += ( xForce * m_Increment ); node->XY().second += ( yForce * m_Increment ); if (!node->IsLeaf()) { for(CPhyloTreeNode::TNodeList_I it = node->SubNodeBegin(); it != node->SubNodeEnd(); it++ ) { x_Calculate((*it)->GetValue()); } } }void CPhyloForce :: x_DrawTree(CPhyloTreeNode * node){ // label if (m_pLabelFont && node->IsLeaf()){ CGlPoint<int> labelPos(node->GetValue()->XY().first, node->GetValue()->XY().second); m_Label.Render(*m_pPane, labelPos, node->GetLabel(), node->GetSelected(), (node->GetAngle() < -1.57 || node->GetAngle()>1.57)); } // drawing leaf node if (node->GetParent()){ x_RenderLine(node->GetParent()->GetValue()->XY().first + m_LineWidth, node->GetParent()->GetValue()->XY().second, node->GetValue()->XY().first, node->GetValue()->XY().second, m_LineWidth, node->GetSelected()?m_LineSelColor:m_LineColor, node->GetSelected()?m_LineSelHiColor:m_LineHiColor); } for(CPhyloTreeNode::TNodeList_I it = node->SubNodeBegin(); it != node->SubNodeEnd(); it++ ) x_DrawTree((*it)->GetValue()); x_RenderNode(node->GetValue()->XY().first, node->GetValue()->XY().second, m_NodeSize, node->GetSelected()?m_NodeSelColor:m_NodeColor);} void CPhyloForce :: x_CountLeafs(CPhyloTreeNode * node, Int4 & lfCount){ if (node->IsLeaf()) lfCount++; for (CPhyloTreeNode::TNodeList_I it = node->SubNodeBegin(); it != node->SubNodeEnd(); it++) x_CountLeafs((*it)->GetValue(), lfCount); }string CPhyloForce::GetDescription(void){ return "Force Layout";}END_NCBI_SCOPE/* * =========================================================================== * $Log: phylo_tree_force.cpp,v $ * Revision 1000.0 2004/06/01 21:31:04 gouriano * PRODUCTION: IMPORTED [GCC34_MSVC7] Dev-tree R1.4 * * Revision 1.4 2004/05/21 22:27:54 gorelenk * Added PCH ncbi_pch.hpp * * Revision 1.3 2004/05/20 15:30:49 tereshko * Typo fixed * * Revision 1.2 2004/05/11 20:53:12 tereshko * Work in progress * * Revision 1.1 2004/05/06 19:41:48 tereshko * Initial revision * * =========================================================================== */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?