/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2020-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM 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 General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . \*---------------------------------------------------------------------------*/ #include "polyLine.H" #include "SubList.H" // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // Foam::tmp Foam::polyLine::concat ( const point& p0, const pointField& intermediate, const point& p1 ) { auto tresult = tmp::New(intermediate.size() + 2); auto& result = tresult.ref(); // Intermediate points (knots) SubList(result, intermediate.size(), 1) = intermediate; // Start/end points (knots) result.first() = p0; result.last() = p1; return tresult; } // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // void Foam::polyLine::calcParam() { lineLength_ = 0; param_.resize(points_.size()); if (param_.size()) { param_[0] = 0; for (label i=1; i < param_.size(); i++) { param_[i] = param_[i-1] + mag(points_[i] - points_[i-1]); } // Normalize on the interval 0-1 lineLength_ = param_.last(); for (label i=1; i < param_.size() - 1; i++) { param_[i] /= lineLength_; } param_.last() = 1; } } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::polyLine::polyLine(const pointField& p, const bool) : points_(p), lineLength_(0), param_() { calcParam(); } Foam::polyLine::polyLine ( const point& start, const pointField& intermediate, const point& end, const bool ) : points_(polyLine::concat(start, intermediate, end)), lineLength_(0), param_() { calcParam(); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // const Foam::pointField& Foam::polyLine::points() const noexcept { return points_; } Foam::label Foam::polyLine::nSegments() const noexcept { return points_.size()-1; } Foam::label Foam::polyLine::localParameter(scalar& lambda) const { // Check endpoints if (lambda < SMALL) { lambda = 0; return 0; } else if (lambda > 1 - SMALL) { lambda = 1; return nSegments(); } // Search table of cumulative distances to find which line-segment // we are on. // Check the upper bound. // Too small to bother with a binary search... label segment = 1; while (param_[segment] < lambda) { ++segment; } --segment; // We want the corresponding lower bound // The local parameter [0-1] on this line segment lambda = (lambda - param_[segment])/(param_[segment+1] - param_[segment]); return segment; } Foam::point Foam::polyLine::position(const scalar mu) const { // Check end-points if (mu < SMALL) { return points_.first(); } else if (mu > 1 - SMALL) { return points_.last(); } scalar lambda = mu; label segment = localParameter(lambda); return position(segment, lambda); } Foam::point Foam::polyLine::position ( const label segment, const scalar mu ) const { // Out-of-bounds if (segment < 0) { return points_.first(); } else if (segment > nSegments()) { return points_.last(); } const point& p0 = points_[segment]; const point& p1 = points_[segment+1]; // Special cases - no calculation needed if (mu <= 0.0) { return p0; } else if (mu >= 1.0) { return p1; } // Linear interpolation return points_[segment] + mu*(p1 - p0); } Foam::scalar Foam::polyLine::length() const noexcept { return lineLength_; } // ************************************************************************* //