;+
; NAME:
;       VECTOR__DEFINE
;
; PURPOSE:
;
;       This is an example of a 3D vector class for plotting
;       vector fields.  This object is a subclass of IDLgrModel
;       which contains a polyline object representing a vector
;       provided a given location and magnitude.
;
; AUTHOR:
;       Rick Towler
;       School of Aquatic and Fishery Sciences
;       University of Washington
;       Box 355020
;       Seattle, WA 98195-5020
;       rtow...@u.washington.edu
;       www.acoustics.washington.edu
;
;
; CATEGORY: Object Graphics
;
;
; CALLING SEQUENCE:
;
;       vectorObject = OBJ_NEW('vector')
;
;
; KEYWORDS:
;
;   This object inherits keywords from it's superclass, IDLgrModel, and
;   passes keywords to IDLgrPolyline.
;
;       location:   A 3 element vector defining the X, Y and Z
;                   coordinates of the vector's location.
;
;       magnitude:  A 3 element vector defining the X, Y and Z
;                   magnitude of the vector.
;
;
; METHODS:
;
;       GetProperty:
;
;       SetProperty:
;
;
; DEPENDENCIES: None.
;
; EXAMPLE:
;
;       vecObj = OBJ_NEW('vector', LOCATION=[0,0,0], MAGNITUDE=[3,2,1], $
;           COLOR=[255,0,0], THICK=2.0)
;
;       xobjview, vecObj
;
;
; MODIFICATION HISTORY:
;       Written by: Rick Towler, 8 November 2002.
;
;-


function Vector::Init,  location=location, $
                        magnitude=magnitude, $
                        _ref_extra=extra


    ;  Check the keywords.
    self.location = (N_ELEMENTS(location) eq 0) ? [0,0,0] : location
    self.magnitude = (N_ELEMENTS(magnitude) eq 0) ? [0,0,-1] : magnitude


    ;  Initialize the superclass.
   ; ok = self->IDLgrModel::init(/SELECT­_TARGET, _EXTRA=extra)
  ;  if (not ok) then return, 0


    ;  Define the unit vector vertices.
    vertices = [[-0.1,0.0,-0.85], $
                [0.0,0.0,-1.0], $
                [0.1,0.0,-0.85], $
                [0,0,0]]


    ;  Connect the dots to form our vector
    polylines = [3,0,1,2,2,1,3]


    ;  Create the vector body
    self.oBody = OBJ_NEW('IDLgrPolyline', vertices, POLYLINES=polylines, $
         _EXTRA=extra)


    ;  Add the polyline to self.
    self -> Add, self.oBody


    ;  "Update" the vector to orient/translate/scale it correctly.
    self -> Update


    RETURN, 1


end


pro Vector::Update


    compile_opt idl2


    ;  Reset our transform.
    self -> Reset


    ;  Rotate the vector.
    lvn = TOTAL(self.magnitude^2)
    if (lvn eq 0.) then begin
        ;  Hide the vector if magnitude=0
        self -> SetProperty, /HIDE
        RETURN
    endif
    self -> SetProperty, HIDE=0
    lMag = SQRT(lvn)
    lvector = self.magnitude / lMag


    yaw = 180. + ATAN(lvector[0],lvector[2]) * !RADEG
    pitch = ATAN(lvector[1], SQRT(lvector[2]^2 + lvector[0]^2)) * !RADEG


    self -> Rotate, [1,0,0], pitch
    self -> Rotate, [0,1,0], yaw


    ;  Scale according to magnitude
    self -> Scale, lMag, lMag, lMag


    ;  Move the vector into place.
    self -> Translate, self.location[0], self.location[1], $
        self.location[2]


    RETURN


end


pro Vector::SetProperty,    location=location, $
                            magnitude=magnitude, $
                            _extra=extra


    compile_opt idl2


    update = 0B


    if (N_ELEMENTS(location) eq 3) then begin
        self.location = location
        update = 1B
    endif


    if (N_ELEMENTS(magnitude) eq 3) then begin
        self.magnitude = magnitude
        update = 1B
    endif


    if (update) then self -> Update


    self->IDLgrModel::SetProperty, _EXTRA=extra
    self.oBody->SetProperty, _EXTRA=extra


end


pro Vector::GetProperty,    location=location, $
                            magnitude=magnitude, $
                            _ref_extra=extra


    compile_opt idl2


    location = self.location
    magnitude = self.magnitude


    self->IDLgrModel::GetProperty, _EXTRA=extra
    self.oBody->GetProperty, _EXTRA=extra


end


pro Vector::Cleanup


    compile_opt idl2


    OBJ_DESTROY, self.oBody


    ;  Call our parents cleanup method
    self->IDLgrModel::Cleanup


end


pro Vector__Define


    struct={Vector, $
            inherits IDLgrModel, $
            oBody:OBJ_NEW(), $


            location:FLTARR(3), $
            magnitude:FLTARR(3) $
            }


end

