001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.osm.visitor.paint; 003 004import org.openstreetmap.josm.gui.MapViewState.MapViewPoint; 005import org.openstreetmap.josm.gui.draw.MapPath2D; 006import org.openstreetmap.josm.tools.Utils; 007 008/** 009 * This class helps with painting arrows with fixed length along a path. 010 * @author Michael Zangl 011 * @since 10827 012 */ 013public class ArrowPaintHelper { 014 private final double sin; 015 private final double cos; 016 private final double length; 017 018 /** 019 * Creates a new arrow helper. 020 * @param radians The angle of the arrow. 0 means that it lies on the current line. In radians 021 * @param length The length of the arrow lines. 022 */ 023 public ArrowPaintHelper(double radians, double length) { 024 this.sin = Math.sin(radians); 025 this.cos = Math.cos(radians); 026 this.length = length; 027 } 028 029 /** 030 * Paint the arrow 031 * @param path The path to append the arrow to. 032 * @param point The point to paint the tip at 033 * @param fromDirection The direction the line is comming from. 034 */ 035 public void paintArrowAt(MapPath2D path, MapViewPoint point, MapViewPoint fromDirection) { 036 double x = point.getInViewX(); 037 double y = point.getInViewY(); 038 double dx = fromDirection.getInViewX() - x; 039 double dy = fromDirection.getInViewY() - y; 040 double norm = Math.sqrt(dx * dx + dy * dy); 041 if (norm > 1e-10) { 042 dx *= length / norm; 043 dy *= length / norm; 044 path.moveTo(x + dx * cos + dy * sin, y + dx * -sin + dy * cos); 045 if (!Utils.equalsEpsilon(cos, 0)) { 046 path.lineTo(point); 047 } 048 path.lineTo(x + dx * cos + dy * -sin, y + dx * sin + dy * cos); 049 } 050 } 051 052 /** 053 * Gets the length of the arrow along the line segment. 054 * @return the length along the line 055 * @since 12154 056 */ 057 public double getOnLineLength() { 058 return length * cos; 059 } 060}