//--------------------------------------------------------- bool SG_Get_Triangle_CircumCircle(TSG_Point Triangle[3], TSG_Point &Point, double &Radius) { TSG_Point AB, AC, AB_M, AC_M, AB_N, AC_N; AB.x = B.x - A.x; AB.y = B.y - A.y; AB_M.x = A.x + AB.x / 2.0; AB_M.y = A.y + AB.y / 2.0; AB_N.x = AB_M.x - AB.y; AB_N.y = AB_M.y + AB.x; AC.x = C.x - A.x; AC.y = C.y - A.y; AC_M.x = A.x + AC.x / 2.0; AC_M.y = A.y + AC.y / 2.0; AC_N.x = AC_M.x - AC.y; AC_N.y = AC_M.y + AC.x; if( SG_Get_Crossing(Point, AB_M, AB_N, AC_M, AC_N, false) ) { AB.x = A.x - Point.x; AB.y = A.y - Point.y; Radius = sqrt(AB.x*AB.x + AB.y*AB.y); return( true ); } return( false ); }
//--------------------------------------------------------- bool SG_Get_Crossing_InRegion(TSG_Point &Crossing, const TSG_Point &a, const TSG_Point &b, const TSG_Rect &Region) { TSG_Point ra, rb; //----------------------------------------------------- ra.y = Region.yMin; rb.y = Region.yMax; ra.x = rb.x = Region.xMin; if( SG_Get_Crossing(Crossing, a, b, ra, rb, true) ) { return( true ); } //----------------------------------------------------- ra.x = rb.x = Region.xMax; if( SG_Get_Crossing(Crossing, a, b, ra, rb, true) ) { return( true ); } //----------------------------------------------------- ra.x = Region.xMin; ra.y = Region.yMax; if( SG_Get_Crossing(Crossing, a, b, ra, rb, true) ) { return( true ); } //----------------------------------------------------- ra.y = rb.y = Region.yMin; if( SG_Get_Crossing(Crossing, a, b, ra, rb, true) ) { return( true ); } //----------------------------------------------------- return( false ); }
//--------------------------------------------------------- double SG_Get_Nearest_Point_On_Line(const TSG_Point &Point, const TSG_Point &Ln_A, const TSG_Point &Ln_B, TSG_Point &Ln_Point, bool bExactMatch) { double dx, dy, Distance, d; TSG_Point Point_B; Point_B.x = Point.x - (Ln_B.y - Ln_A.y); Point_B.y = Point.y + (Ln_B.x - Ln_A.x); if( SG_Get_Crossing(Ln_Point, Ln_A, Ln_B, Point, Point_B, false) ) { if( !bExactMatch || (bExactMatch && SG_IS_BETWEEN(Ln_A.x, Ln_Point.x, Ln_B.x) && SG_IS_BETWEEN(Ln_A.y, Ln_Point.y, Ln_B.y)) ) { dx = Point.x - Ln_Point.x; dy = Point.y - Ln_Point.y; Distance = sqrt(dx*dx + dy*dy); } else { dx = Point.x - Ln_A.x; dy = Point.y - Ln_A.y; d = sqrt(dx*dx + dy*dy); dx = Point.x - Ln_B.x; dy = Point.y - Ln_B.y; Distance = sqrt(dx*dx + dy*dy); if( d < Distance ) { Distance = d; Ln_Point = Ln_A; } else { Ln_Point = Ln_B; } } return( Distance ); } return( -1.0 ); }
//--------------------------------------------------------- TSG_Point CPolygon_Clip::Get_Crossing(CSG_Shape_Polygon *pPolygon, const TSG_Point &a, const TSG_Point &b) { TSG_Point c = a; for(int iPart=0; iPart<pPolygon->Get_Part_Count(); iPart++) { TSG_Point A, B; B = pPolygon->Get_Point(pPolygon->Get_Point_Count(iPart) - 1, iPart); for(int iPoint=0; iPoint<pPolygon->Get_Point_Count(iPart); iPoint++) { A = B; B = pPolygon->Get_Point(iPoint, iPart); if( SG_Get_Crossing(c, A, B, a, b) ) { return( c ); } } } return( c ); }
//--------------------------------------------------------- void CShapes2Grid::Set_Polygon(CSG_Shape *pShape) { bool bFill, *bCrossing; int x, y, xStart, xStop; TSG_Point A, B, a, b, c; CSG_Rect Extent; //----------------------------------------------------- bCrossing = (bool *)SG_Malloc(m_pGrid->Get_NX() * sizeof(bool)); Extent = pShape->Get_Extent(); xStart = (int)((Extent.m_rect.xMin - m_pGrid->Get_XMin()) / m_pGrid->Get_Cellsize()) - 1; if( xStart < 0 ) xStart = 0; xStop = (int)((Extent.m_rect.xMax - m_pGrid->Get_XMin()) / m_pGrid->Get_Cellsize()) + 1; if( xStop >= m_pGrid->Get_NX() ) xStop = m_pGrid->Get_NX() - 1; A.x = m_pGrid->Get_XMin() - 1.0; B.x = m_pGrid->Get_XMax() + 1.0; //----------------------------------------------------- for(y=0, A.y=m_pGrid->Get_YMin(); y<m_pGrid->Get_NY(); y++, A.y+=m_pGrid->Get_Cellsize()) { if( A.y >= Extent.m_rect.yMin && A.y <= Extent.m_rect.yMax ) { B.y = A.y; memset(bCrossing, 0, m_pGrid->Get_NX() * sizeof(bool)); for(int iPart=0; iPart<pShape->Get_Part_Count(); iPart++) { b = pShape->Get_Point(pShape->Get_Point_Count(iPart) - 1, iPart); for(int iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++) { a = b; b = pShape->Get_Point(iPoint, iPart); if( ((a.y <= A.y && A.y < b.y) || (a.y > A.y && A.y >= b.y)) ) { SG_Get_Crossing(c, a, b, A, B, false); x = (int)(1.0 + X_WORLD_TO_GRID(c.x)); if( x < 0 ) { x = 0; } else if( x >= m_pGrid->Get_NX() ) { x = m_pGrid->Get_NX() - 1; } bCrossing[x] = !bCrossing[x]; } } } //--------------------------------------------- for(x=xStart, bFill=false; x<=xStop; x++) { if( bCrossing[x] ) { bFill = !bFill; } if( bFill ) { Set_Value(x, y); } } } } //----------------------------------------------------- SG_Free(bCrossing); }
//--------------------------------------------------------- bool CGCS_Graticule::Get_Coordinate(const CSG_Rect &Extent, CSG_Shapes *pCoordinates, CSG_Shape *pLine, int Axis) { if( !pCoordinates || !Extent.Intersects(pLine->Get_Extent()) || pLine->Get_Point_Count(0) < 2 ) { return( false ); } TSG_Point A[2], B[2], C; switch( Axis ) { case AXIS_LEFT : A[0].x = A[1].x = Extent.Get_XMin(); A[0].y = Extent.Get_YMin(); A[1].y = Extent.Get_YMax(); break; case AXIS_RIGHT : A[0].x = A[1].x = Extent.Get_XMax(); A[0].y = Extent.Get_YMin(); A[1].y = Extent.Get_YMax(); break; case AXIS_BOTTOM: A[0].y = A[1].y = Extent.Get_YMin(); A[0].x = Extent.Get_XMin(); A[1].x = Extent.Get_XMax(); break; case AXIS_TOP : A[0].y = A[1].y = Extent.Get_YMax(); A[0].x = Extent.Get_XMin(); A[1].x = Extent.Get_XMax(); break; default: return( false ); } //----------------------------------------------------- B[1] = pLine->Get_Point(0); for(int i=1; i<pLine->Get_Point_Count(); i++) { B[0] = B[1]; B[1] = pLine->Get_Point(i); if( SG_Get_Crossing(C, A[0], A[1], B[0], B[1], true) ) { CSG_Shape *pPoint = pCoordinates->Add_Shape(); pPoint->Add_Point(C); pPoint->Set_Value(0, CSG_String(pLine->asString(0)) + (Axis == AXIS_LEFT || Axis == AXIS_BOTTOM ? "_MIN" : "_MAX")); pPoint->Set_Value(1, pLine->asString(1)); return( true ); } } //----------------------------------------------------- switch( Axis ) { case AXIS_LEFT : C = pLine->Get_Point(0, 0, true ); break; case AXIS_RIGHT : C = pLine->Get_Point(0, 0, false); break; case AXIS_BOTTOM: C = pLine->Get_Point(0, 0, true ); break; case AXIS_TOP : C = pLine->Get_Point(0, 0, false); break; } if( Extent.Contains(C) ) { CSG_Shape *pPoint = pCoordinates->Add_Shape(); pPoint->Add_Point(C); pPoint->Set_Value(0, CSG_String(pLine->asString(0)) + (Axis == AXIS_LEFT || Axis == AXIS_BOTTOM ? "_MIN" : "_MAX")); pPoint->Set_Value(1, pLine->asString(1)); return( true ); } //----------------------------------------------------- return( false ); }
//--------------------------------------------------------- bool CLine_Crossings::On_Execute(void) { CSG_Shapes *pLines_A = Parameters("LINES_A" )->asShapes(); CSG_Shapes *pLines_B = Parameters("LINES_B" )->asShapes(); CSG_Shapes *pCrossings = Parameters("CROSSINGS")->asShapes(); if( !pLines_A->is_Valid() || !pLines_B->is_Valid() || pLines_A->Get_Extent().Intersects(pLines_B->Get_Extent()) == INTERSECTION_None ) { Error_Set(_TL("no intersection")); return( false ); } //-------------------------------------------------------- int Attributes = Parameters("ATTRIBUTES")->asInt(); pCrossings->Create(SHAPE_TYPE_Point, CSG_String::Format("%s [%s - %s]", _TL("Crossings"), pLines_A->Get_Name(), pLines_B->Get_Name())); if( Attributes == 0 || Attributes == 2 ) { pCrossings->Add_Field("ID_A", SG_DATATYPE_Int); pCrossings->Add_Field("ID_B", SG_DATATYPE_Int); } if( Attributes == 1 || Attributes == 2 ) { Add_Attributes(pCrossings, pLines_A); Add_Attributes(pCrossings, pLines_B); } //-------------------------------------------------------- for(int aLine=0, iPair=0, nPairs=pLines_A->Get_Count()*pLines_B->Get_Count() && Process_Get_Okay(); aLine<pLines_A->Get_Count(); aLine++) { CSG_Shape_Line *pA = (CSG_Shape_Line *)pLines_A->Get_Shape(aLine); for(int bLine=0; bLine<pLines_B->Get_Count() && Set_Progress(iPair++, nPairs); bLine++) { CSG_Shape_Line *pB = (CSG_Shape_Line *)pLines_B->Get_Shape(bLine); if( pA->Intersects(pB) ) { for(int aPart=0; aPart<pA->Get_Part_Count(); aPart++) { TSG_Point A[2]; A[1] = pA->Get_Point(0, aPart); for(int aPoint=1; aPoint<pA->Get_Point_Count(aPart); aPoint++) { A[0] = A[1]; A[1] = pA->Get_Point(aPoint, aPart); for(int bPart=0; bPart<pB->Get_Part_Count(); bPart++) { TSG_Point B[2], C; B[1] = pB->Get_Point(0, bPart); for(int bPoint=1; bPoint<pB->Get_Point_Count(bPart); bPoint++) { B[0] = B[1]; B[1] = pB->Get_Point(bPoint, bPart); if( SG_Get_Crossing(C, A[0], A[1], B[0], B[1]) ) { Set_Crossing(C, pA, pB, pCrossings->Add_Shape(), Attributes); } } } } } } } } //-------------------------------------------------------- return( pCrossings->Get_Count() > 0 ); }
/////////////////////////////////////////////////////////// //--------------------------------------------------------- // This function has been copied from Module: 'Grid_Statistics_AddTo_Polygon' // Function: Get_ShapeIDs(...) // copyright by Olaf Conrad // // added support to clip only with selected polygons (Volker Wichmann) //--------------------------------------------------------- bool CGrid_Polygon_Clip::Get_Mask(CSG_Shapes *pShapes, CSG_Grid *pMask) { bool bFill, *bCrossing; bool bOnlySelected = false; int x, y, ix, xStart, xStop, iShape, iPart, iPoint; double yPos; TSG_Point pLeft, pRight, pa, pb, p; TSG_Rect Extent; CSG_Shape *pShape; //----------------------------------------------------- pMask->Assign(MASK_OFF); bCrossing = (bool *)SG_Malloc(pMask->Get_NX() * sizeof(bool)); if (pShapes->Get_Selection_Count() > 0) bOnlySelected = true; //----------------------------------------------------- for(iShape=0; iShape<pShapes->Get_Count() && Set_Progress(iShape, pShapes->Get_Count()); iShape++) { if (bOnlySelected && !pShapes->Get_Shape(iShape)->is_Selected()) continue; pShape = pShapes->Get_Shape(iShape); Extent = pShape->Get_Extent().m_rect; xStart = Get_System()->Get_xWorld_to_Grid(Extent.xMin) - 1; if( xStart < 0 ) xStart = 0; xStop = Get_System()->Get_xWorld_to_Grid(Extent.xMax) + 1; if( xStop >= Get_NX() ) xStop = Get_NX() - 1; pLeft.x = pMask->Get_XMin() - 1.0; pRight.x = pMask->Get_XMax() + 1.0; //------------------------------------------------- for(y=0, yPos=pMask->Get_YMin(); y<pMask->Get_NY(); y++, yPos+=pMask->Get_Cellsize()) { if( yPos >= Extent.yMin && yPos <= Extent.yMax ) { memset(bCrossing, 0, pMask->Get_NX() * sizeof(bool)); pLeft.y = pRight.y = yPos; //----------------------------------------- for(iPart=0; iPart<pShape->Get_Part_Count(); iPart++) { pb = pShape->Get_Point(pShape->Get_Point_Count(iPart) - 1, iPart); for(iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++) { pa = pb; pb = pShape->Get_Point(iPoint, iPart); if( ( (pa.y <= yPos && yPos < pb.y) || (pa.y > yPos && yPos >= pb.y) ) ) { SG_Get_Crossing(p, pa, pb, pLeft, pRight, false); ix = (int)((p.x - pMask->Get_XMin()) / pMask->Get_Cellsize() + 1.0); if( ix < 0) { ix = 0; } else if( ix >= pMask->Get_NX() ) { continue; } bCrossing[ix] = !bCrossing[ix]; } } } //----------------------------------------- for(x=xStart, bFill=false; x<=xStop; x++) { if( bCrossing[x] ) { bFill = !bFill; } if( bFill ) { pMask->Set_Value(x, y, MASK_ON); } } } } } //----------------------------------------------------- SG_Free(bCrossing); return( true ); }
//--------------------------------------------------------- bool CSG_Network::_Add_Line(CSG_Shape *pLine, int ID) { int iEdge, iPoint, iCrossing; CSG_Shape *pEdge, *pCrossing; CSG_Shapes Crossings(SHAPE_TYPE_Point); //----------------------------------------------------- // 1. find crossings Crossings.Add_Field(SG_T("LINE_POINT") , SG_DATATYPE_Int); Crossings.Add_Field(SG_T("EDGE_ID") , SG_DATATYPE_Int); Crossings.Add_Field(SG_T("EDGE_POINT") , SG_DATATYPE_Int); Crossings.Add_Field(SG_T("EDGE_DIST") , SG_DATATYPE_Double); for(iEdge=0; iEdge<m_Edges.Get_Count(); iEdge++) { pEdge = m_Edges.Get_Shape(iEdge); if( pEdge->Intersects(pLine) ) { TSG_Point a = pEdge->Get_Point(0); for(int iEdge_Point=1; iEdge_Point<pEdge->Get_Point_Count(0); iEdge_Point++) { TSG_Point b = a; a = pEdge->Get_Point(iEdge_Point); TSG_Point A = pLine->Get_Point(0); for(iPoint=1; iPoint<pLine->Get_Point_Count(0); iPoint++) { TSG_Point C, B = A; A = pLine->Get_Point(iPoint); if( SG_Get_Crossing(C, A, B, a, b) ) { pCrossing = Crossings.Add_Shape(); pCrossing->Add_Point(C); pCrossing->Set_Value(0, iPoint); pCrossing->Set_Value(1, iEdge); pCrossing->Set_Value(2, iEdge_Point); pCrossing->Set_Value(3, SG_Get_Distance(C, b)); } } } } } //----------------------------------------------------- // 2. add new line's vertices Crossings.Set_Index(0, TABLE_INDEX_Ascending); pEdge = m_Edges.Add_Shape(); pEdge ->Set_Value(3, ID); for(iCrossing=0, iPoint=0; iCrossing<Crossings.Get_Count(); iCrossing++) { pCrossing = Crossings.Get_Shape_byIndex(iCrossing); while( iPoint < pCrossing->asInt(0) ) { pEdge->Add_Point(pLine->Get_Point(iPoint++)); } pEdge->Add_Point(pCrossing->Get_Point(0)); pEdge = m_Edges.Add_Shape(); pEdge ->Set_Value(3, ID); pEdge ->Add_Point(pCrossing->Get_Point(0)); } while( iPoint < pLine->Get_Point_Count(0) ) { pEdge->Add_Point(pLine->Get_Point(iPoint++)); } //----------------------------------------------------- // 3. split edges, if necessary Crossings.Set_Index(1, TABLE_INDEX_Descending, 2, TABLE_INDEX_Ascending, 3, TABLE_INDEX_Ascending); for(iCrossing=0; iCrossing<Crossings.Get_Count(); ) { pCrossing = Crossings.Get_Shape_byIndex(iCrossing); iEdge = pCrossing->asInt(1); pLine = m_Edges.Get_Shape(iEdge); ID = pLine->asInt(0); iPoint = 0; pEdge = m_Edges.Add_Shape(); pEdge ->Set_Value(3, pLine->asInt(3)); while( 1 ) { while( iPoint < pCrossing->asInt(2) ) { pEdge->Add_Point(pLine->Get_Point(iPoint++)); } pEdge->Add_Point(pCrossing->Get_Point(0)); if( ++iCrossing < Crossings.Get_Count() && iEdge == Crossings.Get_Shape_byIndex(iCrossing)->asInt(1) ) { pEdge = m_Edges.Add_Shape(); pEdge ->Set_Value(3, pLine->asInt(3)); pEdge->Add_Point(pCrossing->Get_Point(0)); pCrossing = Crossings.Get_Shape_byIndex(iCrossing); } else { if( iPoint < pLine->Get_Point_Count() ) { pEdge = m_Edges.Add_Shape(); pEdge ->Set_Value(3, pLine->asInt(3)); pEdge->Add_Point(pCrossing->Get_Point(0)); while( iPoint < pLine->Get_Point_Count() ) { pEdge->Add_Point(pLine->Get_Point(iPoint++)); } } break; } } m_Edges.Del_Shape(iEdge); } return( true ); }
//--------------------------------------------------------- bool SG_Get_Crossing_InRegion(TSG_Point &Crossing, const TSG_Point &_a, const TSG_Point &_b, const TSG_Rect &Region) { bool bResult; TSG_Point a, b, pExt_XY, pExt_X, pExt_Y; CSG_Rect r(Region); a = _a; b = _b; //----------------------------------------------------- if( !r.Contains(a) && r.Contains(b) ) { pExt_X = a; a = b; b = pExt_X; bResult = true; } else if( r.Contains(a) && !r.Contains(b) ) { bResult = true; } else { bResult = false; } //----------------------------------------------------- if( bResult ) { if( a.x > b.x ) { pExt_XY.x = Region.xMin; pExt_X.x = Region.xMin; pExt_Y.x = Region.xMax; } else { pExt_XY.x = Region.xMax; pExt_X.x = Region.xMax; pExt_Y.x = Region.xMin; } if( a.y > b.y ) { pExt_XY.y = Region.yMin; pExt_Y.y = Region.yMin; pExt_X.y = Region.yMax; } else { pExt_XY.y = Region.yMax; pExt_Y.y = Region.yMax; pExt_X.y = Region.yMin; } //------------------------------------------------- if( !SG_Get_Crossing(Crossing, a, b, pExt_X, pExt_XY) ) { if( !SG_Get_Crossing(Crossing, a, b, pExt_Y, pExt_XY) ) { bResult = false; } } } return( bResult ); }
//--------------------------------------------------------- TSG_Intersection CSG_Shape_Line::On_Intersects(CSG_Shape *pShape) { //----------------------------------------------------- if( pShape->Get_Type() == SHAPE_TYPE_Point || pShape->Get_Type() == SHAPE_TYPE_Points ) { bool bIn = false; bool bOut = false; for(int iPart=0; iPart<m_nParts; iPart++) { for(int jPart=0; jPart<pShape->Get_Part_Count(); jPart++) { for(int jPoint=1; jPoint<pShape->Get_Point_Count(jPart); jPoint++) { TSG_Point Point; if( Get_Distance(pShape->Get_Point(jPoint, jPart), Point, iPart) == 0.0 ) { bIn = true; } else { bOut = true; } if( bIn && bOut ) { return( INTERSECTION_Overlaps ); } } } } if( bIn ) { return( INTERSECTION_Contained ); } } //----------------------------------------------------- else if( pShape->Get_Type() == SHAPE_TYPE_Line ) { TSG_Point iA, iB, jA, jB, Crossing; for(int iPart=0; iPart<m_nParts; iPart++) { if( Get_Point_Count(iPart) > 1 ) { iA = Get_Point(0, iPart); for(int iPoint=1; iPoint<Get_Point_Count(iPart); iPoint++) { iB = iA; iA = Get_Point(iPoint, iPart); for(int jPart=0; jPart<pShape->Get_Part_Count(); jPart++) { if( pShape->Get_Point_Count(jPart) > 1 ) { jA = pShape->Get_Point(0, jPart); for(int jPoint=1; jPoint<pShape->Get_Point_Count(jPart); jPoint++) { jB = jA; jA = pShape->Get_Point(jPoint, jPart); if( SG_Get_Crossing(Crossing, iA, iB, jA, jB) ) { return( INTERSECTION_Overlaps ); } } } } } } } } return( INTERSECTION_None ); }