diff options
Diffstat (limited to 'binfilter/bf_sch/source/core/sch_calculat.cxx')
-rw-r--r-- | binfilter/bf_sch/source/core/sch_calculat.cxx | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/binfilter/bf_sch/source/core/sch_calculat.cxx b/binfilter/bf_sch/source/core/sch_calculat.cxx new file mode 100644 index 000000000000..e4c0dc4f40b5 --- /dev/null +++ b/binfilter/bf_sch/source/core/sch_calculat.cxx @@ -0,0 +1,206 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// header for Point, Rectangle +// header for Polygon +// header for DBG_ASSERT +// header for XPolygon, XPolyPolygon +#include <bf_svx/xpoly.hxx> +// header for Line +#include <tools/line.hxx> +// for performance measurement +#include <rtl/logfile.hxx> + +// Note: Enable the following to skip points in the resulting spline +// poly-polygon, if they have equal x-values rather than identical points. +// Unitl now, I think there are situations where the output might differ, if you +// do so, so it's not enabled by default. + +// #define SPLINE_OPTIMIZE_POINTS + +#include "calculat.hxx" + +#include <algorithm> +#include <functional> +namespace binfilter { + +using namespace ::std; + + +/*N*/ void SchCalculationHelper::IntersectPolygonWithRectangle( const XPolygon& rPolygon, const Rectangle& rRectangle, XPolyPolygon& aResult ) +/*N*/ { +/*N*/ RTL_LOGFILE_CONTEXT_AUTHOR( context, "sch", "bm93744", "SchCalculationHelper::IntersectPolygonWithRectangle"); +/*N*/ +/*N*/ aResult.Clear(); +/*N*/ +/*N*/ if( rRectangle.IsInside( rPolygon.GetBoundRect() ) ) +/*N*/ { +/*N*/ aResult.Insert( rPolygon ); +/*N*/ OSL_TRACE( "IntersectPolygonWithRectangle: result has %d polygons", aResult.Count() ); +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ Point aFrom; +/*N*/ Point aTo; +/*N*/ USHORT nCount = rPolygon.GetPointCount(); +/*N*/ +/*N*/ // set last point to a position outside the rectangle, such that the first +/*N*/ // time clip2d returns true, the comparison to last will always yield false +/*N*/ Point aLast (rRectangle.TopLeft()); +/*N*/ aLast.Move (-1, -1); +/*N*/ XPolygon aCurrentPoly; +/*N*/ USHORT nIdx = 0; +/*N*/ +/*N*/ for (USHORT i=1; i<nCount; i++) +/*N*/ { +/*N*/ aFrom = rPolygon[i-1]; +/*N*/ aTo = rPolygon[i]; +/*N*/ if (clip2d (aFrom, aTo, rRectangle)) +/*N*/ { +/*N*/ // compose an XPolygon of as many consecutive points as possible +/*N*/ if (aFrom == aLast) +/*N*/ { +/*N*/ if (aTo != aFrom) +/*N*/ aCurrentPoly.Insert (nIdx++, aTo, XPOLY_NORMAL); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // create an XPolygon and put it into the XPolyPolygon +/*N*/ if (aCurrentPoly.GetPointCount() > 0) +/*N*/ aResult.Insert (aCurrentPoly, XPOLYPOLY_APPEND); +/*N*/ +/*N*/ // start new sequence +/*N*/ aCurrentPoly.SetPointCount (0); +/*N*/ aCurrentPoly.Insert (0, aFrom, XPOLY_NORMAL); +/*N*/ nIdx = 1; +/*N*/ if (aTo != aFrom) +/*N*/ aCurrentPoly.Insert (nIdx++, aTo, XPOLY_NORMAL); +/*N*/ } +/*N*/ +/*N*/ aLast = aTo; +/*N*/ } +/*N*/ } +/*N*/ if (aCurrentPoly.GetPointCount() > 0) +/*N*/ aResult.Insert (aCurrentPoly, XPOLYPOLY_APPEND); +/*N*/ +/*N*/ OSL_TRACE( "IntersectPolygonWithRectangle: result has %d polygons", aResult.Count() ); +/*N*/ } + + + + + +/*N*/ BOOL SchCalculationHelper::clip2d (Point & rPoint0, +/*N*/ Point & rPoint1, +/*N*/ const Rectangle & rRectangle) +/*N*/ { +/*N*/ // Direction vector of the line. +/*N*/ Point aD = rPoint1 - rPoint0; +/*N*/ +/*N*/ if (aD.X()==0 && aD.Y()==0 && rRectangle.IsInside (rPoint0)) +/*N*/ { +/*N*/ // Degenerate case of a zero length line. +/*N*/ return TRUE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Values of the line parameter where the line enters resp. leaves the rectangle. +/*N*/ double fTE = 0, +/*N*/ fTL = 1; +/*N*/ +/*N*/ // Test wether at least a part lies in the four half-planes with respect to +/*N*/ // the rectangles four edges. +/*N*/ if (CLIPt (aD.X(), rRectangle.Left() - rPoint0.X(), fTE, fTL)) +/*N*/ if (CLIPt (-aD.X(), rPoint0.X() - rRectangle.Right(), fTE, fTL)) +/*N*/ if (CLIPt (aD.Y(), rRectangle.Top() - rPoint0.Y(), fTE, fTL)) +/*N*/ if (CLIPt (-aD.Y(), rPoint0.Y() - rRectangle.Bottom(), fTE, fTL)) +/*N*/ { +/*N*/ // At least a part is visible. +/*N*/ if (fTL < 1) +/*N*/ { +/*N*/ // ::com::pute the new end point. +/*N*/ rPoint1.X() = (long)(rPoint0.X() + fTL * aD.X() + 0.5); +/*N*/ rPoint1.Y() = (long)(rPoint0.Y() + fTL * aD.Y() + 0.5); +/*N*/ } +/*N*/ if (fTE > 0) +/*N*/ { +/*N*/ // ::com::pute the new starting point. +/*N*/ rPoint0.X() = (long)(rPoint0.X() + fTE * aD.X() + 0.5); +/*N*/ rPoint0.Y() = (long)(rPoint0.Y() + fTE * aD.Y() + 0.5); +/*N*/ } +/*N*/ return TRUE; +/*N*/ } +/*N*/ +/*N*/ // Line is not visible. +/*N*/ return FALSE; +/*N*/ } +/*N*/ } + + + + +/*N*/ BOOL SchCalculationHelper::CLIPt (double fDenom, +/*N*/ double fNum, +/*N*/ double & fTE, +/*N*/ double & fTL) +/*N*/ { +/*N*/ double fT; +/*N*/ +/*N*/ if (fDenom > 0) // Intersection enters: PE +/*N*/ { +/*N*/ fT = fNum / fDenom; // Parametric value at the intersection. +/*N*/ if (fT > fTL) // fTE and fTL crossover +/*N*/ return FALSE; // therefore reject the line. +/*N*/ else if (fT > fTE) // A new fTE has been found. +/*N*/ fTE = fT; +/*N*/ } +/*N*/ else if (fDenom < 0) // Intersection leaves: PL +/*N*/ { +/*N*/ fT = fNum / fDenom; // Parametric Value at the intersection. +/*N*/ if (fT < fTE) // fTE and fTL crossover +/*N*/ return FALSE; // therefore reject the line. +/*N*/ else if (fT < fTL) // A new fTL has been found. +/*N*/ fTL = fT; +/*N*/ } +/*N*/ else if (fNum > 0) +/*N*/ return FALSE; // Line lies on the outside of the edge. +/*N*/ +/*N*/ return TRUE; +/*N*/ } + + +// -------------------------------------------------------------------------------- + +// Calculation of Splines + + +// ---------------------------------------- + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |