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

edu.mines.jtk.mosaic.PointsView Maven / Gradle / Ivy

There is a newer version: 1.1.0
Show newest version
/****************************************************************************
Copyright 2005, Colorado School of Mines and others.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
****************************************************************************/
package edu.mines.jtk.mosaic;

import java.awt.*;
import java.util.ArrayList;

import edu.mines.jtk.dsp.Sampling;
import edu.mines.jtk.util.Check;
import static edu.mines.jtk.util.ArrayMath.*;

/**
 * A view of points (x1,x2) with marks at points and/or lines between them.
 * Points (x1,x2) may be specified as arrays x1 and x2 of coordinates. Each 
 * pair of arrays x1 and x2 corresponds to one plot segment. Multiple plot 
 * segments may be specified by arrays of arrays of x1 and x2 coordinates.
 * 

* For each point (x1,x2), a mark with a specified style, size, and color * may be painted. Between each consecutive pair of points (x1,x2) within * a plot segment, lines with specified style, width, and color may be * painted. *

* For example, to view sampled functions x2 = sin(x1) and x2 = cos(x1), * one might construct two plot segments by specifying an array of two * arrays of x1 coordinates and a corresponding array of two arrays of * x2 coordinates. *

* Note that mark and line attributes are constant for each points view. * These attributes do not vary among plot segments. To paint marks and * lines with different attributes, construct multiple views. * @author Dave Hale, Colorado School of Mines * @version 2005.12.28 */ public class PointsView extends TiledView { /** * Orientation of axes x1 and x2. For example, the default orientation * X1RIGHT_X2UP corresponds to x1 increasing horizontally from left to * right, and x2 increasing vertically from bottom to top. */ public enum Orientation { X1RIGHT_X2UP, X1DOWN_X2RIGHT } /** * The style of mark plotted at points (x1,x2). * The default mark style is none. */ public enum Mark { NONE, POINT, PLUS, CROSS, ASTERISK, HOLLOW_CIRCLE, HOLLOW_SQUARE, FILLED_CIRCLE, FILLED_SQUARE, } /** * The style of line plotted between consecutive points (x1,x2). * The default line style is solid. */ public enum Line { NONE, SOLID, DASH, DOT, DASH_DOT, } /** * Constructs a view of points (x1,x2) with specified x2 coordinates. * The corresponding coordinates x1 are assumed to be 0, 1, 2, .... * @param x2 array of x2 coordinates. */ public PointsView(float[] x2) { float[] x1 = rampfloat(0.0f,1.0f,x2.length); set(x1,x2); } /** * Constructs a view of points (x1,x2) for a sampled function x2(x1). * @param s1 the sampling of x1 coordinates. * @param x2 array of x2 coordinates. */ public PointsView(Sampling s1, float[] x2) { set(s1,x2); } /** * Constructs a view of points (x1,x2) with a single plot segment. * The lengths of the specified arrays x1 and x2 must be equal. * @param x1 array of x1 coordinates. * @param x2 array of x2 coordinates. */ public PointsView(float[] x1, float[] x2) { set(x1,x2); } /** * Constructs a view of points (x1,x2) with multiple plot segments. * The lengths of the specified arrays x1 and x2 must be equal. * @param x1 array of arrays of x1 coordinates. * @param x2 array of arrays of x2 coordinates. */ public PointsView(float[][] x1, float[][] x2) { set(x1,x2); } /** * Constructs a view of points (x1,x2,x3) with a single plot segment. * The lengths of the specified arrays x1 and x2 must be equal. * If x3 is not null, its length must equal that of x1 and x2. * @param x1 array of x1 coordinates. * @param x2 array of x2 coordinates. * @param x3 array of x3 coordinates; null, if none. */ public PointsView(float[] x1, float[] x2, float[] x3) { set(x1,x2,x3); } /** * Constructs a view of points (x1,x2,x3) with multiple plot segments. * The lengths of the specified arrays x1 and x2 must be equal. * If x3 is not null, its length must equal that of x1 and x2. * @param x1 array of arrays of x1 coordinates. * @param x2 array of arrays of x2 coordinates. * @param x3 array of arrays of x3 coordinates. */ public PointsView(float[][] x1, float[][] x2, float[][] x3) { set(x1,x2,x3); } /** * Sets (x1,x2) coordinates for a sampled function x2(x1). * @param s1 the sampling of x1 coordinates. * @param x2 array of x2 coordinates. */ public void set(Sampling s1, float[] x2) { Check.argument(s1.getCount()==x2.length,"s1 count equals x2 length"); int n1 = x2.length; float[] x1 = new float[n1]; for (int i1=0; i1 * To specify a color, the style string may contain one of "r" for red, * "g" for green, "b" for blue, "c" for cyan, "m" for magenta, "y" for * yellow, "k" for black, or "w" for white. If the style string contains * none of these colors, then the default color is used. *

* To specify a line style, the style string may contain one of "-" for * solid lines, "--" for dashed lines, "-." for dotted lines, or "--." * for dash-dotted lines. If the style string contains none of these * line styles, then no lines are painted. *

* To specify a mark style, the style string may contain one of "." for * point, "+" for plus, "x" for cross, "o" for hollow circle", "O" for * filled circle, "s" for hollow square, or "S" for filled square. If * the style string contains none of these mark styles, then no marks * are painted. * @param style the style string. */ public void setStyle(String style) { // Color. if (style.contains("r")) { setLineColor(Color.RED); setMarkColor(Color.RED); } else if (style.contains("g")) { setLineColor(Color.GREEN); setMarkColor(Color.GREEN); } else if (style.contains("b")) { setLineColor(Color.BLUE); setMarkColor(Color.BLUE); } else if (style.contains("c")) { setLineColor(Color.CYAN); setMarkColor(Color.CYAN); } else if (style.contains("m")) { setLineColor(Color.MAGENTA); setMarkColor(Color.MAGENTA); } else if (style.contains("y")) { setLineColor(Color.YELLOW); setMarkColor(Color.YELLOW); } else if (style.contains("k")) { setLineColor(Color.BLACK); setMarkColor(Color.BLACK); } else if (style.contains("w")) { setLineColor(Color.WHITE); setMarkColor(Color.WHITE); } else { setLineColor(null); setMarkColor(null); } // Line style. if (style.contains("--.")) { setLineStyle(Line.DASH_DOT); } else if (style.contains("--")) { setLineStyle(Line.DASH); } else if (style.contains("-.")) { setLineStyle(Line.DOT); } else if (style.contains("-")) { setLineStyle(Line.SOLID); } else { setLineStyle(Line.NONE); } // Mark style. if (style.contains("+")) { setMarkStyle(Mark.PLUS); } else if (style.contains("x")) { setMarkStyle(Mark.CROSS); } else if (style.contains("o")) { setMarkStyle(Mark.HOLLOW_CIRCLE); } else if (style.contains("O")) { setMarkStyle(Mark.FILLED_CIRCLE); } else if (style.contains("s")) { setMarkStyle(Mark.HOLLOW_SQUARE); } else if (style.contains("S")) { setMarkStyle(Mark.FILLED_SQUARE); } else if (style.contains(".")) { int i = style.indexOf("."); if (i==0 || style.charAt(i-1)!='-') setMarkStyle(Mark.POINT); } else { setMarkStyle(Mark.NONE); } } /** * Sets the line style. * The default style is solid. * @param style the line style. */ public void setLineStyle(Line style) { _lineStyle = style; repaint(); } /** * Sets the line width. * The default width is zero, for the thinnest lines. * @param width the line width. */ public void setLineWidth(float width) { if (_lineWidth!=width) { _lineWidth = width; updateBestProjectors(); repaint(); } } /** * Sets the line color. * The default line color is the tile foreground color. * That default is used if the specified line color is null. * @param color the line color; null, for tile foreground color. */ public void setLineColor(Color color) { if (!equalColors(_lineColor,color)) { _lineColor = color; repaint(); } } /** * Sets the mark style. * The default mark style is none, for no marks. * @param style the mark style. */ public void setMarkStyle(Mark style) { if (_markStyle!=style) { _markStyle = style; updateBestProjectors(); repaint(); } } /** * Sets the mark size. * The default mark size is half the tile font size. * The default is used if the specified mark size is zero. * @param size the mark size. */ public void setMarkSize(float size) { if (_markSize!=size) { _markSize = size; updateBestProjectors(); repaint(); } } /** * Sets the mark color. * The default mark color is the tile foreground color. * That default is used if the specified mark color is null. * @param color the mark color. */ public void setMarkColor(Color color) { if (!equalColors(_markColor,color)) { _markColor = color; repaint(); } } /** * Sets the format used for text labels. * The default format is "%1.4G". * @param format the text format. */ public void setTextFormat(String format) { _textFormat = format; repaint(); } public void paint(Graphics2D g2d) { g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Projector hp = getHorizontalProjector(); Projector vp = getVerticalProjector(); Transcaler ts = getTranscaler(); // Font size and line width from graphics context. float fontSize = g2d.getFont().getSize2D(); float lineWidth = 1.0f; Stroke stroke = g2d.getStroke(); if (stroke instanceof BasicStroke) { BasicStroke bs = (BasicStroke)stroke; lineWidth = bs.getLineWidth(); } // Graphics context for lines. Graphics2D gline = null; if (_lineStyle!=Line.NONE) { gline = (Graphics2D)g2d.create(); float width = lineWidth; if (_lineWidth!=0.0f) width *= _lineWidth; float[] dash = null; if (_lineStyle!=Line.SOLID) { float dotLength = 0.5f*width; float dashLength = 2.0f*width; float gapLength = 2.0f*dotLength+dashLength; if (_lineStyle==Line.DASH) { dash = new float[]{dashLength,gapLength}; } else if (_lineStyle==Line.DOT) { dash = new float[]{dotLength,gapLength}; } else if (_lineStyle==Line.DASH_DOT) { dash = new float[]{dashLength,gapLength,dotLength,gapLength}; } } BasicStroke bs; if (dash!=null) { int cap = BasicStroke.CAP_ROUND; int join = BasicStroke.JOIN_ROUND; float miter = 10.0f; float phase = 0.0f; bs = new BasicStroke(width,cap,join,miter,dash,phase); } else { bs = new BasicStroke(width); } gline.setStroke(bs); if (_lineColor!=null) gline.setColor(_lineColor); } // Graphics context for marks. Graphics2D gmark = null; int markSize = round(fontSize/2.0f); if (_markStyle!=Mark.NONE) { gmark = (Graphics2D)g2d.create(); if (_markSize>=0.0f) markSize = round(_markSize*lineWidth); if (_markColor!=null) gmark.setColor(_markColor); float width = lineWidth; if (_lineWidth!=0.0f) width *= _lineWidth; BasicStroke bs = new BasicStroke(width); gmark.setStroke(bs); } // Graphics context for text labels. Graphics2D gtext = null; if (_x3.size()>0) gtext = (Graphics2D)g2d.create(); // Arrays for (x,y) coordinates. int[] x = new int[_nxmax]; int[] y = new int[_nxmax]; // For all plot segments, ... for (int is=0; is<_ns; ++is) { // Compute (x,y) coordinates. int n = _nx.get(is); float[] x1 = _x1.get(is); float[] x2 = _x2.get(is); computeXY(hp,vp,ts,n,x1,x2,x,y); // Draw lines between consecutive points. if (gline!=null) gline.drawPolyline(x,y,n); // Draw marks at points. if (gmark!=null) { if (_markStyle==Mark.POINT) { paintPoint(gmark,n,x,y); } else if (_markStyle==Mark.PLUS) { paintPlus(gmark,markSize,n,x,y); } else if (_markStyle==Mark.CROSS) { paintCross(gmark,markSize,n,x,y); } else if (_markStyle==Mark.FILLED_CIRCLE) { paintFilledCircle(gmark,markSize,n,x,y); } else if (_markStyle==Mark.HOLLOW_CIRCLE) { paintHollowCircle(gmark,markSize,n,x,y); } else if (_markStyle==Mark.FILLED_SQUARE) { paintFilledSquare(gmark,markSize,n,x,y); } else if (_markStyle==Mark.HOLLOW_SQUARE) { paintHollowSquare(gmark,markSize,n,x,y); } } // Draw text labels. if (gtext!=null) { float[] z = _x3.get(is); paintLabel(gtext,markSize,n,x,y,z); } } } /////////////////////////////////////////////////////////////////////////// // private int _ns; // number of segments ArrayList _nx = new ArrayList(); // numbers of (x1,x2,x3) ArrayList _x1 = new ArrayList(); // arrays of x1 ArrayList _x2 = new ArrayList(); // arrays of x2 ArrayList _x3 = new ArrayList(); // arrays of x3 int _nxmax; // maximum number of points in a segment private Orientation _orientation = Orientation.X1RIGHT_X2UP; private Line _lineStyle = Line.SOLID; private float _lineWidth = 0.0f; private Color _lineColor = null; private Mark _markStyle = Mark.NONE; private float _markSize = -1.0f; private Color _markColor = null; private String _textFormat = "%1.4G"; /** * Called when we might new realignment. */ private void updateBestProjectors() { // Min and max (x1,x2) values. float x1min = FLT_MAX; float x2min = FLT_MAX; float x1max = -FLT_MAX; float x2max = -FLT_MAX; for (int is=0; is<_ns; ++is) { int nx = _nx.get(is); float[] x1 = _x1.get(is); float[] x2 = _x2.get(is); for (int ix=0; ix1.0f) { u0 = 0.01; u1 = 0.99; } // Best projectors. Projector bhp = null; Projector bvp = null; if (_orientation==Orientation.X1RIGHT_X2UP) { bhp = (x1min





© 2015 - 2024 Weber Informatics LLC | Privacy Policy