Re: drawing arrows

I wrote a class a little while ago that draws arrows between points
"A" and "B".  I used a VisADLineArray (which may not be the best approach
since I'm always encouraged to use a Gridded2DSet when I think I want to
use a LineArray).

Here's an outline/excerpt of my class VisADArrowArray extends VisADLineArray.


VisADArrowArray arrows = new VisADArrowArray();

// create the stems of the arrows
float[] coords = { x1, y1, z1, x2, y2, z2, ... }
// where the arrows will draw from x1,y1,z1 to x2,y2,z2
// values of x,y should be in terms of row/col of data
// the coords are transformed at the end to be in terms
// of display coords (-1,1).

int numCols;  // number of columns in your flatfield
int numRows;  // number of rows in your flatfield
double magnify; // have you magnified the display?
                //(reset the aspect ratio of projection control?)


// now add the arrow heads
int numCoords = index; // index = coords.length;

// head is a proportionality constant chosen by trial and error
// it describes how long the slants of the arrow heads will be
float head = numCols / 70.0f;

float slope;  // slope of arrows
float theta;  // angle of disp vector
float phi;    // angle of arrow heads
for( int i = 0; i < numCoords; i+=6 ){
        slope = (coords[ i+1 ] - coords[ i+4 ]) /
                (coords[ i ] - coords[ i+3 ] );
        // get disp vector angle
        theta = ( new Float( slope ).isNaN() ?
                (float)Math.toRadians( 90 ) : // straight up and down
                (float)Math.atan( slope ) );
        // orient the arrow head
        phi = ( coords[ i+3 ] > coords[ i ] ?
                (float)Math.toRadians( 150f ) :
                (float)Math.toRadians( 30f ) );
                // the slants of the arrows are at 30 degrees from the stem
                // (this was the most asthetically pleasing to me)

        //
        // right side slant
        //
        // start at top of arrows
        coords[index++] = coords[i+3];
        coords[index++] = coords[i+4];
        coords[index++] = coords[i+5];  // there is no z dim
        // slant away
        coords[index++] = coords[i+3] +
                ( head * (float)Math.cos( theta + phi ) );
        coords[index++] = coords[i+4] +
                ( head * (float)Math.sin( theta + phi ) );
        coords[index++] = coords[i+5];  // there is no z dim
        //
        // left side slant
        //
        // start at top of arrows
        coords[index++] = coords[i+3];
        coords[index++] = coords[i+4];
        coords[index++] = coords[i+5];  // there is no z dim
        // slant away in opposite direction as above
        coords[index++] = coords[i+3] +
                ( head * (float)Math.cos( theta - phi ) );
        coords[index++] = coords[i+4] +
                ( head * (float)Math.sin( theta - phi ) );
        coords[index++] = coords[i+5];  // there is no z dim
}

// transform coords
// origin of disply (for shape maps) is at the center
// adjust for magnification
for( int i = 0; i < coords.length; i+=3 ){
        coords[i]   = (float)magnify *
                ((float)((2.0 * coords[i] / numCols) - 1.0));
        coords[i+1] = (float)magnify *
                ((float)((2.0 * coords[i+1] / numRows) - 1.0));
        coords[i+2] = coords[i+2];  // there is no z dim
}

arrows.coordinates = coords;
arrows.vertexCount = arrows.coordinates.length / 3;


If you try to use this code and have problems, I'd be happy to help.
Good Luck!

Leah


On Thu, 7 Aug 2003, Bill Hibbard wrote:

> Hi Donna,
>
> With your ScalarMaps of u to Flow1X and v to Flow1Y, try
> experimenting with calls to the setScale() method of the
> FlowControl. See visad/examples/Test28.java for an example.
>
> You can also draw a bunch of lines between points as a
> UnionSet of Gridded2DSets with manifold dimension = 1.
> See visad/examples/Rivers.java for an example.
>
> Good luck,
> Bill
>
> On Thu, 7 Aug 2003, Donna L Gresh wrote:
>
> > Is there a simple way to simply draw a set of arrows from one set of
> > points to another? (my desire is to show the displacement of a set of
> > points)
> >
> > I have set up a FlatField mapping (x,y) ->(u,v), where the (u,v)'s I've
> > computed as the difference between x1,y1 and x2,y2. Thus I'd like to draw
> > lines starting at points x,y with length u,v.
> >
> > I've tried constructing a scalarmap of u to Flow1X and v to Flow1Y, but
> > nothing seems to appear in the display. It may well be that I'm still not
> > doing things exactly as they should be, but is this the right approach?
> >
> >
> >
> > Donna L. Gresh, Ph.D.
> > Optimization and Mathematical Software Group
> > IBM T.J. Watson Research Center
> > (914) 945-2472
> > http://www.research.ibm.com/people/g/donnagresh
> > gresh@xxxxxxxxxx
> >
>


  • 2003 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the visad archives: