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.
- data/.gitignore +14 -0
- data/.idea/angles.iml +63 -0
- data/.idea/encodings.xml +4 -0
- data/.idea/misc.xml +27 -0
- data/.idea/modules.xml +8 -0
- data/.idea/runConfigurations/gem_install_angles.xml +22 -0
- data/.idea/scopes/scope_settings.xml +5 -0
- data/.idea/vcs.xml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +2 -0
- data/angles.gemspec +24 -0
- data/lib/angles.rb +458 -0
- data/lib/angles/version.rb +3 -0
- metadata +111 -0
data/.gitignore
ADDED
data/.idea/angles.iml
ADDED
@@ -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>
|
data/.idea/encodings.xml
ADDED
data/.idea/misc.xml
ADDED
@@ -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>
|
data/.idea/modules.xml
ADDED
@@ -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>
|
data/.idea/vcs.xml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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
|
data/Rakefile
ADDED
data/angles.gemspec
ADDED
@@ -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
|
data/lib/angles.rb
ADDED
@@ -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
|
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: []
|