angles 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
@@ -0,0 +1,63 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="RUBY_MODULE" version="4">
3
+ <component name="FacetManager">
4
+ <facet type="gem" name="Ruby Gem">
5
+ <configuration>
6
+ <option name="GEM_APP_ROOT_PATH" value="$MODULE_DIR$" />
7
+ <option name="GEM_APP_TEST_PATH" value="$MODULE_DIR$/test" />
8
+ <option name="GEM_APP_LIB_PATH" value="$MODULE_DIR$/lib" />
9
+ </configuration>
10
+ </facet>
11
+ </component>
12
+ <component name="ModuleRunConfigurationManager">
13
+ <configuration default="false" name="gem install angles" type="CommandRunConfigurationType" factoryName="Gem Command">
14
+ <module name="angles" />
15
+ <COMMAND_RUN_CONFIGURATION NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" />
16
+ <COMMAND_RUN_CONFIGURATION NAME="WORK DIR" VALUE="$MODULE_DIR$" />
17
+ <COMMAND_RUN_CONFIGURATION NAME="SHOULD_USE_SDK" VALUE="false" />
18
+ <COMMAND_RUN_CONFIGURATION NAME="ALTERN_SDK_NAME" VALUE="" />
19
+ <COMMAND_RUN_CONFIGURATION NAME="myPassParentEnvs" VALUE="true" />
20
+ <envs />
21
+ <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="false" />
22
+ <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" />
23
+ <EXTENSION ID="RubyCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" track_test_folders="true" runner="rcov" />
24
+ <EXTENSION ID="org.jetbrains.plugins.ruby.motion.run.MotionSimulatorRunExtension" />
25
+ <COMMAND_CONFIG_SETTINGS_ID NAME="GEM_NAME" VALUE="bundler" />
26
+ <COMMAND_CONFIG_SETTINGS_ID NAME="EXECUTABLE_NAME" VALUE="gem" />
27
+ <COMMAND_CONFIG_SETTINGS_ID NAME="EXECUTABLE_ARGS" VALUE="install ./angles-0.0.1.gem" />
28
+ <COMMAND_CONFIG_SETTINGS_ID NAME="WORKING_DIR" VALUE="install ./angles-0.0.1.gem" />
29
+ <RunnerSettings RunnerId="RubyRunner" />
30
+ <ConfigurationWrapper RunnerId="RubyRunner" />
31
+ <method />
32
+ </configuration>
33
+ <configuration default="false" name="IRB console: angles" type="IrbRunConfigurationType" factoryName="IRB console" temporary="true">
34
+ <module name="angles" />
35
+ <IRB_RUN_CONFIG NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" />
36
+ <IRB_RUN_CONFIG NAME="WORK DIR" VALUE="$MODULE_DIR$" />
37
+ <IRB_RUN_CONFIG NAME="SHOULD_USE_SDK" VALUE="false" />
38
+ <IRB_RUN_CONFIG NAME="ALTERN_SDK_NAME" VALUE="" />
39
+ <IRB_RUN_CONFIG NAME="myPassParentEnvs" VALUE="true" />
40
+ <envs />
41
+ <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="false" />
42
+ <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" />
43
+ <EXTENSION ID="RubyCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" track_test_folders="true" runner="rcov" />
44
+ <EXTENSION ID="org.jetbrains.plugins.ruby.motion.run.MotionSimulatorRunExtension" />
45
+ <IRB_RUN_CONFIG NAME="SCRIPT_PATH" VALUE="C:/RailsInstaller/Ruby1.9.3/bin/irb" />
46
+ <IRB_RUN_CONFIG NAME="SCRIPT_ARGS" VALUE="--prompt simple" />
47
+ <IRB_RUN_CONFIG NAME="IS_RAILS_CONSOLE" VALUE="false" />
48
+ <RunnerSettings RunnerId="RubyRunner" />
49
+ <ConfigurationWrapper RunnerId="RubyRunner" />
50
+ <method />
51
+ </configuration>
52
+ </component>
53
+ <component name="NewModuleRootManager">
54
+ <content url="file://$MODULE_DIR$">
55
+ <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
56
+ </content>
57
+ <orderEntry type="inheritedJdk" />
58
+ <orderEntry type="sourceFolder" forTests="false" />
59
+ <orderEntry type="library" scope="PROVIDED" name="bundler (v1.7.2, ruby-1.9.3-p545) [gem]" level="application" />
60
+ <orderEntry type="library" scope="PROVIDED" name="rake (v10.3.2, ruby-1.9.3-p545) [gem]" level="application" />
61
+ <orderEntry type="library" scope="PROVIDED" name="ratapprox (v0.0.1, ruby-1.9.3-p545) [gem]" level="application" />
62
+ </component>
63
+ </module>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
4
+ </project>
@@ -0,0 +1,27 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="DaemonCodeAnalyzer">
4
+ <disable_hints />
5
+ </component>
6
+ <component name="DependencyValidationManager">
7
+ <option name="SKIP_IMPORT_STATEMENTS" value="false" />
8
+ </component>
9
+ <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
10
+ <component name="ProjectLevelVcsManager" settingsEditedManually="false">
11
+ <OptionsSetting value="true" id="Add" />
12
+ <OptionsSetting value="true" id="Remove" />
13
+ <OptionsSetting value="true" id="Checkout" />
14
+ <OptionsSetting value="true" id="Update" />
15
+ <OptionsSetting value="true" id="Status" />
16
+ <OptionsSetting value="true" id="Edit" />
17
+ <ConfirmationsSetting value="0" id="Add" />
18
+ <ConfirmationsSetting value="0" id="Remove" />
19
+ </component>
20
+ <component name="ProjectModuleManager">
21
+ <modules />
22
+ </component>
23
+ <component name="ProjectRootManager" version="2" project-jdk-name="ruby-1.9.3-p545" project-jdk-type="RUBY_SDK" />
24
+ <component name="RunManager">
25
+ <list size="0" />
26
+ </component>
27
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/angles.iml" filepath="$PROJECT_DIR$/.idea/angles.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,22 @@
1
+ <component name="ProjectRunConfigurationManager">
2
+ <configuration default="false" name="gem install angles" type="CommandRunConfigurationType" factoryName="Gem Command">
3
+ <module name="angles" />
4
+ <COMMAND_RUN_CONFIGURATION NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" />
5
+ <COMMAND_RUN_CONFIGURATION NAME="WORK DIR" VALUE="$MODULE_DIR$" />
6
+ <COMMAND_RUN_CONFIGURATION NAME="SHOULD_USE_SDK" VALUE="false" />
7
+ <COMMAND_RUN_CONFIGURATION NAME="ALTERN_SDK_NAME" VALUE="" />
8
+ <COMMAND_RUN_CONFIGURATION NAME="myPassParentEnvs" VALUE="true" />
9
+ <envs />
10
+ <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="false" />
11
+ <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" />
12
+ <EXTENSION ID="RubyCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" track_test_folders="true" runner="rcov" />
13
+ <EXTENSION ID="org.jetbrains.plugins.ruby.motion.run.MotionSimulatorRunExtension" />
14
+ <COMMAND_CONFIG_SETTINGS_ID NAME="GEM_NAME" VALUE="bundler" />
15
+ <COMMAND_CONFIG_SETTINGS_ID NAME="EXECUTABLE_NAME" VALUE="gem" />
16
+ <COMMAND_CONFIG_SETTINGS_ID NAME="EXECUTABLE_ARGS" VALUE="install ./angles-0.0.1.gem" />
17
+ <COMMAND_CONFIG_SETTINGS_ID NAME="WORKING_DIR" VALUE="install ./angles-0.0.1.gem" />
18
+ <RunnerSettings RunnerId="RubyRunner" />
19
+ <ConfigurationWrapper RunnerId="RubyRunner" />
20
+ <method />
21
+ </configuration>
22
+ </component>
@@ -0,0 +1,5 @@
1
+ <component name="DependencyValidationManager">
2
+ <state>
3
+ <option name="SKIP_IMPORT_STATEMENTS" value="false" />
4
+ </state>
5
+ </component>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in angles.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Gregory H. Halverson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ # Angles
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'angles'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install angles
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/angles/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'angles/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "angles"
8
+ spec.version = Angles::VERSION
9
+ spec.authors = ["Gregory H. Halverson"]
10
+ spec.email = ["gregory.halverson@gmail.com"]
11
+ spec.summary = %q{Angle class}
12
+ spec.description = %q{Encapsulates angles in Ruby. Easily switch between degrees and radians. Output in human-readable format. Built-in trig functions. Automatically normalize angles.}
13
+ spec.homepage = "https://github.com/gregory-halverson/angles"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "ratapprox", ">=0"
24
+ end
@@ -0,0 +1,458 @@
1
+ require "angles/version"
2
+
3
+ require 'ratapprox'
4
+
5
+ class Angle
6
+ # constants
7
+ @@PI = Math::PI
8
+ @@TWO_PI = Math::PI * 2
9
+ @@PI_SYMBOL = "\u03c0"
10
+ @@DEGREE_SYMBOL = "\u00b0"
11
+ @@SECONDS_DECIMAL_PLACES = 2
12
+ @@ROUND_TRIG = 12
13
+
14
+ # initializers
15
+
16
+ def initialize(angle=0, mode=:degrees, display=:readable)
17
+ @mode = mode
18
+ @display = display
19
+
20
+ case mode
21
+ when :degrees
22
+ self.from_radians Angle.normalize_radians(Angle.degrees_to_radians(angle))
23
+ when :radians
24
+ self.from_radians Angle.normalize_radians angle
25
+ end
26
+ end
27
+
28
+ def from_degrees(degrees)
29
+ @angle = Angle.normalize_radians(Angle.degrees_to_radians(degrees))
30
+ self
31
+ end
32
+
33
+ def from_radians(radians)
34
+ @angle = Angle.normalize_radians(radians)
35
+ self
36
+ end
37
+
38
+ # getters and setters
39
+
40
+ def mode
41
+ @mode
42
+ end
43
+
44
+ def display
45
+ @display
46
+ end
47
+
48
+ def set_display(display)
49
+ @display = display
50
+ end
51
+
52
+ def angle
53
+ @angle
54
+ end
55
+
56
+ def radians
57
+ self.angle
58
+ end
59
+
60
+ def degrees
61
+ Angle.radians_to_degrees(self.radians).to_f
62
+ end
63
+
64
+ def d
65
+ self.degrees.floor
66
+ end
67
+
68
+ def minutes
69
+ self.degrees * 60
70
+ end
71
+
72
+ def m
73
+ self.minutes.floor % 60
74
+ end
75
+
76
+ def seconds
77
+ self.minutes * 60
78
+ end
79
+
80
+ def s
81
+ self.seconds.floor % 60
82
+ end
83
+
84
+ # normailize a value of degrees to [0, 360)
85
+ def self.normalize_degrees(degrees)
86
+ degrees -= 360 while degrees >= 360
87
+ degrees += 360 while degrees < 0
88
+ degrees
89
+ end
90
+
91
+ # normalize a value of radians to [0, 2pi)
92
+ def self.normalize_radians(radians)
93
+ radians -= @@TWO_PI while radians >= @@TWO_PI
94
+ radians += @@TWO_PI while radians < 0
95
+ radians
96
+ end
97
+
98
+ # convert degrees as float to radians as float
99
+ def self.degrees_to_radians(degrees)
100
+ Angle.normalize_radians(degrees.to_f * @@PI / 180)
101
+ end
102
+
103
+ # convert radians as float to degrees as float
104
+ def self.radians_to_degrees(radians)
105
+ Angle.normalize_degrees(radians.to_f * 180 / @@PI)
106
+ end
107
+
108
+ # convert degrees as float to degrees, minutes, seconds
109
+ def self.degrees_to_sexagesimal(degrees)
110
+ degrees = Angle.normalize_degrees(degrees.to_f)
111
+ degrees, remainder = degrees.to_f.modf
112
+ remainder = remainder.round(9)
113
+ minutes, seconds = (remainder * 60).modf
114
+ seconds *= 60
115
+ return degrees, minutes, seconds
116
+ end
117
+
118
+ # convert degrees, minutes, seconds to degrees as float
119
+ def self.sexagesimal_to_degrees(degrees, minutes, seconds)
120
+ degrees = Angle.normalize_degrees(degrees.to_f)
121
+ degrees + minutes.to_f / 60.0 + seconds.to_f / 3600.0
122
+ end
123
+
124
+ # convert degrees as float to coefficient of pi as rational
125
+ def self.degrees_to_coefficient(degrees)
126
+ Angle.radians_to_coefficient(Angle.degrees_to_radians(degrees))
127
+ end
128
+
129
+ # convert coefficient of pi as rational to degrees as float
130
+ def self.coefficient_to_degrees(coefficient)
131
+ Angle.normalize_degrees(coefficient.to_f * 180.0)
132
+ end
133
+
134
+ # convert radians as float to coefficient of pi as rational
135
+ def self.radians_to_coefficient(radians)
136
+ (radians.to_f / @@PI).to_r
137
+ end
138
+
139
+ # convert coefficient of pi as rational to radians as float
140
+ def self.coefficient_to_radians(coefficient)
141
+ Angle.normalize_radians(coefficient.to_f * @@PI)
142
+ end
143
+
144
+ # trig functions
145
+
146
+ def sin
147
+ sin = Math.sin(self.radians).round(@@ROUND_TRIG)
148
+ (sin == 0) ? 0 : sin
149
+ end
150
+
151
+ alias sine sin
152
+ alias jiba sin
153
+
154
+ def cos
155
+ cos = Math.cos(self.radians).round(@@ROUND_TRIG)
156
+ (cos == 0) ? 0 : cos
157
+ end
158
+
159
+ alias cosine cos
160
+
161
+ def tan
162
+ return nil if self.radians == @@PI / 2 or self.radians == 3 * @@PI / 2
163
+
164
+ tan = Math.tan(self.radians).round(@@ROUND_TRIG)
165
+ (tan == 0) ? 0 : tan
166
+ end
167
+
168
+ alias tangent tan
169
+ alias slope tan
170
+
171
+ def csc
172
+ return nil if self.radians == 0 or self.radians == @@PI
173
+
174
+ 1 / self.sin
175
+ end
176
+
177
+ alias cosecant csc
178
+
179
+ def sec
180
+ return nil if self.radians == @@PI / 2
181
+
182
+ 1 / self.cos
183
+ end
184
+
185
+ alias secant sec
186
+
187
+ def cot
188
+ return nil if self.radians == 0 or self.radians == @@PI
189
+ return 0 if self.radians == @@PI / 2
190
+
191
+ 1 / self.tan
192
+ end
193
+
194
+ alias cotangent cot
195
+
196
+ def crd
197
+ 2 * (self / 2).sin
198
+ end
199
+
200
+ alias chord crd
201
+
202
+ def versin
203
+ 1 - self.cos
204
+ end
205
+
206
+ def vercosin
207
+ 1 + self.cos
208
+ end
209
+
210
+ def coversin
211
+ 1 - self.sin
212
+ end
213
+
214
+ def covercosin
215
+ 1 + self.sin
216
+ end
217
+
218
+ def haversin
219
+ self.versin / 2
220
+ end
221
+
222
+ def havercosin
223
+ self.vercosin / 2
224
+ end
225
+
226
+ def hacoversin
227
+ self.coversin / 2
228
+ end
229
+
230
+ def hacovercosin
231
+ self.covercosin / 2
232
+ end
233
+
234
+ def exsec
235
+ self.sec - 1
236
+ end
237
+
238
+ def exsecant
239
+ self.exsec
240
+ end
241
+
242
+ def excsc
243
+ self.csc - 1
244
+ end
245
+
246
+ # inverse trig functions
247
+
248
+ def self.asin(x)
249
+ Angle.new.from_radians(Math.asin(x))
250
+ end
251
+
252
+ def self.acos(x)
253
+ Angle.new.from_radians(Math.acos(x))
254
+ end
255
+
256
+ def self.atan(x)
257
+ Angle.new.from_radians(Math.atan(x))
258
+ end
259
+
260
+ def self.asec(x)
261
+ return nil if x == 0
262
+
263
+ acos(1 / x)
264
+ end
265
+
266
+ def self.acsc(x)
267
+ return nil if x == 0
268
+
269
+ asin(1 / x)
270
+ end
271
+
272
+ def self.acot(x)
273
+ degrees(90) - atan(x)
274
+ end
275
+
276
+ def self.atan2(y, x)
277
+ Angle.new.from_radians(Math.atan2(y, x))
278
+ end
279
+
280
+ # trigonometric properties of angle
281
+
282
+ def acute?
283
+ self.degrees < 90
284
+ end
285
+
286
+ def right?
287
+ self.degrees == 90
288
+ end
289
+
290
+ def obtuse?
291
+ d = self.degress
292
+ d > 90 and d < 180
293
+ end
294
+
295
+ def straight?
296
+ self.degrees == 180
297
+ end
298
+
299
+ def reflex?
300
+ d = self.degrees
301
+ d > 180 and d < 360
302
+ end
303
+
304
+ def full?
305
+ self.degrees == 0
306
+ end
307
+
308
+ def oblique?
309
+ not [0, 90, 180, 270].include? self.degrees
310
+ end
311
+
312
+ # output and type conversions
313
+
314
+ def to_s_deg
315
+ case @display
316
+ when :readable
317
+ degrees = Angle.radians_to_degrees(self.radians.round(10))
318
+ degrees, minutes, seconds = Angle.degrees_to_sexagesimal(degrees)
319
+ seconds = seconds.round(@@SECONDS_DECIMAL_PLACES)
320
+
321
+ output = ''
322
+ output += (@angle < 0 ? '-' : '')
323
+ output += "#{degrees}" + @@DEGREE_SYMBOL
324
+
325
+ if minutes > 0 or seconds > 0
326
+ output += "%02.0f" % minutes
327
+ output += "\'"
328
+
329
+ if seconds > 0
330
+ seconds, remainder = seconds.modf
331
+ remainder = remainder.round(@@SECONDS_DECIMAL_PLACES)
332
+
333
+ if remainder >= 1
334
+ seconds += Integer(remainder).to_f
335
+ remainder -= Integer(remainder).to_f
336
+ end
337
+
338
+ output += "%02.0f" % seconds
339
+
340
+ if not (remainder == 0 or (remainder.abs < (10.0 ** -@@SECONDS_DECIMAL_PLACES)))
341
+ output += ("#{remainder.round(@@SECONDS_DECIMAL_PLACES)}"[1..-1])
342
+ end
343
+
344
+ output += "\""
345
+ end
346
+ end
347
+
348
+ return output
349
+ when :decimal
350
+ return Angle.radians_to_degrees(self.radians).to_s
351
+ else
352
+ return Angle.radians_to_degrees(self.radians).to_s
353
+ end
354
+ end
355
+
356
+ def to_s_rad
357
+ case @display
358
+ when :readable
359
+ coefficient = Angle.radians_to_coefficient(self.radians.round(10))
360
+
361
+ return '0' if coefficient.numerator == 0
362
+
363
+ output = ''
364
+ output += '-' if @angle < 0
365
+ output += "#{coefficient.numerator}" if coefficient.numerator.abs != 1
366
+ output += @@PI_SYMBOL
367
+ output += "/#{coefficient.denominator}" if coefficient.denominator.abs != 1
368
+
369
+ return output
370
+ when :decimal
371
+ self.radians.to_f.to_s
372
+ else
373
+ self.radians.to_f.to_s
374
+ end
375
+ end
376
+
377
+ def to_s
378
+ case @mode
379
+ when :degrees
380
+ return to_s_deg
381
+ when :radians
382
+ return to_s_rad
383
+ else
384
+ return to_s_deg
385
+ end
386
+ end
387
+
388
+ def to_f
389
+ case @mode
390
+ when :degrees
391
+ return Angle.radians_to_degrees(self.radians).round(12)
392
+ when :radians
393
+ return self.radians
394
+ else
395
+ return Angle.radians_to_degrees self.radians
396
+ end
397
+ end
398
+
399
+ def to_r
400
+ Angle.radians_to_coefficient(self.radians) / 2
401
+ end
402
+
403
+ def to_degrees
404
+ Angle.new(Angle.radians_to_degrees(self.radians), mode=:degrees, display=@display)
405
+ end
406
+
407
+ def to_radians
408
+ Angle.new(self.radians, mode=:radians, display=@display)
409
+ end
410
+
411
+ def abs
412
+ new_angle = self.clone
413
+ new_angle.from_radians new_angle.angle.abs
414
+ new_angle
415
+ end
416
+
417
+ def abs!
418
+ @angle = @angle.abs
419
+ end
420
+
421
+ # operator overloads
422
+
423
+ def +(other_angle)
424
+ new_angle = self.clone
425
+ new_angle.from_radians(Angle.normalize_radians(new_angle.angle + other_angle.angle))
426
+ new_angle
427
+ end
428
+
429
+ def -(other_angle)
430
+ new_angle = self.clone
431
+ new_angle.from_radians(Angle.normalize_radians(new_angle.angle - other_angle.angle))
432
+ new_angle
433
+ end
434
+
435
+ def *(number)
436
+ new_angle = self.clone
437
+ new_angle.from_radians(Angle.normalize_radians(new_angle.angle * number))
438
+ new_angle
439
+ end
440
+
441
+ def /(number)
442
+ new_angle = self.clone
443
+ new_angle.from_radians(Angle.normalize_radians(new_angle.angle / number))
444
+ new_angle
445
+ end
446
+ end
447
+
448
+ def degrees(degrees)
449
+ Angle.new degrees, mode=:degrees
450
+ end
451
+
452
+ def sexagesimal(degrees, minutes, seconds)
453
+ Angle.new(Angle.sexagesimal_to_degrees(degrees, minutes, seconds), mode=:degrees)
454
+ end
455
+
456
+ def radians(radians)
457
+ Angle.new radians, mode=:radians
458
+ end
@@ -0,0 +1,3 @@
1
+ module Angles
2
+ VERSION = "0.0.2"
3
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: angles
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gregory H. Halverson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-03-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.7'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.7'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '10.0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '10.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: ratapprox
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Encapsulates angles in Ruby. Easily switch between degrees and radians.
63
+ Output in human-readable format. Built-in trig functions. Automatically normalize
64
+ angles.
65
+ email:
66
+ - gregory.halverson@gmail.com
67
+ executables: []
68
+ extensions: []
69
+ extra_rdoc_files: []
70
+ files:
71
+ - .gitignore
72
+ - .idea/angles.iml
73
+ - .idea/encodings.xml
74
+ - .idea/misc.xml
75
+ - .idea/modules.xml
76
+ - .idea/runConfigurations/gem_install_angles.xml
77
+ - .idea/scopes/scope_settings.xml
78
+ - .idea/vcs.xml
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - angles.gemspec
84
+ - lib/angles.rb
85
+ - lib/angles/version.rb
86
+ homepage: https://github.com/gregory-halverson/angles
87
+ licenses:
88
+ - MIT
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 1.8.28
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: Angle class
111
+ test_files: []