Skip to content

Commit c70bf76

Browse files
committed
Add arrow head for direction of movement only
MilStd 2525C states direction of movement is an arrow or staff, but having an arrow differentiates the direction of movement only from a speed leader line.
1 parent 23580f7 commit c70bf76

File tree

3 files changed

+69
-14
lines changed

3 files changed

+69
-14
lines changed

src/gov/nasa/worldwind/symbology/milstd2525/MilStd2525TacticalSymbol.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -519,20 +519,24 @@ protected void layoutDynamicModifiers(DrawContext dc, AVList modifiers, OrderedS
519519
// The length of the direction of movement line is equal to the height of the symbol frame. See
520520
// MIL-STD-2525C section 5.3.4.1.c, page 33.
521521
double length = this.iconRect.getHeight();
522+
Boolean directionOnly = true;
522523
Object d = this.getModifier(SymbologyConstants.SPEED_LEADER_SCALE);
523524
if (d != null && d instanceof Number)
525+
{
526+
directionOnly = false;
524527
length *= ((Number) d).doubleValue();
528+
}
525529

526530
if (this.useGroundHeadingIndicator)
527531
{
528532
List<? extends Point2D> points = MilStd2525Util.computeGroundHeadingIndicatorPoints(dc, osym.placePoint,
529-
(Angle) o, length, this.iconRect.getHeight());
533+
(Angle) o, length, this.iconRect.getHeight(), directionOnly);
530534
this.addLine(dc, Offset.BOTTOM_CENTER, points, LAYOUT_RELATIVE, points.size() - 1, osym);
531535
}
532536
else
533537
{
534538
List<? extends Point2D> points = MilStd2525Util.computeCenterHeadingIndicatorPoints(dc,
535-
osym.placePoint, (Angle) o, length);
539+
osym.placePoint, (Angle) o, length, directionOnly);
536540
this.addLine(dc, Offset.CENTER, points, null, 0, osym);
537541
}
538542
}

src/gov/nasa/worldwind/symbology/milstd2525/MilStd2525Util.java

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import gov.nasa.worldwind.geom.*;
1111
import gov.nasa.worldwind.globes.Globe;
1212
import gov.nasa.worldwind.render.*;
13-
import gov.nasa.worldwind.symbology.SymbologyConstants;
13+
import gov.nasa.worldwind.symbology.*;
1414
import gov.nasa.worldwind.util.Logging;
1515

1616
import java.awt.geom.*;
@@ -65,6 +65,8 @@ public class MilStd2525Util
6565
protected static final Size DIAMOND_SIZE = Size.fromFraction(0.90625, 0.90625);
6666
protected static final Offset DIAMOND_C2_HQ_OFFSET = Offset.fromFraction(0.0, -0.05172);
6767

68+
protected static final Vec4 SCREEN_NORMAL = new Vec4(0.0, 0.0, 1.0, 1.0);
69+
6870
public static class SymbolInfo
6971
{
7072
public Offset iconOffset;
@@ -312,10 +314,11 @@ else if ((bd != null && bd.equalsIgnoreCase(SymbologyConstants.BATTLE_DIMENSION_
312314
* @param heading Direction of movement, as a bearing clockwise from North.
313315
* @param length Length of the indicator line, in pixels.
314316
*
317+
* @param directionOnly A value indicating whether is direction only, or speed leader line.
315318
* @return List of screen points that describe the speed leader line.
316319
*/
317320
public static List<? extends Point2D> computeCenterHeadingIndicatorPoints(DrawContext dc, Vec4 symbolPoint,
318-
Angle heading, double length)
321+
Angle heading, double length, Boolean directionOnly)
319322
{
320323
if (dc == null)
321324
{
@@ -338,9 +341,17 @@ public static List<? extends Point2D> computeCenterHeadingIndicatorPoints(DrawCo
338341
Vec4 pt1 = view.project(symbolPoint);
339342
Vec4 pt2 = view.project(symbolPoint.add3(dir));
340343

341-
return Arrays.asList(
342-
new Point2D.Double(0, 0),
343-
new Point2D.Double(pt2.x - pt1.x, pt2.y - pt1.y));
344+
Vec4 base = new Vec4(0, 0);
345+
Vec4 tip = new Vec4(pt2.x - pt1.x, pt2.y - pt1.y);
346+
347+
ArrayList<Point2D> points = new ArrayList<Point2D>();
348+
points.add(new Point2D.Double(base.x, base.y));
349+
points.add(new Point2D.Double(tip.x, tip.y));
350+
351+
if (directionOnly)
352+
computeArrowHeadPoints(base, tip, points);
353+
354+
return points;
344355
}
345356

346357
/**
@@ -352,11 +363,11 @@ public static List<? extends Point2D> computeCenterHeadingIndicatorPoints(DrawCo
352363
* @param heading Direction of movement, as a bearing clockwise from North.
353364
* @param length Length of the indicator line, in pixels.
354365
* @param frameHeight Height of the symbol's bounding rectangle, in pixels.
355-
*
366+
* @param directionOnly A value indicating whether is direction only, or speed leader line.
356367
* @return List of screen points that describe the speed leader line.
357368
*/
358369
public static List<? extends Point2D> computeGroundHeadingIndicatorPoints(DrawContext dc, Vec4 symbolPoint,
359-
Angle heading, double length, double frameHeight)
370+
Angle heading, double length, double frameHeight, Boolean directionOnly)
360371
{
361372
if (dc == null)
362373
{
@@ -379,10 +390,18 @@ public static List<? extends Point2D> computeGroundHeadingIndicatorPoints(DrawCo
379390
Vec4 pt1 = view.project(symbolPoint);
380391
Vec4 pt2 = view.project(symbolPoint.add3(dir));
381392

382-
return Arrays.asList(
383-
new Point2D.Double(0, 0),
384-
new Point2D.Double(0, -frameHeight / 2d),
385-
new Point2D.Double(pt2.x - pt1.x, -frameHeight / 2d + (pt2.y - pt1.y)));
393+
Vec4 tip = new Vec4(pt2.x - pt1.x, -frameHeight / 2d + (pt2.y - pt1.y));
394+
Vec4 base = new Vec4(0, -frameHeight / 2d);
395+
396+
List<Point2D> points = new ArrayList<Point2D>();
397+
points.add(new Point2D.Double(0, 0));
398+
points.add(new Point2D.Double(base.x, base.y));
399+
points.add(new Point2D.Double(tip.x, tip.y));
400+
401+
if (directionOnly)
402+
computeArrowHeadPoints(base, tip, points);
403+
404+
return points;
386405
}
387406

388407
/**
@@ -412,6 +431,38 @@ protected static Vec4 computeDirectionOfMovement(DrawContext dc, Vec4 symbolPoin
412431
return dir.transformBy3(surfaceOrientation).normalize3().multiply3(length * pixelSize);
413432
}
414433

434+
/**
435+
* Computes the arrow head points for a direction of movement indicator.
436+
*
437+
* @param base The base point of the direction of movement vector.
438+
* @param tip The end point of the direction of movement vector.
439+
* @param points The list of points to add the arrow line points.
440+
*/
441+
private static void computeArrowHeadPoints(Vec4 base, Vec4 tip, List<Point2D> points){
442+
443+
// Vector that is parallel to the direction between the tip to the base of the arrow
444+
Vec4 parallel = base.subtract3(tip);
445+
446+
// Compute perpendicular component
447+
Vec4 perpendicular = SCREEN_NORMAL.cross3(parallel);
448+
449+
double finalArrowLength = 14;
450+
double arrowHalfWidth = finalArrowLength * Angle.fromDegrees(30.0).tanHalfAngle();
451+
452+
perpendicular = perpendicular.normalize3().multiply3(arrowHalfWidth);
453+
parallel = parallel.normalize3().multiply3(finalArrowLength);
454+
455+
// Compute geometry of direction arrow
456+
Vec4 vertex1 = tip.add3(parallel).add3(perpendicular);
457+
Vec4 vertex2 = tip.add3(parallel).subtract3(perpendicular);
458+
459+
// Add the extra points to the list of points to draw the arrow head at the end of
460+
// the direction of movement indicator.
461+
points.add(new Point2D.Double(vertex1.x, vertex1.y));
462+
points.add(new Point2D.Double(vertex2.x, vertex2.y));
463+
points.add(new Point2D.Double(tip.x, tip.y));
464+
}
465+
415466
/**
416467
* Determines a default color to apply to a symbol. MIL-STD-2525C section 5.5.1.1 (pg. 37) states that obstacles
417468
* should be displayed in green, friendly entities in black or blue, and hostile entities in red. This method return

src/gov/nasa/worldwind/symbology/milstd2525/graphics/TacticalGraphicSymbol.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ protected void layoutDynamicModifiers(DrawContext dc, AVList modifiers, OrderedS
350350
double length = this.iconRect.getHeight();
351351

352352
java.util.List<? extends Point2D> points = MilStd2525Util.computeGroundHeadingIndicatorPoints(dc,
353-
osym.placePoint, (Angle) o, length, this.iconRect.getHeight());
353+
osym.placePoint, (Angle) o, length, this.iconRect.getHeight(), true);
354354
this.addLine(dc, BELOW_BOTTOM_CENTER_OFFSET, points, LAYOUT_RELATIVE, points.size() - 1, osym);
355355
}
356356
}

0 commit comments

Comments
 (0)