#!/usr/bin/ruby
# 直線の検出サンプル
# Satofumi KAMIMURA
# $Id: detectLines.rb 778 2009-05-05 08:13:45Z satofumi $

# !!! あとは、角度が同じデータを直線としてまとめるあたり
# !!! とりあえず、帰宅して寝ましょうか

ShiftValue = 0
JudgeDegree = 10
EachMaxLength = 50
MinPoints = 1
MinLength = 40


pre_x = 0
pre_y = 0
pre_point_x = 0
pre_point_y = 0

line_begin_x = 0
line_begin_y = 0
line_end_x = 0
line_end_y = 0

line_points = 0

pre_degree = 0

print "plot 'points.dat' with point pointsize 0\n"

while line = gets

  real_x, real_y, index = line.split
  real_x = real_x.to_i
  real_y = real_y.to_i

  # 距離誤差を取り除くために、除算して平滑化する
  x = real_x.to_i >> ShiftValue
  y = real_y.to_i >> ShiftValue

  if (pre_x != x) || (pre_y != y)

    # 隣接点との傾きを計算する
    degree = Math::atan2(pre_point_y - y, pre_point_x - x) * 180.0 / Math::PI;

    print '# ', real_x, "\t", real_y, "\t", index, ', ', degree.to_i, ' (', pre_x, ', ', pre_y, ')', "\n"

    if (pre_degree - degree).abs <= JudgeDegree
      line_points = line_points + 1
      line_end_x = real_x
      line_end_y = real_y

    else
      if line_points >= MinPoints
        # 点と点との距離の平均値を計算し、間隔が広すぎるならば登録しない
        diff_x = line_end_x - line_begin_x
        diff_y = line_end_y - line_begin_y
        length = Math::sqrt((diff_x * diff_x) + (diff_y * diff_y)).to_i
        each_length = length / line_points
        if (length > MinLength) && (each_length < EachMaxLength)
          # 複数回、同じ角度として扱われたデータがあれば、始点と終点を表示する
          # !!! 実際には、まとめる点の傾きを平均し、中心点を通過する直線にすべき
          # !!! 点と線を完全に重ねると見にくいので、意図的にずらしてある
          offset = 30
          print 'set arrow from ', (line_begin_x + offset), ', ', (line_begin_y + offset), ' to ', (line_end_x + offset), ', ', (line_end_y + offset), "\n"
        end
      end

      # 始点の記録
      line_begin_x = real_x
      line_begin_y = real_y
      line_end_x = line_begin_x
      line_end_y = line_begin_y
      line_points = 0
    end

    pre_degree = degree
    pre_point_x = x
    pre_point_y = y
  else
    line_points = line_points + 1
  end

  pre_x = x
  pre_y = y
end

print "pause -1\n"
