vector2d 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/vector2d.rb +157 -0
  2. metadata +46 -0
data/lib/vector2d.rb ADDED
@@ -0,0 +1,157 @@
1
+ #--
2
+ # Copyright (c) 2006 Inge Jørgensen <inge@elektronaut.no>
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+
25
+ # Class for for easy handling of two-dimensional coordinates. It's forte is argument flexibility,
26
+ # methods that take vectors accepts arguments in many forms. See Vector2d.new for details and examples.
27
+ class Vector2d
28
+
29
+ # X axis
30
+ attr_accessor :x
31
+ # Y axis
32
+ attr_accessor :y
33
+
34
+
35
+
36
+ # Create a new vector from args. The following examples are equal:
37
+ # Vector2d.new( 150, 100 )
38
+ # Vector2d.new( 150.0, 100.0 )
39
+ # Vector2d.new( "150x100" )
40
+ # Vector2d.new( "150.0x100.0" )
41
+ # Vector2d.new( [150,100} )
42
+ # Vector2d.new( { :x => 150, :y => 100 } )
43
+ # Vector2d.new( { "x" => 150.0, "y" => 100.0 } )
44
+ # Vector2d.new( Vector2d.new( 150, 100 ) )
45
+ def initialize( *args )
46
+ args.flatten!
47
+ if ( args.length == 1 )
48
+ if ( args[0].kind_of?( String ) && args[0].match( /^[\s]*[\d\.]*[\s]*x[\s]*[\d\.]*[\s]*$/ ) )
49
+ args = args[0].split( "x" )
50
+ elsif args[0].kind_of?( Vector2d )
51
+ args = [ args[0].x, args[0].y ]
52
+ elsif args[0].kind_of?( Hash )
53
+ args[0] = args[0][:x] if args[0][:x]
54
+ args[0] = args[0]["x"] if args[0]["x"]
55
+ args[1] = args[0][:y] if args[0][:y]
56
+ args[1] = args[0]["y"] if args[0]["y"]
57
+ else
58
+ args = [ args[0], args[0] ]
59
+ end
60
+ end
61
+ @x, @y = args[0].to_f, args[1].to_f
62
+ end
63
+
64
+
65
+
66
+ # Compare two vectors
67
+ def ==( comp )
68
+ ( comp.x == @x && comp.y == y )
69
+ end
70
+
71
+
72
+
73
+ # Get a String representation of vector.
74
+ # Vector2d.new( 150, 100 ).to_s # "150x100"
75
+ def to_s; "#{@x}x#{@y}"; end
76
+
77
+
78
+
79
+ # Get length of vector.
80
+ def length; Math.sqrt((@x*@x)+(@y*@y)); end
81
+
82
+ # Set new length.
83
+ def length= ( new_length )
84
+ v = self * (new_length/length)
85
+ @x, @y = v.x, v.y
86
+ end
87
+
88
+
89
+
90
+ # Normalize vector (set length to 1.0)
91
+ def normalize; self.dup.normalize!; end
92
+ # In-place form of Vector2d.normalize.
93
+ def normalize!; length = 1.0; self; end
94
+
95
+
96
+ # Round coordinates to nearest integer.
97
+ def round; self.dup.round!; end
98
+ # In-place form of Vector2d.round.
99
+ def round!; @x, @y = @x.round, @y.round; self; end
100
+
101
+
102
+ # Get the aspect ratio of the vector, returns a Float.
103
+ def aspect_ratio; (@x/@y).abs; end
104
+
105
+
106
+
107
+ # Multiply vectors. If args is a single Numeric, both axis will be multiplied.
108
+ def * ( *vector_or_number ); v = Vector2d::new( vector_or_number ); Vector2d.new( @x * v.x, @y * v.y ); end
109
+ # Divide vectors. If args is a single Numeric, both axis will be divided.
110
+ def / ( *vector_or_number ); v = Vector2d::new( vector_or_number ); Vector2d.new( @x / v.x, @y / v.y ); end
111
+ # Add vectors. If args is a single Numeric, it will be added to both axis.
112
+ def + ( *vector_or_number ); v = Vector2d::new( vector_or_number ); Vector2d.new( @x + v.x, @y + v.y ); end
113
+ # Subtract vectors. If args is a single Numeric, it will be subtracted from both axis.
114
+ def - ( *vector_or_number ); v = Vector2d::new( vector_or_number ); Vector2d.new( @x - v.x, @y - v.y ); end
115
+
116
+
117
+
118
+ # Constrain/expand so that both coordinates fit within (the square implied by) another vector.
119
+ # This is useful for resizing images to fit a certain size while keeping aspect ratio.
120
+ #
121
+ # == Examples
122
+ #
123
+ # my_image = Vector2d.new( "320x200" ) # Creates a new vector object
124
+ # my_image.constrain_both( 100 ) # Returns a new vector: x=100, y=63
125
+ # my_image.constrain_both( 150, 50 ) # Returns a new vector: x=80, y=50
126
+ # my_image.constrain_both( "150x50" ) # Equal to constrain_both( 150, 50 )
127
+ # my_image.constrain_both( "x100" ) # Returns a new vector: x=160, y=100
128
+ #
129
+ # == Note
130
+ #
131
+ # Either axis will be disregarded if zero or nil (see the last example). This is a feature, not a bug. ;)
132
+ def constrain_both( *vector_or_number )
133
+ scale = Vector2d::new( vector_or_number ) / self
134
+ ( self * ( (scale.y==0||(scale.x>0&&scale.x<scale.y) ) ? scale.x : scale.y ) )
135
+ end
136
+
137
+
138
+
139
+ # Constrain/expand so that one of the coordinates fit within (the square implied by) another vector.
140
+ #
141
+ # == Example
142
+ #
143
+ # my_image = Vector2d.new( "320x200" ) # Creates a new vector object
144
+ # my_image.constrain_one( 100, 100 ) # Returns a new vector: x=160, y=100
145
+ def constrain_one( *vector_or_number )
146
+ scale = Vector2d::new( vector_or_number ) / self
147
+ if ( scale.x > 0 && scale.y > 0 )
148
+ scale = ( scale.x<scale.y) ? scale.y : scale.x
149
+ self * scale
150
+ else
151
+ constrain_both( args )
152
+ end
153
+ end
154
+
155
+ end #class Vector2d
156
+
157
+
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: vector2d
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.5
7
+ date: 2006-12-10 00:00:00 +01:00
8
+ summary: A simplistic class for handling two-dimensional vectors.
9
+ require_paths:
10
+ - lib
11
+ email: inge@elektronaut.no
12
+ homepage: http://rubyforge.org/projects/vector2d/
13
+ rubyforge_project: vector2d
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - "Inge J\xC3\xB8rgensen"
31
+ files:
32
+ - lib/vector2d.rb
33
+ test_files: []
34
+
35
+ rdoc_options: []
36
+
37
+ extra_rdoc_files: []
38
+
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ requirements: []
44
+
45
+ dependencies: []
46
+