<commit_before>#pragma once
#include <sonder/geometry/circle.hh>

namespace sonder {

class circular_section {
 public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW;

  circular_section(const Eigen::Vector3f &_direction,
                   const Eigen::Vector3f &_normal,
                   const Eigen::Vector3f &_center,
                   const float            _radius,
                   const float            _arc_rads)
      : direction(_direction), normal(_normal), center(_center), radius(_radius), arc_rads(_arc_rads) {
  }

  const Eigen::Vector3f direction = Eigen::Vector3f::Zero();
  const Eigen::Vector3f normal    = Eigen::Vector3f::Zero();
  const Eigen::Vector3f center    = Eigen::Vector3f::Zero();
  const float           radius    = 0.0f;
  const float           arc_rads  = 0.0f;
};
}<commit_msg>Add circular section intersection<commit_after>#pragma once
#include <sonder/geometry/circle.hh>

namespace sonder {

class circular_section {
 public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW;

  circular_section(const Eigen::Vector3f &_direction,
                   const Eigen::Vector3f &_normal,
                   const Eigen::Vector3f &_center,
                   const float            _radius,
                   const float            _arc_rads)
      : direction(_direction),
        normal(_normal),
        center(_center),
        radius(_radius),
        arc_rads(_arc_rads),
        spanning_circle(_normal, _center, _radius) {
    _cos_arc_rads = std::cos(_arc_rads);
  }
  EigStdVector<Eigen::Vector3f> intersect(const circular_section &other) const {
    EigStdVector<Eigen::Vector3f>       intersections;
    const EigStdVector<Eigen::Vector3f> candidate_intersections = spanning_circle.intersect(other.spanning_circle);
    for (const auto &candidate : candidate_intersections) {
      const bool on_both_arcs = is_point_on_circle_on_arc(candidate) && other.is_point_on_circle_on_arc(candidate);

      if (on_both_arcs) {
        intersections.emplace_back(candidate);
      }

      // std::cout << dot << " : " << _cos_arc_rads << std::endl;
    }

    return intersections;
  }

  const Eigen::Vector3f direction = Eigen::Vector3f::Zero();
  const Eigen::Vector3f normal    = Eigen::Vector3f::Zero();
  const Eigen::Vector3f center    = Eigen::Vector3f::Zero();

  const float radius   = 0.0f;
  const float arc_rads = 0.0f;

  const circle spanning_circle = circle(Eigen::Vector3f::Zero(), Eigen::Vector3f::Zero(), 0.0);

  // Does a point that already lies on the circle lie on the arc?
  //
  //
  bool is_point_on_circle_on_arc(const Eigen::Vector3f &pt) const {
    const auto  difference = (pt - center).normalized();
    const float dot        = std::fabs(difference.dot(direction));
    return (dot >= _cos_arc_rads);
  }

 private:
  float _cos_arc_rads;
};
}
{'fraction_non_alphanumeric': 0.10884353741496598, 'fraction_numerical': 0.01217329036877909, 'mean_word_length': 3.0434153400868307, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 9, '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': '2967801', 'n_tokens_mistral': 913, 'n_tokens_neox': 860, 'n_words': 177}