//--------------------------------------------------------- int CSG_Network::_Add_Node(CSG_PRQuadTree &Search, int Edge_ID, const TSG_Point &Node_Point, const TSG_Point &Dir_Point) { int Node_ID; double Distance; CSG_PRQuadTree_Leaf *pLeaf = Search.Get_Nearest_Leaf(Node_Point, Distance); if( !pLeaf || Distance > 0.0 )//00001 ) { Node_ID = Get_Node_Count(); m_Nodes.Inc_Array(); ((CSG_Network_Node **)m_Nodes.Get_Array())[Node_ID] = new CSG_Network_Node(Node_ID, Node_Point); Search.Add_Point(Node_Point.x, Node_Point.y, Node_ID); } else { Node_ID = (int)pLeaf->Get_Z(); } Get_Node(Node_ID).Add_Edge(Edge_ID, SG_Get_Angle_Of_Direction(Node_Point, Dir_Point)); return( Node_ID ); }
bool CSG_PRQuadTree::Get_Nearest_Point(double x, double y, TSG_Point &Point, double &Value, double &Distance) const { CSG_PRQuadTree_Leaf *pLeaf = _Get_Nearest_Point(m_pRoot, x, y, Distance = -1); if( pLeaf ) { Point.x = pLeaf->Get_X(); Point.y = pLeaf->Get_Y(); Value = pLeaf->Get_Z(); return( true ); } return( false ); }
//--------------------------------------------------------- size_t CSG_PRQuadTree::Get_Nearest_Points(CSG_Points_Z &Points, double x, double y, size_t maxPoints, double Radius, int iQuadrant) const { CSG_Array Selection; _Select_Nearest_Points(Selection, x, y, maxPoints, Radius, iQuadrant); Points.Clear(); for(size_t i=0; i<Selection.Get_Size(); i++) { CSG_PRQuadTree_Leaf *pLeaf = _Get_Selected(Selection, i)->pLeaf; Points.Add(pLeaf->Get_X(), pLeaf->Get_Y(), pLeaf->Get_Z()); } return( Points.Get_Count() ); }
//--------------------------------------------------------- bool CPoints_Filter::Do_Filter(TSG_Point Point, double zPoint, int Quadrant) { if( !m_Search.Select_Nearest_Points(Point.x, Point.y, m_nMaxPoints, m_Radius, Quadrant) ) { return( false ); } if( m_Search.Get_Selected_Count() <= m_nMinPoints ) { return( true ); } switch( m_Method ) { //----------------------------------------------------- case 0: // keep maxima case 1: // keep minima case 2: // remove maxima case 3: // remove minima { for(int i=0; i<m_Search.Get_Selected_Count(); i++) { CSG_PRQuadTree_Leaf *pLeaf = m_Search.Get_Selected_Leaf(i); if( pLeaf ) { double z; if( pLeaf->has_Statistics() ) { switch( m_Method ) { case 0: z = ((CSG_PRQuadTree_Leaf_List *)pLeaf)->Get_Maximum(); break; // keep maxima case 1: z = ((CSG_PRQuadTree_Leaf_List *)pLeaf)->Get_Minimum(); break; // keep minima case 2: z = ((CSG_PRQuadTree_Leaf_List *)pLeaf)->Get_Maximum(); break; // remove maxima case 3: z = ((CSG_PRQuadTree_Leaf_List *)pLeaf)->Get_Minimum(); break; // remove minima } } else { z = pLeaf->Get_Z(); } switch( m_Method ) { case 0: if( zPoint < (z - m_Tolerance) ) return( true ); break; // keep maxima case 1: if( zPoint > (z + m_Tolerance) ) return( true ); break; // keep minima case 2: if( zPoint < (z - m_Tolerance) ) return( false ); break; // remove maxima case 3: if( zPoint > (z + m_Tolerance) ) return( false ); break; // remove minima } } } return( m_Method <= 1 ? false : true ); } //----------------------------------------------------- case 4: // remove below percentile case 5: // remove above percentile { double n = 0.0; for(int i=0; i<m_Search.Get_Selected_Count(); i++) { CSG_PRQuadTree_Leaf *pLeaf = m_Search.Get_Selected_Leaf(i); if( pLeaf ) { if( pLeaf->has_Statistics() ) { for(int j=0; j<((CSG_PRQuadTree_Leaf_List *)pLeaf)->Get_Count(); j++) { if( zPoint > ((CSG_PRQuadTree_Leaf_List *)pLeaf)->Get_Value(j) ) { n++; } } } else if( zPoint > pLeaf->Get_Z() ) { n++; } } } n *= 100.0 / m_Search.Get_Selected_Count(); return( m_Method == 4 ? n < m_Percentile : n > m_Percentile ); } } //----------------------------------------------------- return( false ); }
//--------------------------------------------------------- void CSG_PRQuadTree::_Select_Nearest_Points(CSG_Array &Selection, CSG_PRQuadTree_Item *pItem, double x, double y, double &Distance, double Radius, size_t maxPoints, int iQuadrant) const { //----------------------------------------------------- if( pItem->is_Leaf() ) { CSG_PRQuadTree_Leaf *pLeaf = (CSG_PRQuadTree_Leaf *)pItem; if( _Quadrant_Contains(x, y, iQuadrant, pLeaf->Get_Point()) == false ) { return; } double d = SG_Get_Distance(x, y, pLeaf->Get_X(), pLeaf->Get_Y(), m_bPolar); if( Radius > 0.0 && Radius < d ) { return; } //------------------------------------------------- if( Selection.Get_Size() < maxPoints ) { if( Distance < d ) { Distance = d; } _Add_Selected(Selection, pLeaf, d); } else if( d < Distance ) { size_t i; for(i=0; i<Selection.Get_Size(); i++) { if( Distance <= _Get_Selected(Selection, i)->Distance ) { _Set_Selected(Selection, i, pLeaf, d); break; } } for(i=0, Distance=d; i<maxPoints; i++) { if( Distance < _Get_Selected(Selection, i)->Distance ) { Distance = _Get_Selected(Selection, i)->Distance; } } } } //----------------------------------------------------- else // if( pItem->is_Node() ) { int i; CSG_PRQuadTree_Item *pChild; for(i=0; i<4; i++) { if( (pChild = ((CSG_PRQuadTree_Node *)pItem)->Get_Child(i)) != NULL && pChild->Contains(x, y) == true ) { _Select_Nearest_Points(Selection, pChild, x, y, Distance, Radius, maxPoints, iQuadrant); } } for(i=0; i<4; i++) { if( (pChild = ((CSG_PRQuadTree_Node *)pItem)->Get_Child(i)) != NULL && pChild->Contains(x, y) == false ) { if( _Radius_Intersects(x, y, Radius, iQuadrant, pChild) ) { if( Get_Selected_Count() < maxPoints || ( Distance > (x < pChild->Get_xCenter() ? pChild->Get_xMin() - x : x - pChild->Get_xMax()) && Distance > (y < pChild->Get_yCenter() ? pChild->Get_yMin() - y : y - pChild->Get_yMax()) ) ) { _Select_Nearest_Points(Selection, pChild, x, y, Distance, Radius, maxPoints, iQuadrant); } } } } } }
//--------------------------------------------------------- bool CSG_PRQuadTree_Node::Add_Point(double x, double y, double z) { if( Contains(x, y) ) { if( has_Statistics() ) { Get_X()->Add_Value(x); Get_Y()->Add_Value(y); Get_Z()->Add_Value(z); } int i = y < m_yCenter ? (x < m_xCenter ? 0 : 3) : (x < m_xCenter ? 1 : 2); //------------------------------------------------- if( m_pChildren[i] == NULL ) { double Size = 0.5 * m_Size; switch( i ) { case 0: m_pChildren[i] = new CSG_PRQuadTree_Leaf(m_xCenter - Size, m_yCenter - Size, Size, x, y, z); break; case 1: m_pChildren[i] = new CSG_PRQuadTree_Leaf(m_xCenter - Size, m_yCenter + Size, Size, x, y, z); break; case 2: m_pChildren[i] = new CSG_PRQuadTree_Leaf(m_xCenter + Size, m_yCenter + Size, Size, x, y, z); break; case 3: m_pChildren[i] = new CSG_PRQuadTree_Leaf(m_xCenter + Size, m_yCenter - Size, Size, x, y, z); break; } return( true ); } //----------------------------------------------------- if( m_pChildren[i]->is_Leaf() ) { CSG_PRQuadTree_Leaf *pLeaf = m_pChildren[i]->asLeaf(); if( x != pLeaf->Get_X() || y != pLeaf->Get_Y() ) { if( has_Statistics() ) { m_pChildren[i] = new CSG_PRQuadTree_Node_Statistics (pLeaf); } else { m_pChildren[i] = new CSG_PRQuadTree_Node (pLeaf); } ((CSG_PRQuadTree_Node *)m_pChildren[i])->Add_Point(x, y, z); } else { if( !pLeaf->has_Statistics() ) { m_pChildren[i] = new CSG_PRQuadTree_Leaf_List(pLeaf->m_xCenter, pLeaf->m_yCenter, pLeaf->m_Size, x, y, pLeaf->Get_Z()); delete(pLeaf); } ((CSG_PRQuadTree_Leaf_List *)m_pChildren[i])->Add_Value(z); } return( true ); } //------------------------------------------------- // if( m_pChildren[i]->is_Node() ) { return( ((CSG_PRQuadTree_Node *)m_pChildren[i])->Add_Point(x, y, z) ); } } return( false ); }