📄 gsegment.java
字号:
package no.geosoft.cc.graphics;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;import java.util.List;import no.geosoft.cc.geometry.Box;import no.geosoft.cc.geometry.Geometry;import no.geosoft.cc.geometry.Rect;import no.geosoft.cc.geometry.Region;/** * Class for holding a polyline. <tt>GSegment</tt>s are contained by * <tt>GObjects</tt>. They can have its own rendering style (<tt>GStyle</tt>) * or inherit style from its parent <tt>GObject</tt> if not specified. * <p> * Example usage: * * <pre> * public class Box extends GObject * { * private double x0_, y0_, width_, height_; * private GSegment border_; * * public Box (double x0, double y0, double width, double height) * { * // Store the abstract representation of the box * x0_ = x0; * y0_ = y0; * width_ = width; * height_ = height; * * // Prepare the graphics representation of the box * border_ = new GSegment(); * addSegment (border_); * } * * public void draw() * { * // Complete the graphics representation of the box * double[] xy = new double {x0_, y0_, * x0_ + width_, y0_, * x0_ + width_, y0_ + height_, * x0_, y0_ + height_, * x0_, y0} * border_.setGeometry (xy); * } * } * </pre> * * A typical <tt>GObject</tt> will have many <tt>GSegment</tt>s and * sub-<tt>GObject</tt>s. Some of these can be created in the constructor * while others may need to be created within the draw method as they depend * ont external factors such as zoom etc. * <p> * For efficiency, <b>G</b> does not store world coordinates internally but * converts these to device coordinates in the rendering step. It is * therfore essential that geometry is provided in the <tt>draw()</tt> * method which is called by <b>G</b> on retransformations * (zoom/resize etc.). * * @author <a href="mailto:jacob.dreyer@geosoft.no">Jacob Dreyer</a> */ public class GSegment implements GStyleListener{ private GObject owner_; // Owner private int x_[], y_[]; private GImage vertexImage_; private Rect rectangle_; // Bounding box private Object userData_; // Whatever app assoc with graphics private GStyle style_; // As applied to this object private GStyle actualStyle_; // Adjusted for owner inherits private boolean isVisible_; // Due to position not vis. setting private List texts_; // of GText private Collection components_; // of GComponent private Collection images_; // of GImage /** * Create a GSegment. */ public GSegment() { owner_ = null; x_ = null; y_ = null; rectangle_ = null; texts_ = null; images_ = null; vertexImage_ = null; components_ = null; isVisible_ = false; style_ = null; actualStyle_ = new GStyle(); } /** * Return the owner GObject of this GSegment. If the GSegment has not been * added to a GObject, owner is null. * * @return GObject owner of this GSegment, or null if not attacted to one. */ public GObject getOwner() { return owner_; } /** * Set the owner of this GSegment. * * @param owner New owner of this GSegment. */ void setOwner (GObject owner) { owner_ = owner; updateContext(); } /** * Convenience method to get the scene of the graphics hierarchy of this * GSegment. * * @return Scene of the graphics hierarchy of this GSegment (or null if * it is somehow not attached to a scene). */ GScene getScene() { return owner_ == null ? null : owner_.getScene(); } /** * Set user data of this GSegment. * * @param userData User data of this GSegment. */ public void setUserData (Object userData) { userData_ = userData; } /** * Return user data of this GSegment. * * @return User data of this GSegment. */ public Object getUserData() { return userData_; } /** * Return device X coordinates of this segment. * * @return Device X coordinates of this segment. */ int[] getX() { return x_; } /** * Return device X coordinates of this GSegment. * * @return Device X coordinates of this segment. */ int[] getY() { return y_; } /** * Return number of points in the polyline of this GSegment. * * @return Number of points in this GSegment. May be 0 if the GSegment * is empty. */ int getNPoints() { return x_ == null ? 0 : x_.length; } /** * Return rectangle bounding box of this GSegment. Covers GSegment geometry * only, not associated annotations, images or AWT components. * * @return Rectangle bounding box of the geometry of this GSegment. */ Rect getRectangle() { return rectangle_; } /** * Return region of this GSegment including associated annotations, * images and AWT components. * * @return Region of this GSegment includings its sub components. */ Region getRegion() { Region region = new Region(); // First add geometry part if (rectangle_ != null) region.union (rectangle_); // Add extent of all texts if (texts_ != null) { for (Iterator i = texts_.iterator(); i.hasNext(); ) { GText text = (GText) i.next(); region.union (text.getRectangle()); } } // Add extent of all images if (images_ != null) { for (Iterator i = images_.iterator(); i.hasNext(); ) { GImage image = (GImage) i.next(); region.union (image.getRectangle()); } } // Add extent of all AWT components if (images_ != null) { for (Iterator i = images_.iterator(); i.hasNext(); ) { GComponent component = (GComponent) i.next(); region.union (component.getRectangle()); } } return region; } /** * Return the X center of the geometry of this GSegment. * * @return X center of the geometry of this GSegment. */ int getCenterX() { return rectangle_ == null ? 0 : rectangle_.getCenterX(); } /** * Return the Y center of the geometry of this GSegment. * * @return Y center of the geometry of this GSegment. */ int getCenterY() { return rectangle_ == null ? 0 : rectangle_.getCenterY(); } /** * This method is called in a response to updated geometry, new * parent or new style settings. */ private void updateContext() { isVisible_ = false; // Until otherwise proved // Nothing to update if we are not in the tree if (owner_ == null) return; // Flag owner region as invalid owner_.flagRegionValid (false); // Not more we can do if we're not in the scene if (owner_.getScene() == null) return; // Check if we're outside the scene if (rectangle_ != null) isVisible_ = owner_.getScene().getRegion().isIntersecting (rectangle_); // Update GWindow damage area updateDamage(); // If segment has text, annotation must be updated if (texts_ != null) owner_.getScene().setAnnotationValid (false); // If segment has images, their positions must be updated if (images_ != null) owner_.getScene().computePositions (images_); } /** * Flag the geometry part of this GSegment as damaged. */ void updateDamage() { if (isVisible_ && rectangle_ != null && !rectangle_.isEmpty() && owner_ != null && owner_.getWindow() != null) owner_.getWindow().updateDamageArea (rectangle_); } /** * Compute the rectangle bounding box of this GSegment. */ private void computeRectangle() { // Actual rectangle depends on line width int lineWidth = actualStyle_.getLineWidth() - 1; if (x_ != null) { if (rectangle_ == null) rectangle_ = new Rect(); rectangle_.set (x_, y_); rectangle_.expand (lineWidth + 1, lineWidth + 1); } } /** * Set single point device coordinate geometry. * * @param x X coordinate. * @param y Y coordinate. */ public void setGeometry (int x, int y) { setGeometry (new int[] {x}, new int[] {y}); } /** * Set two point (line) device coordinate geometry. * * @param x0 X coordinate of first end point. * @param y0 Y coordinate of first end point. * @param x1 X coordinate of second end point. * @param y1 Y coordinate of second end point. */ public void setGeometry (int x0, int y0, int x1, int y1) { setGeometry (new int[] {x0, x1}, new int[] {y0, y1}); } /** * Set polyline device coordinate geometry. * * @param x X coordinates. * @param y Y coordinates. */ public void setGeometry (int[] x, int[] y) { // Mark old area as damaged updateDamage(); // Update geometry if (x == null) { x_ = null; y_ = null; rectangle_ = null; } else { int nPoints = x.length; // Reallocate if (x_ == null || x_.length != nPoints) { x_ = new int[nPoints]; y_ = new int[nPoints]; } for (int i = 0; i < nPoints; i++) { x_[i] = x[i]; y_[i] = y[i]; } // Update bounding box computeRectangle(); } updateContext(); } /** * Set polyline device coordinate geometry. * * @param xy Polyline geometry [x,y,x,y,...]. null can be specified * to indicate that the present geometry should be removed. */ public void setGeometry (int[] xy) { // Mark old area as damaged updateDamage(); // Update geometry if (xy == null) { x_ = null; y_ = null; rectangle_ = null; } else { int nPoints = xy.length / 2; // Reallocate if (x_ == null || x_.length != nPoints) { x_ = new int[nPoints]; y_ = new int[nPoints]; } for (int i = 0; i < nPoints; i++) { x_[i] = xy[i*2 + 0]; y_[i] = xy[i*2 + 1]; } // Update bounding box computeRectangle(); } updateContext(); } /** * Set single point world coordinate geometry. * * @param x X coordinate. * @param y Y coordinate. * @param z Z coordinate. */ public void setGeometry (double x, double y, double z) { setGeometry (new double[] {x}, new double[] {y}, new double[] {z}); } /** * Set single point world coordinate geometry. Ignore Z coordinate * (set to 0.0). * * @param x X coordinate. * @param y Y coordinate. */ public void setGeometry (double x, double y) { setGeometry (x, y, 0.0); } /** * Set two point (line) world coordinate geometry. * * @param x0 X coordinate of first end point. * @param y0 Y coordinate of first end point. * @param z0 Z coordinate of first end point. * @param x1 X coordinate of second end point. * @param y1 Y coordinate of second end point. * @param z1 Z coordinate of second end point. */ public void setGeometry (double x0, double y0, double z0, double x1, double y1, double z1) { setGeometry (new double[] {x0, x1}, new double[] {y0, y1}, new double[] {z0, z1}); } /** * Set two point (line) world coordinate geometry. Ignore Z coordinate * (set to 0.0). * * @param x0 X coordinate of first end point. * @param y0 Y coordinate of first end point. * @param x1 X coordinate of second end point. * @param y1 Y coordinate of second end point. */ public void setGeometry (double x0, double y0, double x1, double y1) { setGeometry (new double[] {x0, x1}, new double[] {y0, y1}, new double[] {0.0, 0.0}); } /** * Set polyline world coordinate geometry. * TODO: Look at the implementation * * @param wx X coordinates. * @param wy Y coordinates. * @param wz Z coordinates. May be null if Z is to be ignored. */ public void setGeometry (double x[], double y[], double z[]) { GTransformer transformer = owner_.getScene().getTransformer(); int nPoints = x.length; double[] world = new double[3]; int[] device = new int[2]; int[] devx = new int[nPoints]; int[] devy = new int[nPoints]; for (int i = 0; i < x.length; i++) { world[0] = x[i]; world[1] = y[i]; world[2] = z == null ? 0.0 : z[i]; device = transformer.worldToDevice (world); devx[i] = device[0]; devy[i] = device[1]; } setGeometry (devx, devy); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -