This repository has been archived by the owner on Nov 19, 2023. It is now read-only.
/
point.rb
117 lines (95 loc) · 2.06 KB
/
point.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# Copyright (c) 2009 Paolo Capriotti <p.capriotti@gmail.com>
#
# This program 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 2 of the License, or
# (at your option) any later version.
require 'toolkit'
class Point
include PrintablePoint
attr_reader :x, :y
def initialize(x, y)
@x = x
@y = y
end
def == other
other and @x == other.x and @y == other.y
end
def + other
self.class.new(@x + other.x, @y + other.y)
end
def - other
self.class.new(@x - other.x, @y - other.y)
end
def * factor
self.class.new(@x * factor, @y * factor)
end
def / factor
self.class.new(@x / factor, @y / factor)
end
def eql?(other)
other.instance_of?(Point) and self == other
end
def hash
[@x, @y].hash
end
def unit
Point.new(@x.unit, @y.unit)
end
def =~(other)
other.nil? or
(((not other.x) or other.x == x) and
((not other.y) or other.y == y))
end
def to_coord(ysize)
"#{(self.x + ?a).chr if x}#{(ysize - self.y) if self.y}"
end
def self.from_coord(s, ysize, opts = { })
if s =~ /^([a-zA-Z]?)(\d*)/
letter = $1
number = $2
x = unless letter.empty?
if letter =~ /[a-z]/
letter[0] - ?a
else
letter[0] - ?A
end
end
y = ysize - number.to_i unless number.empty?
if (x and y) or (not opts[:strict])
new x, y
end
end
end
end
class PointRange
include Enumerable
attr_reader :src, :dst, :delta
def initialize(src, dst)
@src = src
@dst = dst
@delta = @dst - @src
@increment = @delta.unit
end
def each
current = @src
while current != @dst
yield current
current += @increment
end
end
def parallel?
@delta.x == 0 or @delta.y == 0
end
def diagonal?
@delta.x.abs == @delta.y.abs
end
def valid?
parallel? or diagonal?
end
end
class Numeric
def unit
self <=> 0
end
end