Announcement

Collapse
No announcement yet.

Pyramid/Rigid shape Manipulation

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Pyramid/Rigid shape Manipulation

    I'm trying to use a rotated pyramid to show a camera's "field of view". See screenshot of what I have so far (The blue dot represents the camera's location):

    Click image for larger version

Name:	AS2yX.png
Views:	1
Size:	414.7 KB
ID:	111959

    Here are the definitions of how WorldWind's Rigid Shape API defines the pyramid attributes (http://builds.worldwind.arc.nasa.gov...idShape.html):

    Center Position of shape (Latitude/Longitude)
    north-south axis length: Side 1 (L)
    east-west axis length: Side 2 (W)
    vertical axis length: Height of Pyramid (H)
    Roll: Roll, Rotation about the north-south axis
    Tilt: Pitch, Rotation about the east-west axis
    Heading: Azimuth, rotation about vertical axis
    I've got it working as expected when the camera is looking straight out. I am calculating a center position of the pyramid based on the camera's range.

    I set the heading to 0 degrees, the roll to 90, and set the tilt in degrees to whatever direction I want the camera (and hence the pyramid) to face. This is what I'm showing in the screenshot.

    What I'm struggling with now is how to show the field of view moving up and down as the camera tilts up and down (along with the FOV rotating around the axis). I'm not even sure what sort of geometric equations I need to be looking at for this. I've tried a bunch of guess and check sort of things with the code, but I can't find a pattern to set up a formula for this. My Geometry skills have not been used in a while, so any help is appreciated.

    Here is some sample java code that shows what I am trying to do. The code currently draws the camera's FoV and rotates around the camera. When I try to set the roll to anything other than 90, things go haywire. What I would like is to be able to show the FOV tilting up and down.

    Code:
        public class CameraFOV extends ApplicationTemplate {
        	public static class AppFrame extends ApplicationTemplate.AppFrame {
        		public AppFrame() {
        			this.addCameraAndFOV();
        
        		}
        
        		double direction = 45;
        
        		protected void addCameraAndFOV() {
        			double lat = 40;
        			double lon = -120;
        			final double alt = 20000;
        
        			RenderableLayer layer = new RenderableLayer();
        			layer.setName("Camera");
        
        			final TacticalSymbol symbol = new MilStd2525TacticalSymbol(
        					"SFSP-----------", Position.fromDegrees(lat, lon, alt));
        			TacticalSymbolAttributes tAttrs = new BasicTacticalSymbolAttributes();
        			tAttrs.setScale(.4);
        			symbol.setAttributes(tAttrs);
        			symbol.setValue(AVKey.DISPLAY_NAME, "Camera"); // Tool tip text.
        			symbol.setShowLocation(false);
        			layer.addRenderable(symbol);
        
        			// Add the symbol layer to the World Wind model.
        			this.getWwd().getModel().getLayers().add(layer);
        
        			// Update the layer panel to display the symbol layer.
        			this.getLayerPanel().update(this.getWwd());
        
        			layer = new RenderableLayer();
        			layer.setName("FOV");
        
        			// Create and set an attribute bundle.
        			ShapeAttributes attrs = new BasicShapeAttributes();
        			attrs.setInteriorMaterial(Material.RED);
        			attrs.setInteriorOpacity(0.4);
        			attrs.setEnableLighting(true);
        			attrs.setOutlineMaterial(Material.RED);
        			attrs.setOutlineWidth(2d);
        			attrs.setDrawInterior(true);
        			attrs.setDrawOutline(true);
        
        			final double verticalradius = 50000;
        			final double nsradius = 15000;
        			final double ewradius = 10000;
        
        			LatLon initialFovPosition = Position.greatCircleEndPosition(
        					symbol.getPosition(), Math.toRadians(direction + 90),
        					verticalradius / Earth.WGS84_EQUATORIAL_RADIUS);
        
        			final Pyramid pyramid = new Pyramid(Position.fromDegrees(
        					initialFovPosition.getLatitude().degrees,
        					initialFovPosition.getLongitude().degrees, alt), nsradius,
        					verticalradius, ewradius);
        			pyramid.setAltitudeMode(WorldWind.ABSOLUTE);
        			pyramid.setAttributes(attrs);
        			pyramid.setValue(AVKey.DISPLAY_NAME, "Camera FOV");
        			layer.addRenderable(pyramid);
        
        			Thread rotatingThread = new Thread(new Runnable() {
        
        				@Override
        				public void run() {
        
        					while (true) {
        
        						direction += 5;
        
        						LatLon updatedFovPosition = Position.greatCircleEndPosition(
        								symbol.getPosition(),
        								Math.toRadians(direction + 90), verticalradius
        										/ Earth.WGS84_EQUATORIAL_RADIUS);
        
        						pyramid.setCenterPosition(Position.fromDegrees(
        								updatedFovPosition.getLatitude().degrees,
        								updatedFovPosition.getLongitude().degrees, alt));
        
        						pyramid.setHeading(Angle.fromDegrees(0));
        						pyramid.setRoll(Angle.fromDegrees(90));
        						pyramid.setTilt(Angle.fromDegrees(direction));
        
        						AppFrame.this.getWwd().redraw();
        
        						try {
        							Thread.sleep(2000);
        						} catch (InterruptedException e) {
        							// TODO Auto-generated catch block
        							e.printStackTrace();
        						}
        
        					}
        
        				}
        			});
        
        			rotatingThread.start();
        
        			// Add the layer to the model and update the layer panel.
        			insertBeforePlacenames(getWwd(), layer);
        			this.getLayerPanel().update(this.getWwd());
        		}
        	}
        
        	public static void main(String[] args) {
        		ApplicationTemplate.start("Camera FOV", AppFrame.class);
        	}
        }

  • #2
    Solved issue by overriding RigidShape to re-arrange the order of computeRenderMatrix(DrawContext dc) from:

    // roll
    if (roll != null)
    matrix = matrix.multiply(Matrix.fromRotationY(Ang le.POS360.subtract(this.roll)));
    // tilt
    if (tilt != null)
    matrix = matrix.multiply(Matrix.fromRotationX(Ang le.POS360.subtract(this.tilt)));
    // heading
    if (heading != null)
    matrix = matrix.multiply(Matrix.fromRotationZ(Ang le.POS360.subtract(this.heading)));

    to:

    if (heading != null)
    matrix = matrix.multiply(Matrix.fromRotationZ(Ang le.POS360.subtract(this.heading)));
    // roll
    if (roll != null)
    matrix = matrix.multiply(Matrix.fromRotationY(Ang le.POS360.subtract(this.roll)));
    // tilt
    if (tilt != null)
    matrix = matrix.multiply(Matrix.fromRotationX(Ang le.POS360.subtract(this.tilt)));
    // heading

    Comment


    • #3
      roll then tilt then heading
      sequence changed to:
      heading then roll then tilt

      It's good you got it working and it may help someone else with a similar problem.

      I have not used the roll and pitch defined as you have it here:
      Roll: Roll, Rotation about the north-south axis
      Tilt: Pitch, Rotation about the east-west axis
      Neil
      http://www.nlneilson.com

      Comment


      • #4
        HI graspinggrasper. I am trying to do something which is little bit similar to what you have discussed over here. I have to attach a pyramid to the nose of an aircraft to depict the coverage of its radar. I have tried your code. But I am failed to rotate the pyramid with with the aircraft heading. The apex of the pyramid moves away from the aircraft nose when it takes a turn. Can you please guide me how can I achieve this.

        Comment


        • #5
          Have you tried flipping the heading 180 degrees? Can you provide a screenshot?

          Comment


          • #6
            Hey, tzafar, were you able to do what you were trying to do? I'm trying do something similar. In my case, the pyramid/cone is pointed to earth in the default scenario. If I rotated in the vertical axis (heading) everything stays fine (as expected). However, if I rotate in the another axis, the vertex will appear in a different place, while the centre of the pyramid will be in the same place. I tried to play with an overload RigidShape.computeRenderMatrix and change the rotations or adding a translation there, as well as with the several other functions.
            In the end, the function where I found to be easier to manipulate the position of the object ended up being the RigidShape.drawGeometry function. If I use a glTranslated function here, the pyramid/cone will be affected successfully, so the problem lies with calculating the translation vector. To my despair, this task is turning out to be harder than what I expected. If I try to obtain any vertex data from the ShapeData object, it will be in a relative position. However, if I try to either apply a translation with either a relative or an absolute position, the pyramid will not move in the way I'd like it to move.

            (The way I calculate the absolute translation vector is by knowing the desired place of the vertex and the centroid, calculate the vector between these point, apply the rotations seen in the computeRenderMatrix function, and then calculating the difference between these vectors.)

            Any suggestions?

            Comment

            Working...
            X