<commit_before>/******************************************************************************
 *
 * File:        chop.cpp  (Formerly chop.c)
 * Author:      <NAME>, OCR Technology
 *
 * (c) Copyright 1987, Hewlett-Packard Company.
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 ** http://www.apache.org/licenses/LICENSE-2.0
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 *
 *****************************************************************************/

/*----------------------------------------------------------------------
              I n c l u d e s
----------------------------------------------------------------------*/

#define _USE_MATH_DEFINES // for M_PI
#include "chop.h"
#include <cmath> // for M_PI
#include "outlines.h"
#include "plotedges.h"
#include "wordrec.h"

// Include automatically generated configuration file if running autoconf.
#ifdef HAVE_CONFIG_H
#  include "config_auto.h"
#endif

namespace tesseract {

// Show if the line is going in the positive or negative X direction.
static int direction(const EDGEPT *point) {
  //* direction to return
  int dir = 0;
  //* prev point
  const EDGEPT *prev = point->prev;
  //* next point
  const EDGEPT *next = point->next;

  if (((prev->pos.x <= point->pos.x) && (point->pos.x < next->pos.x)) ||
      ((prev->pos.x < point->pos.x) && (point->pos.x <= next->pos.x))) {
    dir = 1;
  }
  if (((prev->pos.x >= point->pos.x) && (point->pos.x > next->pos.x)) ||
      ((prev->pos.x > point->pos.x) && (point->pos.x >= next->pos.x))) {
    dir = -1;
  }

  return dir;
}

/**
 * @name point_priority
 *
 * Assign a priority to and edge point that might be used as part of a
 * split. The argument should be of type EDGEPT.
 */
PRIORITY Wordrec::point_priority(EDGEPT *point) {
  return static_cast<PRIORITY>(angle_change(point->prev, point, point->next));
}

/**
 * @name add_point_to_list
 *
 * Add an edge point to a POINT_GROUP containing a list of other points.
 */
void Wordrec::add_point_to_list(PointHeap *point_heap, EDGEPT *point) {
  if (point_heap->size() < MAX_NUM_POINTS - 2) {
    PointPair pair(point_priority(point), point);
    point_heap->Push(&pair);
  }

#ifndef GRAPHICS_DISABLED
  if (chop_debug > 2) {
    mark_outline(point);
  }
#endif
}

// Returns true if the edgept supplied as input is an inside angle.  This
// is determined by the angular change of the vectors from point to point.
bool Wordrec::is_inside_angle(EDGEPT *pt) {
  return angle_change(pt->prev, pt, pt->next) < chop_inside_angle;
}

/**
 * @name angle_change
 *
 * Return the change in angle (degrees) of the line segments between
 * points one and two, and two and three.
 */
int Wordrec::angle_change(EDGEPT *point1, EDGEPT *point2, EDGEPT *point3) {
  VECTOR vector1;
  VECTOR vector2;

  int angle;

  /* Compute angle */
  vector1.x = point2->pos.x - point1->pos.x;
  vector1.y = point2->pos.y - point1->pos.y;
  vector2.x = point3->pos.x - point2->pos.x;
  vector2.y = point3->pos.y - point2->pos.y;
  /* Use cross product */
  float length = std::sqrt(static_cast<float>(vector1.length()) * vector2.length());
  if (static_cast<int>(length) == 0) {
    return (0);
  }
  angle = static_cast<int>(floor(asin(vector1.cross(vector2) / length) / M_PI * 180.0 + 0.5));

  /* Use dot product */
  if (vector1.dot(vector2) < 0) {
    angle = 180 - angle;
  }
  /* Adjust angle */
  if (angle > 180) {
    angle -= 360;
  }
  if (angle <= -180) {
    angle += 360;
  }
  return (angle);
}

/**
 * @name pick_close_point
 *
 * Choose the edge point that is closest to the critical point.  This
 * point may not be exactly vertical from the critical point.
 */
EDGEPT *Wordrec::pick_close_point(EDGEPT *critical_point, EDGEPT *vertical_point, int *best_dist) {
  EDGEPT *best_point = nullptr;
  int this_distance;
  int found_better;

  do {
    found_better = false;

    this_distance = edgept_dist(critical_point, vertical_point);
    if (this_distance <= *best_dist) {
      if (!(same_point(critical_point->pos, vertical_point->pos) ||
            same_point(critical_point->pos, vertical_point->next->pos) ||
            (best_point && same_point(best_point->pos, vertical_point->pos)) ||
            is_exterior_point(critical_point, vertical_point))) {
        *best_dist = this_distance;
        best_point = vertical_point;
        if (chop_vertical_creep) {
          found_better = true;
        }
      }
    }
    vertical_point = vertical_point->next;
  } while (found_better == true);

  return (best_point);
}

/**<commit_msg>[misc] Fix variable type. Fixes warning.<commit_after>/******************************************************************************
 *
 * File:        chop.cpp  (Formerly chop.c)
 * Author:      <NAME>, OCR Technology
 *
 * (c) Copyright 1987, Hewlett-Packard Company.
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 ** http://www.apache.org/licenses/LICENSE-2.0
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 *
 *****************************************************************************/

/*----------------------------------------------------------------------
              I n c l u d e s
----------------------------------------------------------------------*/

#define _USE_MATH_DEFINES // for M_PI
#include "chop.h"
#include <cmath> // for M_PI
#include "outlines.h"
#include "plotedges.h"
#include "wordrec.h"

// Include automatically generated configuration file if running autoconf.
#ifdef HAVE_CONFIG_H
#  include "config_auto.h"
#endif

namespace tesseract {

// Show if the line is going in the positive or negative X direction.
static int direction(const EDGEPT *point) {
  //* direction to return
  int dir = 0;
  //* prev point
  const EDGEPT *prev = point->prev;
  //* next point
  const EDGEPT *next = point->next;

  if (((prev->pos.x <= point->pos.x) && (point->pos.x < next->pos.x)) ||
      ((prev->pos.x < point->pos.x) && (point->pos.x <= next->pos.x))) {
    dir = 1;
  }
  if (((prev->pos.x >= point->pos.x) && (point->pos.x > next->pos.x)) ||
      ((prev->pos.x > point->pos.x) && (point->pos.x >= next->pos.x))) {
    dir = -1;
  }

  return dir;
}

/**
 * @name point_priority
 *
 * Assign a priority to and edge point that might be used as part of a
 * split. The argument should be of type EDGEPT.
 */
PRIORITY Wordrec::point_priority(EDGEPT *point) {
  return static_cast<PRIORITY>(angle_change(point->prev, point, point->next));
}

/**
 * @name add_point_to_list
 *
 * Add an edge point to a POINT_GROUP containing a list of other points.
 */
void Wordrec::add_point_to_list(PointHeap *point_heap, EDGEPT *point) {
  if (point_heap->size() < MAX_NUM_POINTS - 2) {
    PointPair pair(point_priority(point), point);
    point_heap->Push(&pair);
  }

#ifndef GRAPHICS_DISABLED
  if (chop_debug > 2) {
    mark_outline(point);
  }
#endif
}

// Returns true if the edgept supplied as input is an inside angle.  This
// is determined by the angular change of the vectors from point to point.
bool Wordrec::is_inside_angle(EDGEPT *pt) {
  return angle_change(pt->prev, pt, pt->next) < chop_inside_angle;
}

/**
 * @name angle_change
 *
 * Return the change in angle (degrees) of the line segments between
 * points one and two, and two and three.
 */
int Wordrec::angle_change(EDGEPT *point1, EDGEPT *point2, EDGEPT *point3) {
  VECTOR vector1;
  VECTOR vector2;

  int angle;

  /* Compute angle */
  vector1.x = point2->pos.x - point1->pos.x;
  vector1.y = point2->pos.y - point1->pos.y;
  vector2.x = point3->pos.x - point2->pos.x;
  vector2.y = point3->pos.y - point2->pos.y;
  /* Use cross product */
  float length = std::sqrt(static_cast<float>(vector1.length()) * vector2.length());
  if (static_cast<int>(length) == 0) {
    return (0);
  }
  angle = static_cast<int>(floor(asin(vector1.cross(vector2) / length) / M_PI * 180.0 + 0.5));

  /* Use dot product */
  if (vector1.dot(vector2) < 0) {
    angle = 180 - angle;
  }
  /* Adjust angle */
  if (angle > 180) {
    angle -= 360;
  }
  if (angle <= -180) {
    angle += 360;
  }
  return (angle);
}

/**
 * @name pick_close_point
 *
 * Choose the edge point that is closest to the critical point.  This
 * point may not be exactly vertical from the critical point.
 */
EDGEPT *Wordrec::pick_close_point(EDGEPT *critical_point, EDGEPT *vertical_point, int *best_dist) {
  EDGEPT *best_point = nullptr;
  int this_distance;
  bool found_better;

  do {
    found_better = false;

    this_distance = edgept_dist(critical_point, vertical_point);
    if (this_distance <= *best_dist) {
      if (!(same_point(critical_point->pos, vertical_point->pos) ||
            same_point(critical_point->pos, vertical_point->next->pos) ||
            (best_point && same_point(best_point->pos, vertical_point->pos)) ||
            is_exterior_point(critical_point, vertical_point))) {
        *best_dist = this_distance;
        best_point = vertical_point;
        if (chop_vertical_creep) {
          found_better = true;
        }
      }
    }
    vertical_point = vertical_point->next;
  } while (found_better == true);

  return (best_point);
}

/**
{'fraction_non_alphanumeric': 0.18760129659643435, 'fraction_numerical': 0.012155591572123177, 'mean_word_length': 2.981048387096774, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 107, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '6471262', 'n_tokens_mistral': 3241, 'n_tokens_neox': 3124, 'n_words': 911}