Buggy code:
public class DirectedPath extends Path { public static final double DEFAULT_ARROW_OFFSET = 0.5 ; public static final double DEFAULT_ARROW_LENGTH = 300 ; public static final Angle DEFAULT_ARROW_ANGLE = Angle . fromDegrees ( 45.0 ) ; public static final double DEFAULT_MAX_SCREEN_SIZE = 20.0 ; protected double arrowOffset = DirectedPath . DEFAULT_ARROW_OFFSET ; protected double arrowLength = DirectedPath . DEFAULT_ARROW_LENGTH ; protected Angle arrowAngle = DirectedPath . DEFAULT_ARROW_ANGLE ; protected double maxScreenSize = DirectedPath . DEFAULT_MAX_SCREEN_SIZE ; public DirectedPath ( ) { } public DirectedPath ( Iterable < ? extends Position > positions ) { } public DirectedPath ( Position . PositionList positions ) { } public DirectedPath ( Position posA , Position posB ) { } public double getArrowOffset ( ) { } public void setArrowOffset ( double arrowOffset ) { } public double getArrowLength ( ) { } public void setArrowLength ( double arrowLength ) { } public double getMaxScreenSize ( ) { } public void setMaxScreenSize ( double maxScreenSize ) { } public Angle getArrowAngle ( ) { } public void setArrowAngle ( Angle arrowAngle ) { } protected static final String ARROWS_KEY = "DirectedPath.DirectionArrows" ; @ Override protected void computePath ( DrawContext dc , List < Position > positions , PathData pathData ) { } protected void computeDirectionArrows ( DrawContext dc , PathData pathData ) { IntBuffer polePositions = pathData . getPolePositions ( ) ; int numPositions = ( polePositions . limit ( ) ) // 2 ; List < Position > tessellatedPositions = pathData . getTessellatedPositions ( ) ; final int FLOATS_PER_ARROWHEAD = 9 ; FloatBuffer buffer = ( ( FloatBuffer ) ( pathData . getValue ( DirectedPath . ARROWS_KEY ) ) ) ; if ( ( buffer == null ) || ( ( buffer . capacity ( ) ) < ( numPositions * FLOATS_PER_ARROWHEAD ) ) ) buffer = Buffers . newDirectFloatBuffer ( ( FLOATS_PER_ARROWHEAD * numPositions ) ) ; pathData . setValue ( DirectedPath . ARROWS_KEY , buffer ) ; buffer . clear ( ) ; Terrain terrain = dc . getTerrain ( ) ; double arrowBase = ( this . getArrowLength ( ) ) * ( this . getArrowAngle ( ) . tanHalfAngle ( ) ) ; int thisPole = ( polePositions . get ( 0 ) ) // 2 ; Position poleA = tessellatedPositions . get ( thisPole ) ; Vec4 polePtA = this . computePoint ( dc , terrain , poleA ) ; for ( int i = 2 ; i < ( polePositions . limit ( ) ) ; i += 2 ) { int nextPole = ( polePositions . get ( i ) ) // 2 ; Position poleB = tessellatedPositions . get ( nextPole ) ; Vec4 polePtB = this . computePoint ( dc , terrain , poleB ) ; <START_BUG> int midPoint = ( ( int ) ( Math . round ( ( ( this . arrowOffset ) * ( thisPole + nextPole ) ) ) ) ) ; <END_BUG> Position posA = tessellatedPositions . get ( midPoint ) ; Position posB = tessellatedPositions . get ( ( midPoint + 1 ) ) ; Vec4 ptA = this . computePoint ( dc , terrain , posA ) ; Vec4 ptB = this . computePoint ( dc , terrain , posB ) ; this . computeArrowheadGeometry ( dc , polePtA , polePtB , ptA , ptB , this . getArrowLength ( ) , arrowBase , buffer , pathData ) ; thisPole = nextPole ; polePtA = polePtB ; } } protected void computeArrowheadGeometry ( DrawContext dc , Vec4 polePtA , Vec4 polePtB , Vec4 ptA , Vec4 ptB , double arrowLength , double arrowBase , FloatBuffer buffer , PathData pathData ) { } protected boolean isArrowheadSmall ( DrawContext dc , Vec4 arrowPt , int numPixels ) { } @ Override protected void doDrawOutline ( DrawContext dc ) { } protected void drawDirectionArrows ( DrawContext dc , PathData pathData ) { } }

Fix:
int midPoint = ( ( int ) ( Math . floor ( ( ( this . arrowOffset ) * ( thisPole + nextPole ) ) ) ) ) ;