All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.gov.nasa.worldwind.symbology.milstd2525.graphics.lines.AdvanceForFeint Maven / Gradle / Ivy

/*
 * Copyright (C) 2012 United States Government as represented by the Administrator of the
 * National Aeronautics and Space Administration.
 * All Rights Reserved.
 */

package gov.nasa.worldwind.symbology.milstd2525.graphics.lines;

import gov.nasa.worldwind.geom.*;
import gov.nasa.worldwind.globes.Globe;
import gov.nasa.worldwind.render.*;
import gov.nasa.worldwind.symbology.milstd2525.graphics.TacGrpSidc;
import gov.nasa.worldwind.util.WWUtil;

import java.util.*;

/**
 * Implementation of the Axis of Advance for Feint graphic (2.X.2.3.3).
 *
 * @author pabercrombie
 * @version $Id: AdvanceForFeint.java 545 2012-04-24 22:29:21Z pabercrombie $
 */
public class AdvanceForFeint extends AbstractAxisArrow
{
    /**
     * Factor used to compute the distance between the solid and dashed lines in the arrow head. A larger value will
     * move the dashed line farther from the solid line.
     */
    protected static final double DASHED_LINE_DISTANCE = 0.2;

    /** Shape attributes for the dashed part of the graphic. */
    protected ShapeAttributes dashedAttributes = new BasicShapeAttributes();

    /**
     * Indicates the graphics supported by this class.
     *
     * @return List of masked SIDC strings that identify graphics that this class supports.
     */
    public static List getSupportedGraphics()
    {
        return Arrays.asList(TacGrpSidc.C2GM_DCPN_AAFF);
    }

    /**
     * Create a new graphic.
     *
     * @param sidc Symbol code the identifies the graphic.
     */
    public AdvanceForFeint(String sidc)
    {
        super(sidc, 2);

        // Path 1 is used to draw the dashed line. This path needs its own shape attributes because it is always drawn
        // dashed.
        this.paths[1].setAttributes(this.dashedAttributes);
    }

    /** {@inheritDoc} Overridden to compute positions for the dashed portion of the arrow head. */
    @Override
    protected double createArrowHeadPositions(List leftPositions, List rightPositions,
        List arrowHeadPositions, Globe globe)
    {
        // This graphic has a double line for the arrowhead, and the outer line is always drawn dashed. Take the
        // arrowhead computed by the super class and create the other line from it.
        double halfWidth = super.createArrowHeadPositions(leftPositions, rightPositions, arrowHeadPositions, globe);

        // The rest of the method assumes that the superclass populates arrowHeadPositions with three positions.
        if (arrowHeadPositions == null || arrowHeadPositions.size() != 3)
            throw new IllegalStateException();

        Iterator positions = this.positions.iterator();
        Position pos1 = positions.next();
        Position pos2 = positions.next();

        Vec4 pt1 = globe.computePointFromPosition(pos1);
        Vec4 pt2 = globe.computePointFromPosition(pos2);

        // Superclass gives us list of {pt N, pt 1, pt N'} where pt N is the corner of the arrow head on one side of the
        // tip and pt N' is the corner on the other side. See superclass documentation for more details.
        Vec4 ptN = globe.computePointFromPosition(arrowHeadPositions.get(0));
        Vec4 ptN_prime = globe.computePointFromPosition(arrowHeadPositions.get(2));

        // Transform pt N and pt N' to find the ends of the dashed line.
        Vec4 dir = ptN.subtract3(ptN_prime).multiply3(DASHED_LINE_DISTANCE);
        ptN = ptN.add3(dir);
        ptN_prime = ptN_prime.subtract3(dir);

        dir = pt1.subtract3(ptN).multiply3(DASHED_LINE_DISTANCE);
        ptN = ptN.add3(dir);

        dir = pt1.subtract3(ptN_prime).multiply3(DASHED_LINE_DISTANCE);
        ptN_prime = ptN_prime.add3(dir);

        List newPositions = Arrays.asList(
            globe.computePositionFromPoint(ptN),
            pos1,
            globe.computePositionFromPoint(ptN_prime));

        this.paths[1].setPositions(new ArrayList(newPositions));

        // Control point 1 specifies the tip of the dashed line, so move the tip of the other arrow toward the body of
        // the graphic.
        double dist = dir.getLength3(); // Shift point the same distance as used above for other points.
        dir = pt2.subtract3(pt1);
        pt1 = pt1.add3(dir.normalize3().multiply3(dist));
        arrowHeadPositions.set(1, globe.computePositionFromPoint(pt1));

        return halfWidth;
    }

    /** Determine active attributes for this frame. */
    @Override
    protected void determineActiveAttributes()
    {
        super.determineActiveAttributes();

        // Copy active attributes to the dashed attribute bundle.
        this.dashedAttributes.copy(this.getActiveShapeAttributes());

        // Re-apply stipple pattern.
        this.dashedAttributes.setOutlineStipplePattern(this.getOutlineStipplePattern());
        this.dashedAttributes.setOutlineStippleFactor(this.getOutlineStippleFactor());
    }

    /** Create labels for the start and end of the path. */
    @Override
    protected void createLabels()
    {
        String text = this.getText();
        if (!WWUtil.isEmpty(text))
            this.addLabel(text);
    }

    /**
     * Determine positions for the start and end labels.
     *
     * @param dc Current draw context.
     */
    @Override
    protected void determineLabelPositions(DrawContext dc)
    {
        if (WWUtil.isEmpty(this.labels))
            return;

        Iterator positions = this.positions.iterator();
        Position pos1 = positions.next();
        Position pos2 = positions.next();

        // Place label 25% of the distance from point 2 to point 1.
        LatLon mid = LatLon.interpolate(0.25, pos2, pos1);

        this.labels.get(0).setPosition(new Position(mid, 0));
        this.labels.get(0).setOrientationPosition(pos1);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy