Re: Variable Winds

Hi James,

> I'd like to be able to represent "variable winds" using the
> visad.bom.BarbRendererJ3D and BarbManipulationRendererJ3D classes. I'm
> thinking of the following approach:
> 
> * the user currently interacts with BMR by right clicking & dragging on
> the wind barb. There is no way to indicate a "variable" wind
> * I can attach a KeyboardBehaviorJ3D to the DisplayRenderer, modelled on
> CBMKeyboardBehaviorJ3D
> * I can listen for the "V" key to indicate a variable wind
> * I could then set the Wind Direction of the wind barb to, say,
> Double.NaN (so far so good)
> * then, I'd like to be able to modify BarbRendererJ3D to check for a
> wind direction of NaN (with a non-NaN wind speed), and take special
> action to indicate a variable winds (eg dashed circle instead of the
> continous circle currently done for calm winds)
>   _but_ when I look in BarbRendererJ3D, the dir/spd has already been
> converted to u & v components somewhere along the line (_and_ are
> floats).
> 
> So, my questions are:
> * is my approach sound, and if so, where should I be looking to define a
> "variable wind"
> * if not, what are the alternatives.

Hi James,

This will be tricky. Two approaches:

1. The conversion from polar to Cartesian
flow components is done in ShaodwType.assembleFlow() via a
call to the toReference() method of FlowSphericalCoordinateSystem,
which is instantiated in Display to define the relation between:

  (Flow1Elevation, Flow1Azimuth, Flow1Radial)

and:

  (Flow1X, Flow1Y, Flow1Z)

The toReference() method undoubtedly converts NaN values in
Flow1Azimuth to NaN values for all three of Flow1X, Flow1Y and
Flow1Z. These cause ShaodwType.assembleFlow() to set false values
in the 'boolean[][] range_select' array, which evewntually gets
passed to ShadowBarbRealTupleTypeJ3D.staticMakeFlow() and causes
it to not draw any graphics for those NaN values. Note that
visad.bom.ShadowBarbRealTupleTypeJ3D.staticMakeFlow() is called
by the makeFlow() methods of various visad.bom.Shadow* classes.
Note also that ShadowBarbRealTupleTypeJ3D.staticMakeFlow()
calls makeVector() of the DataRenderer to actually draw the
graphics, which for Java3D barbs end up calling
visad.bom.BarbManipulationRendererJ3D.makeVector().

To change this, you need to define new DisplayRealType
instances:

  (Flow1ElevationBOM, Flow1AzimuthBOM, Flow1RadialBOM)

with a DisplayTupleType that uses a new class modified from
FlowSphericalCoordinateSystem to define their relation to:

  (Flow1X, Flow1Y, Flow1Z)

The modifed FlowSphericalCoordinateSystem would convert
Flow1AzimuthBOM = NaN values to perhaps Flow1X = NaN and
Flow1Y = Flow1RadialBOM. Then you could modify
ShadowBarbRealTupleTypeJ3D.staticMakeFlow() to detect those
cases of range_select[0][i] == false where Flow1X = NaN and
Flow1Y != NaN, and render them using a modifed
ShadowBarbRealTupleTypeJ3D.staticMakeFlow() that renders them
as your circles using the Flow1RadialBOM (speed) information
encoded in Flow1Y.

This is a real hack.

2. An alternative is for your application to note where it wants
variable winds. It could set those wind components to NaN to
disable the usual barb rendering, and then create new Data with
a MathType something like:

  (x, y, aux_speed)

with the ScalarMaps:

  x -> XAxis
  y -> YAxis
  aux_speed -> Shape

and just create an array of shapes for the variable circles for
various speed values.

Cheers,
Bill
----------------------------------------------------------
Bill Hibbard, SSEC, 1225 W. Dayton St., Madison, WI  53706
hibbard@xxxxxxxxxxxxxxxxx  608-263-4427  fax: 608-263-6738
http://www.ssec.wisc.edu/~billh/vis.html