Vector: Difference between revisions
m (grammar) |
(Add Racket) |
||
Line 46: | Line 46: | ||
In the construction of these numeric constants, <code>ad</code> is followed by an '''a'''ngle in '''d'''egrees while <code>ar</code> is followed by an '''a'''ngle in '''r'''adians. This practice of embedding letters in a numeric constant is analogous to the use of '''e'''xponential notation when describing some floating point numbers. |
In the construction of these numeric constants, <code>ad</code> is followed by an '''a'''ngle in '''d'''egrees while <code>ar</code> is followed by an '''a'''ngle in '''r'''adians. This practice of embedding letters in a numeric constant is analogous to the use of '''e'''xponential notation when describing some floating point numbers. |
||
=={{header|Racket}}== |
|||
{{trans|Python}} |
|||
We store internally only the <code>x, y</code> components and calculate the norm, angle and slope on demand. We have two constructors one with <code>(x,y)</code> and another with <code>(slope, norm)</code>. |
|||
We use <code>fl*</code> and <code>fl/</code> to try to get the most sensible result for vertical vectors. |
|||
<lang Racket>#lang racket |
|||
(require racket/flonum) |
|||
(define (rad->deg x) (fl* 180. (fl/ (exact->inexact x) pi))) |
|||
;Custom printer |
|||
;no shared internal structures |
|||
(define (vec-print v port mode) |
|||
(write-string "Vec:\n" port) |
|||
(write-string (format " -Slope: ~a\n" (vec-slope v)) port) |
|||
(write-string (format " -Angle(deg): ~a\n" (rad->deg (vec-angle v))) port) |
|||
(write-string (format " -Norm: ~a\n" (vec-norm v)) port) |
|||
(write-string (format " -X: ~a\n" (vec-x v)) port) |
|||
(write-string (format " -Y: ~a\n" (vec-y v)) port)) |
|||
(struct vec (x y) |
|||
#:methods gen:custom-write |
|||
[(define write-proc vec-print)]) |
|||
;Alternative constructor |
|||
(define (vec/slope-norm s n) |
|||
(vec (* n (/ 1 (sqrt (+ 1 (sqr s))))) |
|||
(* n (/ s (sqrt (+ 1 (sqr s))))))) |
|||
;Properties |
|||
(define (vec-norm v) |
|||
(sqrt (+ (sqr (vec-x v)) (sqr (vec-y v))))) |
|||
(define (vec-slope v) |
|||
(fl/ (exact->inexact (vec-y v)) (exact->inexact (vec-x v)))) |
|||
(define (vec-angle v) |
|||
(atan (vec-y v) (vec-x v))) |
|||
;Operations |
|||
(define (vec+ v w) |
|||
(vec (+ (vec-x v) (vec-x w)) |
|||
(+ (vec-y v) (vec-y w)))) |
|||
(define (vec- v w) |
|||
(vec (- (vec-x v) (vec-x w)) |
|||
(- (vec-y v) (vec-y w)))) |
|||
(define (vec*e v l) |
|||
(vec (* (vec-x v) l) |
|||
(* (vec-y v) l))) |
|||
(define (vec/e v l) |
|||
(vec (/ (vec-x v) l) |
|||
(/ (vec-y v) l)))</lang> |
|||
'''Tests |
|||
<lang Racket>(vec/slope-norm 1 10) |
|||
(vec/slope-norm 0 10) |
|||
(vec 3 4) |
|||
(vec 0 10) |
|||
(vec 10 0) |
|||
(vec+ (vec/slope-norm 1 10) (vec/slope-norm 1 2)) |
|||
(vec*e (vec/slope-norm 4 5) 2)</lang> |
|||
{{out}} |
|||
<pre>Vec: |
|||
-Slope: 1.0 |
|||
-Angle(deg): 45.0 |
|||
-Norm: 10.0 |
|||
-X: 7.071067811865475 |
|||
-Y: 7.071067811865475 |
|||
Vec: |
|||
-Slope: 0.0 |
|||
-Angle(deg): 0.0 |
|||
-Norm: 10 |
|||
-X: 10 |
|||
-Y: 0 |
|||
Vec: |
|||
-Slope: 1.3333333333333333 |
|||
-Angle(deg): 53.13010235415597 |
|||
-Norm: 5 |
|||
-X: 3 |
|||
-Y: 4 |
|||
Vec: |
|||
-Slope: +inf.0 |
|||
-Angle(deg): 90.0 |
|||
-Norm: 10 |
|||
-X: 0 |
|||
-Y: 10 |
|||
Vec: |
|||
-Slope: 0.0 |
|||
-Angle(deg): 0.0 |
|||
-Norm: 10 |
|||
-X: 10 |
|||
-Y: 0 |
|||
Vec: |
|||
-Slope: 1.0 |
|||
-Angle(deg): 45.0 |
|||
-Norm: 11.999999999999998 |
|||
-X: 8.48528137423857 |
|||
-Y: 8.48528137423857 |
|||
Vec: |
|||
-Slope: 4.0 |
|||
-Angle(deg): 75.96375653207353 |
|||
-Norm: 10.000000000000002 |
|||
-X: 2.42535625036333 |
|||
-Y: 9.70142500145332</pre> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
Revision as of 23:56, 30 March 2015
Implement a Vector class (or a set of functions) that models a Physical Vector. You should implement The four basic operations and a 'pretty print' function. Your Vector may be initialized in any reasonable way.
- Start and end points and direction - Angular coefficient and value (length)
The four operations to be implemented are:
- Vector+Vector addition
- Vector-Vector subtraction
- Vector*scalar multiplication
- Vector/scalar division
J
These are primitive (built in) operations in J:
<lang J> 5 7+2 3 7 10
5 7-2 3
3 4
5 7*11
55 77
5 7%2
2.5 3.5</lang>
A few things here might be worth noting:
J treats a sequences of space separated numbers as a single word, this is analogous to how languages which support a "string" data type support treating strings with spaces in them as single words. Put differently: '5 7' is a sequence of three characters but 5 7 (without the quotes) is a sequence of two numbers.
J uses the percent sign to represent division. This is a visual pun with the "division sign" or "obelus" which has been used to represent the division operation for hundreds of years.
In J, a single number (or single character) is special. It's not a treated as a sequence except in contexts where you explicitly declare it to be one (for example, by prefixing it with a comma). (If it were treated as a sequence the above operations would have been errors, because of the length mis-match.)
It's perhaps also worth noting that J allows you to specify complex numbers using polar coordinates, and complex numbers can be converted to vectors using the special token (+.) - for example:
<lang J> 2ad45 1.41421j1.41421
+. 2ad45
1.41421 1.41421
2ar0.785398
1.41421j1.41421
+. 2ar0.785398
1.41421 1.41421</lang>
In the construction of these numeric constants, ad
is followed by an angle in degrees while ar
is followed by an angle in radians. This practice of embedding letters in a numeric constant is analogous to the use of exponential notation when describing some floating point numbers.
Racket
We store internally only the x, y
components and calculate the norm, angle and slope on demand. We have two constructors one with (x,y)
and another with (slope, norm)
.
We use fl*
and fl/
to try to get the most sensible result for vertical vectors.
<lang Racket>#lang racket
(require racket/flonum)
(define (rad->deg x) (fl* 180. (fl/ (exact->inexact x) pi)))
- Custom printer
- no shared internal structures
(define (vec-print v port mode)
(write-string "Vec:\n" port) (write-string (format " -Slope: ~a\n" (vec-slope v)) port) (write-string (format " -Angle(deg): ~a\n" (rad->deg (vec-angle v))) port) (write-string (format " -Norm: ~a\n" (vec-norm v)) port) (write-string (format " -X: ~a\n" (vec-x v)) port) (write-string (format " -Y: ~a\n" (vec-y v)) port))
(struct vec (x y)
#:methods gen:custom-write [(define write-proc vec-print)])
- Alternative constructor
(define (vec/slope-norm s n)
(vec (* n (/ 1 (sqrt (+ 1 (sqr s))))) (* n (/ s (sqrt (+ 1 (sqr s)))))))
- Properties
(define (vec-norm v)
(sqrt (+ (sqr (vec-x v)) (sqr (vec-y v)))))
(define (vec-slope v)
(fl/ (exact->inexact (vec-y v)) (exact->inexact (vec-x v))))
(define (vec-angle v)
(atan (vec-y v) (vec-x v)))
- Operations
(define (vec+ v w)
(vec (+ (vec-x v) (vec-x w)) (+ (vec-y v) (vec-y w))))
(define (vec- v w)
(vec (- (vec-x v) (vec-x w)) (- (vec-y v) (vec-y w))))
(define (vec*e v l)
(vec (* (vec-x v) l) (* (vec-y v) l)))
(define (vec/e v l)
(vec (/ (vec-x v) l) (/ (vec-y v) l)))</lang>
Tests <lang Racket>(vec/slope-norm 1 10)
(vec/slope-norm 0 10)
(vec 3 4)
(vec 0 10)
(vec 10 0)
(vec+ (vec/slope-norm 1 10) (vec/slope-norm 1 2))
(vec*e (vec/slope-norm 4 5) 2)</lang>
- Output:
Vec: -Slope: 1.0 -Angle(deg): 45.0 -Norm: 10.0 -X: 7.071067811865475 -Y: 7.071067811865475 Vec: -Slope: 0.0 -Angle(deg): 0.0 -Norm: 10 -X: 10 -Y: 0 Vec: -Slope: 1.3333333333333333 -Angle(deg): 53.13010235415597 -Norm: 5 -X: 3 -Y: 4 Vec: -Slope: +inf.0 -Angle(deg): 90.0 -Norm: 10 -X: 0 -Y: 10 Vec: -Slope: 0.0 -Angle(deg): 0.0 -Norm: 10 -X: 10 -Y: 0 Vec: -Slope: 1.0 -Angle(deg): 45.0 -Norm: 11.999999999999998 -X: 8.48528137423857 -Y: 8.48528137423857 Vec: -Slope: 4.0 -Angle(deg): 75.96375653207353 -Norm: 10.000000000000002 -X: 2.42535625036333 -Y: 9.70142500145332
Python
Implements a Vector Class that is initialized with origin, angular coefficient and value.
<lang python>class Vector:
def __init__(self,m,value): self.m = m self.value = value self.angle = math.degrees(math.atan(self.m)) self.x = self.value * math.sin(math.radians(self.angle)) self.y = self.value * math.cos(math.radians(self.angle))
def __add__(self,vector): """ >>> Vector(1,10) + Vector(1,2) Vector: - Angular coefficient: 1.0 - Angle: 45.0 degrees - Value: 12.0 - X component: 8.49 - Y component: 8.49 """ final_x = self.x + vector.x final_y = self.y + vector.y final_value = pytagoras(final_x,final_y) final_m = final_y / final_x return Vector(final_m,final_value)
def __neg__(self): return Vector(self.m,-self.value)
def __sub__(self,vector): return self + (- vector) def __mul__(self,scalar): """ >>> Vector(4,5) * 2 Vector: - Angular coefficient: 4 - Angle: 75.96 degrees - Value: 10 - X component: 9.7 - Y component: 2.43
""" return Vector(self.m,self.value*scalar)
def __div__(self,scalar): return self * (1 / scalar) def __repr__(self): """ Returns a nicely formatted list of the properties of the Vector.
>>> Vector(1,10) Vector: - Angular coefficient: 1 - Angle: 45.0 degrees - Value: 10 - X component: 7.07 - Y component: 7.07 """ return """Vector: - Angular coefficient: {} - Angle: {} degrees - Value: {} - X component: {} - Y component: {}""".format(self.m.__round__(2), self.angle.__round__(2), self.value.__round__(2), self.x.__round__(2), self.y.__round__(2))</lang>