<commit_before>//
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2010 <NAME>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file at the top level of the distribution
// and at http://projectchrono.org/license-chrono.txt.
//

#ifndef CHC_LINEPATH_H
#define CHC_LINEPATH_H

#include <math.h>

#include "ChCLine.h"
#include "core/ChSmartpointers.h"

namespace chrono {
namespace geometry {

#define CH_GEOCLASS_LINEPATH 20

///
/// PATH
///
/// Geometric object representing an sequence of other ChLine objects,
/// assuming they are concatenated properly, to have C0 continuity.
///

class ChApi ChLinePath : public ChLine {
    // Chrono simulation of RTTI, needed for serialization
    CH_RTTI(ChLinePath, ChLine);

  public:
    //
    // DATA
    //
    std::vector<ChSharedPtr<ChLine> > lines;
    std::vector<double> end_times;
    std::vector<double> durations;

  public:
    //
    // CONSTRUCTORS
    //

    // Creation by default.

    ChLinePath() {}

    ~ChLinePath(){};

    ChLinePath(const ChLinePath& source) {
        lines = source.lines;
        end_times = source.end_times;
        durations = source.durations;
    }

    void Copy(const ChLinePath* source) {
        ChLine::Copy(source);
        lines = source->lines;
        end_times = source->end_times;
        durations = source->durations;
    }

    ChGeometry* Duplicate() { return new ChLinePath(*this); };

    //
    // OVERRIDE BASE CLASS FUNCTIONS
    //

    virtual int GetClassType() { return CH_GEOCLASS_LINEPATH; };

    virtual int Get_complexity() { return 2; };

    /// Returns curve length. sampling does not matter
    double Length(int sampling) {
        double tot = 0;
        for (int i = 0; i < lines.size(); ++i) {
            tot += lines[i]->Length(sampling);
        }
        return tot;
    }

    /// Curve evaluation (only parU is used, in 0..1 range)
    virtual void Evaluate(Vector& pos, const double parU, const double parV = 0., const double parW = 0.) {
        if (lines.size() == 0)
            return;

        double u = parU;

        // wrap u if it is a closed loop.
        if (this->closed)
            u = fmod(parU, this->GetPathDuration());

        double uA = 0;
        double uB = 0;
        // Search sub line covering the parU
        // (brute force search.. assuming a limited number of
        // added lines, it is ok anyway.)
        int i;
        for (i = 0; i < lines.size(); ++i) {
            if (u <= end_times[i])
                break;
        }
        if (i == lines.size())  // beyond end
            i -= 1;
        uB = end_times[i];
        if (i > 0)
            uA = end_times[i - 1];

        double local_U = (u - uA) / durations[i];
        lines[i]->Evaluate(pos, local_U, 0, 0);
    }

    /// Return the start point of the line.
    virtual ChVector<> GetEndA() { return (*lines.begin())->GetEndA(); }

    /// Return the end point of the line.
    virtual ChVector<> GetEndB() { return (*lines.end())->GetEndB(); }

    //
    // CUSTOM FUNCTIONS
    //

    /// Get count of sub-lines that have been added:
    size_t GetSubLinesCount() { return lines.size(); }

    /// Access the nth line
    ChSharedPtr<ChLine> GetSubLineN(size_t n) { return lines[n]; }

    /// Get the nth line duration
    double GetSubLineDurationN(size_t n) { return durations[n]; }

    /// Set the nth line duration
    void SetSubLineDurationN(size_t n, double mduration) {
        durations[n] = mduration;

        double last_t = 0;
        if (n > 0)
            last_t = end_times[n - 1];
        for (size_t i = n; i < end_times.size(); ++i) {
            last_t += durations[n];<commit_msg>References to ends of poly lines - the correct way<commit_after>//
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2010 <NAME>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file at the top level of the distribution
// and at http://projectchrono.org/license-chrono.txt.
//

#ifndef CHC_LINEPATH_H
#define CHC_LINEPATH_H

#include <math.h>

#include "ChCLine.h"
#include "core/ChSmartpointers.h"

namespace chrono {
namespace geometry {

#define CH_GEOCLASS_LINEPATH 20

///
/// PATH
///
/// Geometric object representing an sequence of other ChLine objects,
/// assuming they are concatenated properly, to have C0 continuity.
///

class ChApi ChLinePath : public ChLine {
    // Chrono simulation of RTTI, needed for serialization
    CH_RTTI(ChLinePath, ChLine);

  public:
    //
    // DATA
    //
    std::vector<ChSharedPtr<ChLine> > lines;
    std::vector<double> end_times;
    std::vector<double> durations;

  public:
    //
    // CONSTRUCTORS
    //

    // Creation by default.

    ChLinePath() {}

    ~ChLinePath(){};

    ChLinePath(const ChLinePath& source) {
        lines = source.lines;
        end_times = source.end_times;
        durations = source.durations;
    }

    void Copy(const ChLinePath* source) {
        ChLine::Copy(source);
        lines = source->lines;
        end_times = source->end_times;
        durations = source->durations;
    }

    ChGeometry* Duplicate() { return new ChLinePath(*this); };

    //
    // OVERRIDE BASE CLASS FUNCTIONS
    //

    virtual int GetClassType() { return CH_GEOCLASS_LINEPATH; };

    virtual int Get_complexity() { return 2; };

    /// Returns curve length. sampling does not matter
    double Length(int sampling) {
        double tot = 0;
        for (int i = 0; i < lines.size(); ++i) {
            tot += lines[i]->Length(sampling);
        }
        return tot;
    }

    /// Curve evaluation (only parU is used, in 0..1 range)
    virtual void Evaluate(Vector& pos, const double parU, const double parV = 0., const double parW = 0.) {
        if (lines.size() == 0)
            return;

        double u = parU;

        // wrap u if it is a closed loop.
        if (this->closed)
            u = fmod(parU, this->GetPathDuration());

        double uA = 0;
        double uB = 0;
        // Search sub line covering the parU
        // (brute force search.. assuming a limited number of
        // added lines, it is ok anyway.)
        int i;
        for (i = 0; i < lines.size(); ++i) {
            if (u <= end_times[i])
                break;
        }
        if (i == lines.size())  // beyond end
            i -= 1;
        uB = end_times[i];
        if (i > 0)
            uA = end_times[i - 1];

        double local_U = (u - uA) / durations[i];
        lines[i]->Evaluate(pos, local_U, 0, 0);
    }

    /// Return the start point of the line.
    virtual ChVector<> GetEndA() { return (lines.front())->GetEndA(); }

    /// Return the end point of the line.
    virtual ChVector<> GetEndB() { return (lines.back())->GetEndB(); }

    //
    // CUSTOM FUNCTIONS
    //

    /// Get count of sub-lines that have been added:
    size_t GetSubLinesCount() { return lines.size(); }

    /// Access the nth line
    ChSharedPtr<ChLine> GetSubLineN(size_t n) { return lines[n]; }

    /// Get the nth line duration
    double GetSubLineDurationN(size_t n) { return durations[n]; }

    /// Set the nth line duration
    void SetSubLineDurationN(size_t n, double mduration) {
        durations[n] = mduration;

        double last_t = 0;
        if (n > 0)
            last_t = end_times[n - 1];
        for (size_t i = n; i < end_times.size(); ++i) {
            last_t += durations[n];
{'fraction_non_alphanumeric': 0.12682991748735695, 'fraction_numerical': 0.006920415224913495, 'mean_word_length': 2.0736196319018405, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6119625', 'n_tokens_mistral': 2457, 'n_tokens_neox': 2329, 'n_words': 729}