/** * Compute the {@link Graduations} used to the ruler drawing in auto-ticks mode.. * * @return the used decimal format. */ private DecimalFormat computeUserGraduation() { /* The maximum distance corresponding to the actually displayed sprites. */ double maxSpritesDistance = 0.0; Graduations currentGraduations = rulerModel.getGraduations(); List<Double> ticks = currentGraduations.getNewValues(); DecimalFormat format = currentGraduations.getFormat(); for (double value : ticks) { Texture sprite = computeSprite(value, format); if (sprite != null) { Vector3d windowPosition = canvasProjection.project(rulerModel.getPosition(value)); Vector3d delta = projectCenterToEdge(sprite, windowTicksDelta); spritesList.add( new PositionedSprite(sprite, windowPosition.plus(windowTicksDelta.plus(delta)))); Vector3d farDelta = windowTicksDelta.plus(delta.times(2.0)); maxSpritesDistance = Math.max(maxSpritesDistance, farDelta.getNorm()); } } this.graduations = currentGraduations; this.maximalSpritesDistance = maxSpritesDistance; return format; }
/** * Compute the {@link Graduations} used to the ruler drawing in auto-ticks mode.. * * @return the used decimal format. */ private DecimalFormat computeAutoGraduation() { /* The maximum distance corresponding to the actually displayed sprites. */ double maxSpritesDistance = 0.0; Graduations currentGraduations = rulerModel.getGraduations(); Graduations ticksGraduation = currentGraduations; DecimalFormat format = currentGraduations.getFormat(); boolean canGetMore = true; List<PositionedSprite> newSpritesList = new LinkedList<PositionedSprite>(); while (currentGraduations != null) { /* The maximum distance to any of the sprites' farthest sides at a given iteration. */ double currentMaximalSpritesDistance = 0; newSpritesList.clear(); List<Double> ticks = currentGraduations.getNewValues(); for (double value : ticks) { Texture sprite = computeSprite(value, format); Vector3d windowPosition = canvasProjection.project(rulerModel.getPosition(value)); Dimension textureSize = computeSpriteDimension(value); Vector3d delta = projectCenterToEdge(textureSize, windowTicksDelta); PositionedSprite newSprite = new PositionedSprite( sprite, textureSize, windowPosition.plus(windowTicksDelta.plus(delta))); newSpritesList.add(newSprite); Vector3d farDelta = windowTicksDelta.plus(delta.times(2.0)); currentMaximalSpritesDistance = Math.max(currentMaximalSpritesDistance, farDelta.getNorm()); } if (collide(newSpritesList, rulerModel.getMargin()) || collide(spritesList, newSpritesList, rulerModel.getMargin())) { currentGraduations = currentGraduations.getAlternative(); canGetMore = false; } else { maxSpritesDistance = Math.max(maxSpritesDistance, currentMaximalSpritesDistance); spritesList.addAll(newSpritesList); ticksGraduation = currentGraduations; if (canGetMore) { currentGraduations = currentGraduations.getMore(); } else { currentGraduations = null; } } } this.graduations = ticksGraduation; this.maximalSpritesDistance = maxSpritesDistance; return format; }
/** * Fill a vertices buffer with the needed data to draw a ruler. * * @param verticesBuffer the {@link ElementsBuffer} to fill. * @param rulerModel the {@link RulerModel} to draw. * @param ticksValue the list of ticks. * @param subTicksValue the list of sub-ticks. * @param canvasProjection the used canvas projection. */ private void fillVertices( ElementsBuffer verticesBuffer, RulerModel rulerModel, List<Double> ticksValue, List<Double> subTicksValue, Transformation canvasProjection) { Vector3d a = rulerModel.getFirstPoint(); Vector3d b = rulerModel.getSecondPoint(); if ((a != null) && (b != null)) { int bufferSize = 2 * ticksValue.size() + 2 * subTicksValue.size(); if (rulerModel.isLineVisible()) { bufferSize += 2; } FloatBuffer data = FloatBuffer.allocate(4 * bufferSize); data.rewind(); for (double value : ticksValue) { Vector3d p = canvasProjection.project(rulerModel.getPosition(value)); data.put(p.getDataAsFloatArray(4)); data.put(p.plus(windowTicksDelta).getDataAsFloatArray(4)); } for (double value : subTicksValue) { Vector3d p = canvasProjection.project(rulerModel.getPosition(value)); data.put(p.getDataAsFloatArray(4)); data.put(p.plus(windowSubTicksDelta).getDataAsFloatArray(4)); } if (rulerModel.isLineVisible()) { data.put(canvasProjection.project(a).getDataAsFloatArray(4)); data.put(canvasProjection.project(b).getDataAsFloatArray(4)); } data.rewind(); verticesBuffer.setData(data, 4); } else { verticesBuffer.setData(new float[0], 4); } }
/** * Compute and return the minimal screen distance between two successive ticks of the given * {@link Graduations}. If the given {@link Graduations} is <code>null</code>, the returned * value is {@link Double#MAX_VALUE}. * * @param graduations the given {@link Graduations}. * @return the minimal screen distance between two successive ticks of the given {@link * Graduations}. */ private double computeTicksDistance(Graduations graduations) { double minimalDistance = Double.MAX_VALUE; if (graduations != null) { Vector3d previousProjection = null; for (double currentValue : graduations.getAllValues()) { Vector3d currentProjection = canvasProjection.project(rulerModel.getPosition(currentValue)); if (previousProjection != null) { minimalDistance = Math.min(minimalDistance, currentProjection.minus(previousProjection).getNorm2()); } previousProjection = currentProjection; } minimalDistance = Math.sqrt(minimalDistance); } return minimalDistance; }