Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
  • 11 commits
  • 53 files changed
  • 0 commit comments
  • 1 contributor
Showing with 2,840 additions and 1,809 deletions.
  1. +0 −182 src/net/samuel/ben/BasicExpressionUI.java
  2. +0 −31 src/net/samuel/ben/ExpressionModel.java
  3. +0 −123 src/net/samuel/ben/ExpressionUI.java
  4. +0 −28 src/net/samuel/ben/FixedReturn.java
  5. +0 −150 src/net/samuel/ben/Group.java
  6. +0 −38 src/net/samuel/ben/Literal.java
  7. +0 −104 src/net/samuel/ben/NibPath.java
  8. +0 −37 src/net/samuel/ben/Node.java
  9. +0 −25 src/net/samuel/ben/NodeEventListener.java
  10. +0 −29 src/net/samuel/ben/NodeStyle.java
  11. +0 −37 src/net/samuel/ben/Operator.java
  12. +0 −111 src/net/samuel/ben/OperatorFromMethod.java
  13. +0 −83 src/net/samuel/ben/Piece.java
  14. +0 −313 src/net/samuel/ben/ReversiblePathFactory.java
  15. +0 −101 src/net/samuel/ben/SegmentPath.java
  16. +0 −180 src/net/samuel/ben/SquigglyPath.java
  17. +0 −39 src/net/samuel/ben/UnsetArg.java
  18. +0 −53 src/net/samuel/ben/UnusedReturn.java
  19. +102 −86 src/quicktests/OnePiece.java
  20. +24 −11 src/quicktests/OnePiece2.java
  21. +296 −0 src/space/Area.java
  22. +61 −0 src/space/Double.java
  23. +62 −0 src/space/Float.java
  24. +30 −0 src/space/Int.java
  25. +8 −0 src/space/Integral.java
  26. +86 −0 src/space/IntegralImpl.java
  27. +24 −0 src/space/Long.java
  28. +20 −0 src/space/Num.java
  29. +111 −0 src/space/NumArray.java
  30. +110 −0 src/space/NumImpl.java
  31. +8 −0 src/space/Rational.java
  32. +54 −0 src/space/RationalImpl.java
  33. +156 −0 src/space/Vector.java
  34. +127 −0 src/space/Zero.java
  35. +22 −0 src/veb/Content.java
  36. +15 −0 src/veb/Drawable.java
  37. +69 −0 src/veb/Elem.java
  38. +172 −0 src/veb/Grid.java
  39. +84 −0 src/veb/Layout.java
  40. +16 −0 src/veb/Surface.java
  41. +16 −0 src/veb/Tree.java
  42. +136 −0 src/veb/swing/BorderDecoration.java
  43. +49 −44 src/{net/samuel/ben → veb/swing}/CompoundPath.java
  44. +51 −0 src/veb/swing/EmptyDecoration.java
  45. +4 −4 src/{net/samuel/ben → veb/swing}/ExprBuildComponent.java
  46. +124 −0 src/veb/swing/ExpressionUI.java
  47. +105 −0 src/veb/swing/NibPath.java
  48. +5 −0 src/veb/swing/Node.java
  49. +320 −0 src/veb/swing/ReversiblePathFactory.java
  50. +106 −0 src/veb/swing/SegmentPath.java
  51. +187 −0 src/veb/swing/SquigglyPath.java
  52. +52 −0 src/veb/swing/SwingDecoration.java
  53. +28 −0 src/veb/swing/SwingSurface.java
View
182 src/net/samuel/ben/BasicExpressionUI.java
@@ -1,182 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
-**/
-
-package net.samuel.ben;
-import java.awt.Font;
-import java.awt.Stroke;
-import java.awt.BasicStroke;
-import java.awt.Paint;
-import java.awt.Color;
-import java.awt.FontMetrics;
-import java.awt.Graphics2D;
-import java.awt.geom.Rectangle2D;
-
-public class BasicExpressionUI extends ExpressionUI {
- public BasicExpressionUI() { }
- public Stroke borderStroke() { return _stroke; }
- public double heteroborderSpace() { return 3.0; }
- public Paint borderPaint() { return Color.black; }
- public Paint areaPaint() { return Color.white; }
- private final static Font _labelFont =
- new Font("Helvetica", Font.PLAIN, 12);
- private final static BasicStroke _stroke = new BasicStroke((float) 0.75);
- public Font labelFont() { return _labelFont; }
- private static final double SQRT2 = Math.sqrt(2.0);
- /**
- * Bounding box for content drawn on a Graphics2D object
- * Includes padding, and for arc-based nodes
- * includes space for arc.
- * Does *not* include space for borders or nibs.
- **/
- public void contentArea(Graphics2D g, Node n, Rectangle2D r) {
- NodeStyle ns = n.getStyle();
- Rectangle2D b = labelFont().getStringBounds(n.getLabel(),
- g.getFontRenderContext());
- /* Strictly, it's an semiellipse. We need the ellipse to be large
- enough that the label + padding doesn't touch any part of it.
- To circumscribe a square with a circle, assume the diameter
- runs corner to corner, cutting the square into two isoceles right
- triangles. By Pythagorean, d = sqrt(2 * s^2), so d = sqrt(2) * s.
- Given that an ellipse is simply a streched circle a similarly
- stretched square will still fit.
- Our semiellipse is just half of an ellipse, but our rectangle is
- also just half of a larger rectangle so we don't need to do
- anything about that.**/
- double ellipsePad = ns == NodeStyle.semicircle_top || ns == NodeStyle.semicircle_bottom
- ? SQRT2 : 1.0;
- r.setRect(b.getX(), b.getY(),
- (b.getWidth() + 2.0) * ellipsePad,
- (b.getHeight() + 2.0) * ellipsePad);
- }
- /**
- * thickness of the border with the senior sibling
- * this is west border width in a LTR UI
- **/
- public double seniorBorderSize(Graphics2D g, Node n, Rectangle2D content)
- {
- switch(n.getStyle()) {
- case squiggly_sides:
- return 2.0 * squigglyAmplitude() + _stroke.getLineWidth();
- case straight_sides:
- return _stroke.getLineWidth();
- case pointy_sides:
- // pointyangle is twice the angle of a right triangle whose
- // opposite side is half our height and whose adjacent is the
- // width we're interested in.
- // tan(pointy/2) = height/2 / return
- return content.getHeight() / 2.0 / Math.tan(pointyAngle());
- case semicircle_top:
- case semicircle_bottom:
- return 0.0;
- }
- throw new AssertionError();
- }
- /**
- * thickness of the border with the junior sibling
- * this is east border width in a LTR UI
- **/
- public double juniorBorderSize(Graphics2D g, Node n, Rectangle2D content)
- {
- return seniorBorderSize(g, n, content);
- }
- /**
- * thickness of the border with the children
- * this is the north border height in a LTR UI
- **/
- public double childrenBorderSize(Graphics2D g, Node n,
- Rectangle2D content)
- {
- switch(n.getStyle()) {
- case squiggly_sides:
- case semicircle_bottom:
- return 2.0 * squigglyAmplitude() + _stroke.getLineWidth();
- case pointy_sides:
- // Check if this is a capture or a recall
- return n.getIns().isEmpty() ? _stroke.getLineWidth() :
- 2.0 * squigglyAmplitude() + _stroke.getLineWidth();
- case semicircle_top:
- return 0.0;
- case straight_sides:
- return _stroke.getLineWidth();
- }
- throw new AssertionError();
- }
- /**
- * thickness of the border with the parent
- * this is the south border height in a LTR UI
- **/
- public double parentBorderSize(Graphics2D g, Node n, Rectangle2D content)
- {
- switch(n.getStyle()) {
- case squiggly_sides:
- case semicircle_top:
- return 2.0 * squigglyAmplitude() + _stroke.getLineWidth();
- case straight_sides:
- case pointy_sides:
- // Check if this is a capture or a recall
- return n.getIns().isEmpty() ? _stroke.getLineWidth() :
- 2.0 * squigglyAmplitude() + _stroke.getLineWidth();
- case semicircle_bottom:
- return 0.0;
- }
- throw new AssertionError();
- }
- /**
- * distance the nib descends
- * this is the height of the north descender area in a LTR UI
- **/
- public double nibDescent() {
- return 12.0;
- }
- /**
- * width of the nib
- * this is the width of the descender itself in a LTR UI
- **/
- public double nibExtent() {
- return 8.0;
- }
- /**
- * minimal spacing between nibs
- * This will probably never matter because a node with any text will be
- * wider than the nib extent.
- * This is padding around the nib. Between two nibs, there will be >= this
- * value * 2, between a nib and a corner, there will be >= this value.
- **/
- public double nibSpacing() {
- return 2.0;
- }
- // This should be small, 2 or 3 pixels. Note the actual border width is
- // twice this.
- public double squigglyAmplitude() { return 2.0; }
- // The squiggles are a rough approximation of a sine wave
- public double squigglyWavelength() { return 32.0; }
- /**
- * Pointy sides are essentially the same as a less-than or greater-than
- * sign. This is the interior angle used to determine the width of the
- * sides column, i.e. width = (height / 2) / tan(pointyAngle / 2)
- * The return value should be in radians.
- **/
- public double pointyAngle() { return Math.toRadians(160); }
- @Override
- public Paint areaPaint(Node n) {
- // TODO Auto-generated method stub
- return null;
- }
-}
View
31 src/net/samuel/ben/ExpressionModel.java
@@ -1,31 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-import java.util.List;
-import java.util.NavigableMap;
-import java.util.TreeMap;
-import javax.swing.tree.MutableTreeNode;
-
-class ExpressionModel {
- //private NavigableMap<String, Object> inputs;
- //private NavigableMap<String, Object> operators;
- private List<Node> elems;
-}
View
123 src/net/samuel/ben/ExpressionUI.java
@@ -1,123 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-import java.awt.Graphics2D;
-import java.awt.Paint;
-import java.awt.Stroke;
-import java.awt.geom.Rectangle2D;
-
-/**
- * Conventions are based on left-to-right:
- * INPUTS (siblings) ^
- * senior ---> junior | children /
- * ____ ____ ____ ____ | descendants
- * | \___/ \___/ \____/ |
- * | |
- * | |
- * | | |
- * |_____________ ______________| | parents /
- * \___/ v ancestors
- * OUTPUT
- */
-
-abstract public class ExpressionUI extends javax.swing.plaf.ComponentUI {
- /**
- * The squiggles are roughly a sine wave, and that's what the amplitude
- * describes.
- * This should be small, 2 or 3 pixels. Note the actual border width is
- * twice this plus the size of the border stroke pen.
- */
- abstract public double squigglyAmplitude();
- /**
- * The squiggles are roughly a sine wave, and that's what the wavelength
- * describes.
- */
- abstract public double squigglyWavelength();
- /**
- * This can be any pen. The pen must have a well defined size to be able
- * to calculate the actual thickness of the border.
- */
- abstract public Stroke borderStroke();
- /**
- * Pointy sides are essentially the same as a less-than or greater-than
- * sign. This is the interior angle used to determine the width of the
- * sides column, i.e. width = (height / 2) / tan(pointyAngle / 2)
- * The return value should be in radians.
- */
- abstract public double pointyAngle();
- /**
- * Space between different borders.
- */
- abstract public double heteroborderSpace();
- /**
- * Paint for border strokes
- */
- abstract public Paint borderPaint();
- /**
- * Paint for piece areas
- */
- abstract public Paint areaPaint(Node n);
- /**
- * Sets bounding box for content drawn on a Graphics2D object
- * Includes padding, and for arc-based nodes
- * includes space for arc.
- * Does *not* include space for borders or nibs.
- */
- abstract public void contentArea(Graphics2D g, Node n, Rectangle2D r);
- /**
- * thickness of the border with the senior sibling
- * this is west border width in a LTR UI
- */
- abstract public double seniorBorderSize(Graphics2D g, Node n, Rectangle2D content);
- /**
- * thickness of the border with the junior sibling
- * this is east border width in a LTR UI
- */
- abstract public double juniorBorderSize(Graphics2D g, Node n, Rectangle2D content);
- /**
- * thickness of the border with the children
- * this is the north border height in a LTR UI
- */
- abstract public double childrenBorderSize(Graphics2D g, Node n, Rectangle2D content);
- /**
- * thickness of the border with the parent
- * this is the south border height in a LTR UI
- */
- abstract public double parentBorderSize(Graphics2D g, Node n, Rectangle2D content);
- /**
- * distance the nib descends into the content area
- * this is the height of the north descender area in a LTR UI
- */
- abstract public double nibDescent();
- /**
- * width of the nib
- * this is the width of the descender itself in a LTR UI
- */
- abstract public double nibExtent();
- /**
- * minimal spacing between nibs
- * This will probably never matter because a node with any text will be
- * wider than the nib extent.
- * This is padding around the nib. Between two nibs, there will be >= this
- * value * 2, between a nib and a corner, there will be >= this value.
- **/
- abstract public double nibSpacing();
-}
View
28 src/net/samuel/ben/FixedReturn.java
@@ -1,28 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-
-abstract class FixedReturn implements Node {
- public NodeStyle getStyle() {
- return NodeStyle.straight_sides;
- }
-}
-
View
150 src/net/samuel/ben/Group.java
@@ -1,150 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-import java.awt.Graphics2D;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.IdentityHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-/** A piecegroup has many pieces in a tree organization.
- * All pieces are assembled into a single unit.
- * Rows alternate border row (which includes the nib descender), content row
- * Columns alternate side column and content column.
- *
- * Like columns may be collapsed.
- * content squiggly squiggly content -> content squiggly content
- **/
-
-public class Group {
- private ExpressionUI eui;
- private ExprBuildComponent ebc;
- private double nibDescent;
- private double nibExtent;
- private double nibSpacing;
- public Group(ExprBuildComponent _ebc) {
- ebc = _ebc;
- eui = _ebc.getUI();
- nibDescent = eui.nibDescent();
- nibExtent = eui.nibExtent();
- nibSpacing = eui.nibSpacing();
- }
-
- /**
- * Set up the grid of nodes
- **/
- private void build_grid(Node root, Graphics2D g) {
- // Make sure it's really the root. The root is often an
- // UnusedReturn.
- while(root.getOut() != null)
- root = root.getOut();
- LinkedList<Node> queue = new LinkedList<Node>();
- queue.offer(root);
- ninf.put(root, new NodeInfo(root, 0, 0));
- List<Node> all = new ArrayList<Node>();
- int maxrow = 0;
- // Do node-widths, row numbers, and parent / older sibling links
- while(!queue.isEmpty()) {
- Node n = queue.remove();
- NodeInfo ni = ninf.get(n);
- int o = 0;
- NodeInfo os = null;
- for(Node child : n.getIns()) {
- queue.offer(child);
- os = ninf.put(child,
- new NodeInfo(child, ni.row + 1, o++, ni, os));
- }
- if(o == 0)
- ni.nwidth = 1; // By default it is 0, and it gets set later...
- else
- maxrow = Math.max(maxrow, ni.row + 1);
- all.add(n);
- }
- gmap = new ArrayList<SortedMap<Integer, NodeInfo>>(maxrow + 1);
- for(int i = maxrow + 1; i > 0; i--) {
- gmap.add(new TreeMap<Integer, NodeInfo>());
- }
- Rectangle2D labelRect = new Rectangle2D.Double();
- // Iterate backwards to hit the leaves first.
- // This makes leaves tell parents how wide they need to be.
- ListIterator<Node> li = all.listIterator(all.size());
- while(li.hasPrevious()) {
- Node x = li.previous();
- NodeInfo xi = ninf.get(x);
- eui.contentArea(g, x, labelRect);
- xi.cont_width = labelRect.getWidth();
- xi.cont_height = labelRect.getHeight();
- Node px = x.getOut();
- if(px == null)
- continue;
- NodeInfo pxi = ninf.get(px);
- pxi.span += xi.span;
- pxi.chld_width += Math.max(xi.chld_width, xi.cont_width);
- }
- // Iterate forwards as a node's column is older sibling + nwidth
- li = all.listIterator(0);
- while(li.hasNext()) {
- Node x = li.next();
- NodeInfo xi = ninf.get(x);
- if(xi.off == 0)
- xi.col = 0;
- else
- xi.col = xi.old_sib.col + xi.old_sib.span;
- gmap.get(xi.row).put(xi.col, xi);
- }
- }
-
- private ArrayList<SortedMap<Integer, NodeInfo>> gmap;
- private IdentityHashMap<Node, NodeInfo> ninf;
- private class NodeInfo {
- public NodeInfo(Node n, int r, int o) {
- node = n;
- row = r;
- off = o;
- parent = null;
- old_sib = null;
- nwidth = 0;
- }
- public NodeInfo(Node n, int r, int o, NodeInfo p, NodeInfo os) {
- node = n;
- row = r;
- off = o;
- parent = p;
- old_sib = os;
- nwidth = 0;
- }
- public Node node;
- public NodeInfo parent;
- public NodeInfo old_sib;
- public int row;
- public int col;
- public int off;
- public int span;
- public double cont_width;
- public double cont_height;
- public double chld_width;
- public int nwidth;
- }
-}
View
38 src/net/samuel/ben/Literal.java
@@ -1,38 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-
-import java.util.List;
-
-abstract class Literal implements Node {
- abstract public List<? extends Node> getIns();
- abstract public Node getOut();
- abstract public String getLabel();
- abstract public Object getValue();
- abstract public Class<?> getType();
- abstract public boolean canAddIns(); // Should this node have an input adder
- abstract public void addIn(Node n);
- abstract public void setIn(int i, Node n);
- abstract public void setOut(Node n);
- public NodeStyle getStyle() {
- return NodeStyle.straight_sides;
- }
-}
View
104 src/net/samuel/ben/NibPath.java
@@ -1,104 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-import java.awt.geom.Rectangle2D;
-
-public class NibPath {
- public static ReversiblePathFactory rpf(Rectangle2D r, int bits)
- {
- return rpf(r.getX(), r.getY(), r.getWidth(), r.getHeight(),
- bits);
- }
- public static ReversiblePathFactory rpf(double x, double y, double w,
- double h, int bits)
- {
- //System.out.println("RPF called with " + x + ", " + y + ", " + w + ", " + h);
- ReversiblePathFactory f = new ReversiblePathFactory();
- /* A nib is roughly an hourglass shape with a rounded
- bottom:
-
- x------------------>x+w
- y1 O O 7
- | ••• | | •••
- | •••| |•••
- | 2 6
- | •| |•
- | O • | | • O
- | | • O O • |
- | |• •|
- | 3 5
- | |•••• ••••|
- V | •••• •••• |
- y+h O O----4----O O
-
- The control points are all just vertical, except for
- control points on point 4 which are horizontal
- Points 2, 3, 5 and 6 can be moved. Any control points
- must be within the area to avoid twists.
-
- We can get nice nib variation by just moving points
- within a square area. We have 32 bits for 4 points,
- so 4 bits of variance per dimension per point..
-
- Point Area
- 1 0.0, 0.0 : 0.0, 0.0
- cp -0.1,-0.1 : 0.1, 0.1
- 2 0.1, 0.2 : 0.4, 0.4
- cp 0.0 -0.2 0.0 +0.2
- 3 0.0, 0.6 : 0.3, 0.9
- cp 0.0 -0.2 0.0 +0.2
- 4 0.5, 1.0 : 0.5, 1.0
- cp -0.3 0.0 +0.3 0.0
- 5 0.7, 0.6 : 1.0, 0.9
- cp 0.0 +0.3 0.0 -0.3
- 6 0.6, 0.2 : 0.9, 0.4
- cp 0.0 +0.2 0.0 -0.2
- 7 1.0, 0.0 : 1.0, 0.0
- */
- f.appendTriplet(x, y, x, y, x + w * 0.1, y + h * 0.1); // point 1
- double xb = (bits & 15) / 15.0, yb = (bits >>> 4 & 15) / 15.0;
- bits = bits >>> 8;
- f.appendSymmetricTriplet( // point 2
- x + w * (0.1 + 0.3 * xb), y + h * (0.2 + 0.2 * yb),
- 0.0, 0.2 * h);
- xb = (bits & 15) / 15.0; yb = (bits >>> 4 & 15) / 15.0;
- bits = bits >>> 8;
- f.appendSymmetricTriplet( // point 3
- x + w * (0.0 + 0.3 * xb), y + h * (0.6 + 0.3 * yb),
- 0.0, 0.3 * h);
- f.appendSymmetricTriplet( // point 4
- x + w * 0.5, y + h * 1.0,
- 0.3 * w, 0.0);
- xb = (bits & 15) / 15.0; yb = (bits >>> 4 & 15) / 15.0;
- bits = bits >>> 8;
- f.appendSymmetricTriplet( // point 5
- x + w * (0.7 + 0.3 * xb), y + h * (0.6 + 0.3 * yb),
- 0.0, -0.3 * h);
- xb = (bits & 15) / 15.0; yb = (bits >>> 4 & 15) / 15.0;
- bits = bits >>> 8;
- f.appendSymmetricTriplet( // point 6
- x + w * (0.6 + 0.3 * xb), y + h * (0.2 + 0.2 * yb),
- 0.0, -0.2 * h);
- f.appendTriplet(x + w * 0.9, y + h * 0.1, x + w, y, x + w, y); // point 7
- //System.out.println("RPF constructed");
- return f;
- }
-}
View
37 src/net/samuel/ben/Node.java
@@ -1,37 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-
-import java.util.List;
-
-// Represents an object managed by the ExpressionComponent
-interface Node {
- public List<? extends Node> getIns();
- public Node getOut();
- public Class<?> getType();
- public Object getValue();
- public String getLabel();
- public boolean canAddIns(); // Should this node have an input adder
- public void addIn(Node n);
- public void setIn(int i, Node n);
- public void setOut(Node n);
- public NodeStyle getStyle();
-}
View
25 src/net/samuel/ben/NodeEventListener.java
@@ -1,25 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-
-interface NodeEventListener {
-
-}
View
29 src/net/samuel/ben/NodeStyle.java
@@ -1,29 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-
-public enum NodeStyle {
- squiggly_sides,
- straight_sides,
- pointy_sides,
- semicircle_top,
- semicircle_bottom
-}
View
37 src/net/samuel/ben/Operator.java
@@ -1,37 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-import java.util.List;
-
-abstract class Operator implements Node {
- abstract public List<? extends Node> getIns();
- abstract public Node getOut();
- abstract public Class<?> getType();
- abstract public Object getValue();
- abstract public String getLabel();
- public NodeStyle getStyle() {
- return NodeStyle.squiggly_sides;
- }
- abstract public boolean canAddIns(); // Should this node have an input adder
- abstract public void addIn(Node n);
- abstract public void setIn(int i, Node n);
- abstract public void setOut(Node n);
-}
View
111 src/net/samuel/ben/OperatorFromMethod.java
@@ -1,111 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-public class OperatorFromMethod extends Operator {
- protected Method m;
- protected ArrayList<Class<?>> paramTypes;
- protected ArrayList<Node> params;
- public OperatorFromMethod(Method _m) {
- super();
- if(_m == null)
- throw new NullPointerException();
- m = _m;
- Class<?>[] ca = m.getParameterTypes();
- if(isStatic()) {
- paramTypes = new ArrayList<Class<?>>(Arrays.asList(ca));
- } else {
- paramTypes = new ArrayList<Class<?>>(ca.length + 1);
- paramTypes.add(m.getDeclaringClass());
- paramTypes.addAll(Arrays.asList(ca));
- }
- params = new ArrayList<Node>(paramTypes.size());
- for(Class<?> c : paramTypes) {
- params.add(new UnsetArg(this, c));
- }
- }
- protected boolean isStatic() {
- return Modifier.isStatic(m.getModifiers());
- }
- public String getLabel() { return toString(); }
- public Class<?> getType() { return m.getReturnType(); }
- public List<? extends Node> getIns() {
- return Collections.unmodifiableList(params);
- }
- public void setIn(int arg, Node n) {
- if(arg < 0 || arg >= maxArgs())
- throw new IndexOutOfBoundsException("arg " + arg + " of " + this.toString());
- if(n == null)
- n = new UnsetArg(this, paramTypes.get(arg));
- if(paramTypes.get(arg).isAssignableFrom(n.getType()))
- params.set(arg, n);
- else
- throw new ClassCastException("arg " + arg + " of " + this.toString());
- }
- private int maxArgs() {
- // TODO Auto-generated method stub
- return 0;
- }
- public Object getValue() {
- ArrayList<Object> values = new ArrayList<Object>(paramTypes.size());
- for(int i = 0; i < paramTypes.size(); ++i)
- values.set(i, params.get(i).getValue());
- try {
- if(isStatic())
- return m.invoke(null,
- values.toArray());
- else
- return m.invoke(values.get(0),
- values.subList(1,
- values.size()).toArray());
- } catch(Throwable t) {
- return t;
- }
- }
- public String toString() { return m.toGenericString(); }
- @Override
- public Node getOut() {
- // TODO Auto-generated method stub
- return null;
- }
- @Override
- public boolean canAddIns() {
- // TODO Auto-generated method stub
- return false;
- }
- @Override
- public void addIn(Node n) {
- // TODO Auto-generated method stub
-
- }
- @Override
- public void setOut(Node n) {
- // TODO Auto-generated method stub
-
- }
-}
View
83 src/net/samuel/ben/Piece.java
@@ -1,83 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-
-/**
- * Represents a graphical element
- */
-
-class Piece {
- public enum Draw {
- full_area, semicircle_top, semicircle_bottom,
- squiggly_side, squiggly_row, straight_side, straight_row,
- pointy_left_side, pointy_right_side, corner, empty
- }
- public class Part {
- public Draw d;
- }
- Piece(Node _n, Group _g) {
- n = _n; g = _g;
- }
- public void calc_dims() {
- switch(ns) {
- case squiggly_sides:
- left.d = right.d = Draw.squiggly_side;
- top.d = bot.d = Draw.squiggly_row;
- content.d = Draw.empty;
- break;
- case straight_sides:
- left.d = right.d = Draw.straight_side;
- top.d = n.canAddIns() ? Draw.squiggly_row : Draw.straight_row;
- bot.d = Draw.squiggly_row;
- content.d = Draw.empty;
- break;
- case pointy_sides:
- left.d = Draw.pointy_left_side;
- right.d = Draw.pointy_right_side;
- top.d = n.canAddIns() ? Draw.squiggly_row : Draw.straight_row;
- bot.d = Draw.squiggly_row;
- content.d = Draw.empty;
- break;
- case semicircle_top:
- left.d = right.d = top.d = Draw.empty;
- bot.d = Draw.squiggly_row;
- content.d = Draw.semicircle_top;
- break;
- case semicircle_bottom:
- left.d = right.d = bot.d = Draw.empty;
- top.d = Draw.squiggly_row;
- content.d = Draw.semicircle_bottom;
- break;
- default:
- throw new RuntimeException("What?!");
- }
- }
- private float w;
- private float h;
- private Node n;
- private Group g;
- private Part left;
- private Part right;
- private Part top;
- private Part bot;
- private Part content;
- private NodeStyle ns;
-}
View
313 src/net/samuel/ben/ReversiblePathFactory.java
@@ -1,313 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-import java.awt.geom.Point2D;
-import java.awt.geom.PathIterator;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Collection;
-import java.util.AbstractCollection;
-import java.util.Iterator;
-/**
- * Describes a path that can be iterated forwards or backwards.
- */
-public class ReversiblePathFactory {
- private LinkedList<double[]> points;
- private static final boolean debuggery = false;
- public ReversiblePathFactory() {
- points = new LinkedList<double[]>();
- }
- public ReversiblePathFactory(ReversiblePathFactory copy) {
- points = new LinkedList<double[]>(copy.points);
- }
- public void appendPinch() {
- points.add(new double[0]);
- }
- public void prependPinch() {
- points.add(0, new double[0]);
- }
- public void appendPoint(Point2D p) {
- appendPoint(p.getX(), p.getY());
- }
- public void appendPoint(double x, double y) {
- double[] pa = new double[2];
- pa[0] = x;
- pa[1] = y;
- if(debuggery) write("append", pa);
- points.add(pa);
- }
- public void appendTriplet(Point2D fcp, Point2D p, Point2D scp) {
- appendTriplet(fcp.getX(), fcp.getY(), p.getX(), p.getY(),
- scp.getX(), scp.getY());
- }
- public void appendTriplet(double fcpx, double fcpy, double px, double py,
- double scpx, double scpy)
- {
- double[] pa = new double[6];
- pa[0] = fcpx; pa[1] = fcpy;
- pa[2] = px; pa[3] = py;
- pa[4] = scpx; pa[5] = scpy;
- if(debuggery) write("append", pa);
- points.add(pa);
- }
- public void appendSymmetricTriplet(Point2D p, double dx, double dy) {
- appendTriplet(p.getX() - dx, p.getY() - dy, p.getX(), p.getY(),
- p.getX() + dx, p.getY() + dy);
- }
- public void prependSymmetricTriplet(Point2D p, double dx, double dy) {
- prependTriplet(p.getX() - dx, p.getY() - dy, p.getX(), p.getY(),
- p.getX() + dx, p.getY() + dy);
- }
- public void appendSymmetricTriplet(double px, double py,
- double dx, double dy) {
- appendTriplet(px - dx, py - dy, px, py, px + dx, py + dy);
- }
- public void prependSymmetricTriplet(double px, double py,
- double dx, double dy) {
- prependTriplet(px - dx, py - dy, px, py, px + dx, py + dy);
- }
- public void prependPoint(Point2D p) {
- prependPoint(p.getX(), p.getY());
- }
- public void prependPoint(double x, double y) {
- double[] pa = new double[2];
- pa[0] = x;
- pa[1] = y;
- points.add(0, pa);
- if(debuggery) write("prepend", pa);
- }
- public void prependTriplet(Point2D fcp, Point2D p, Point2D scp) {
- prependTriplet(fcp.getX(), fcp.getY(), p.getX(), p.getY(),
- scp.getX(), scp.getY());
- }
- public void prependTriplet(double fcpx, double fcpy, double px, double py,
- double scpx, double scpy)
- {
- double[] pa = new double[6];
- pa[0] = fcpx; pa[1] = fcpy;
- pa[2] = px; pa[3] = py;
- pa[4] = scpx; pa[5] = scpy;
- points.add(0, pa);
- if(debuggery) write("prepend", pa);
- }
- public void append(ReversiblePathFactory rp) {
- points.addAll(rp.points);
- }
- public void appendReverse(ReversiblePathFactory rp) {
- points.addAll(rp.pointsReversed());
- }
- public void prepend(ReversiblePathFactory rp) {
- points.addAll(0, rp.points);
- }
- public void prependReverse(ReversiblePathFactory rp) {
- points.addAll(0, rp.pointsReversed());
- }
- private Collection<double[]> pointsReversed() {
- return new AbstractCollection<double[]>() {
- public int size() { return points.size(); }
- public Iterator<double[]> iterator() {
- final ListIterator<double[]> li =
- points.listIterator(points.size());
- return new Iterator<double[]>() {
- private ListIterator<double[]> it;
-
- public boolean hasNext() { return it.hasPrevious(); }
- public double[] next() { return it.previous(); }
- public void remove() {}
- };
- }
- };
- }
- public PathIterator forwardPath(int winding) {
- return new ReversiblePath(points.listIterator(0), true, winding);
- }
- public PathIterator reversePath(int winding) {
- return new ReversiblePath(points.listIterator(points.size()), false, winding);
- }
- public PathIterator forwardPath() {
- return forwardPath(PathIterator.WIND_NON_ZERO);
- }
- public PathIterator reversePath() {
- return reversePath(PathIterator.WIND_NON_ZERO);
- }
- private static void write(String s, double[] d) {
- write(s, d, d == null ? 0 : d.length);
- }
- private static void write(String s, double[] d, int x) {
- StringBuffer sb = new StringBuffer();
- sb.append(s);
- if(d == null) {
- sb.append(" null");
- } else {
- for(int i = 0; i < x; i += 2)
- sb.append(" <" + d[i] + ", " + d[i + 1] + ">");
- }
- System.out.println(sb);
- }
- private static void write(String s, float[] d) {
- write(s, d, d == null ? 0 : d.length);
- }
- private static void write(String s, float[] d, int x) {
- StringBuffer sb = new StringBuffer();
- sb.append(s);
- if(d == null) {
- sb.append(" null");
- } else {
- for(int i = 0; i < x; i += 2)
- sb.append(" <" + d[i] + ", " + d[i + 1] + ">");
- }
- System.out.println(sb);
- }
- private class ReversiblePath implements PathIterator {
- public ReversiblePath(ListIterator<double[]> iter,
- boolean forward, int winding)
- {
- if(debuggery) System.out.println("constructor");
- it = iter;
- d = forward;
- cur = null;
- prior = null;
- next();
- w = winding;
- }
- ListIterator<double[]> it;
- double[] prior;
- double[] cur;
- boolean d;
- int w;
- public int currentSegment(double[] c) {
- if(debuggery) System.out.println("currentSegment float");
- switch(cur == null ? 0 : cur.length) {
- case 0:
- if(debuggery) System.out.println("close");
- return PathIterator.SEG_CLOSE;
- case 2:
- switch(prior == null ? 0 : prior.length) {
- case 0:
- case 2:
- c[0] = cur[0];
- c[1] = cur[1];
- if(debuggery) write("lineto", c, 2);
- return PathIterator.SEG_LINETO;
- case 6:
- c[0] = prior[d ? 4 : 0];
- c[1] = prior[d ? 5 : 1];
- c[2] = cur[0];
- c[3] = cur[1];
- if(debuggery) write("quadto", c, 4);
- return PathIterator.SEG_QUADTO;
- default:
- throw new RuntimeException("Malformed ReversiblePath");
- }
- case 6:
- switch(prior == null ? 0 : prior.length) {
- case 0:
- case 2:
- c[0] = cur[d ? 0 : 4];
- c[1] = cur[d ? 1 : 5];
- c[2] = cur[2];
- c[3] = cur[3];
- if(debuggery) write("quadto", c, 4);
- return PathIterator.SEG_QUADTO;
- case 6:
- c[0] = prior[d ? 4 : 0];
- c[1] = prior[d ? 5 : 1];
- c[2] = cur[d ? 0 : 4];
- c[3] = cur[d ? 1 : 5];
- c[4] = cur[2];
- c[5] = cur[3];
- if(debuggery) write("cubeto", c, 6);
- return PathIterator.SEG_CUBICTO;
- default:
- throw new RuntimeException("Malformed ReversiblePath");
- }
- default:
- throw new RuntimeException("Malformed ReversiblePath");
- }
- }
- public int currentSegment(float[] c) {
- if(debuggery) System.out.println("currentSegment float");
- switch(cur == null ? 0 : cur.length) {
- case 0:
- if(debuggery) System.out.println("close");
- return PathIterator.SEG_CLOSE;
- case 2:
- switch(prior == null ? 0 : prior.length) {
- case 0:
- case 2:
- c[0] = (float) cur[0];
- c[1] = (float) cur[1];
- if(debuggery) write("lineto", c, 2);
- return PathIterator.SEG_LINETO;
- case 6:
- c[0] = (float) prior[d ? 4 : 0];
- c[1] = (float) prior[d ? 5 : 1];
- c[2] = (float) cur[0];
- c[3] = (float) cur[1];
- if(debuggery) write("quadto", c, 4);
- return PathIterator.SEG_QUADTO;
- default:
- throw new RuntimeException("Malformed ReversiblePath");
- }
- case 6:
- switch(prior == null ? 0 : prior.length) {
- case 0:
- case 2:
- c[0] = (float) cur[d ? 0 : 4];
- c[1] = (float) cur[d ? 1 : 5];
- c[2] = (float) cur[2];
- c[3] = (float) cur[3];
- if(debuggery) write("quadto", c, 4);
- return PathIterator.SEG_QUADTO;
- case 6:
- c[0] = (float) prior[d ? 4 : 0];
- c[1] = (float) prior[d ? 5 : 1];
- c[2] = (float) cur[d ? 0 : 4];
- c[3] = (float) cur[d ? 1 : 5];
- c[4] = (float) cur[2];
- c[5] = (float) cur[3];
- if(debuggery) write("cubeto", c, 6);
- return PathIterator.SEG_CUBICTO;
- default:
- throw new RuntimeException("Malformed ReversiblePath");
- }
- default:
- throw new RuntimeException("Malformed ReversiblePath");
- }
- }
- public void next() {
- if(debuggery) System.out.println("next");
- prior = cur;
- if(d)
- cur = it.hasNext() ? it.next() : null;
- else
- cur = it.hasPrevious() ? it.previous() : null;
- }
- public boolean isDone() {
- if(debuggery) System.out.println("isDone");
- return cur == null;
- }
- public int getWindingRule() {
- if(debuggery) System.out.println("getWindingRule");
- return w;
- }
- } // private class ReversiblePathIterator
-} // public class ReversiblePath
View
101 src/net/samuel/ben/SegmentPath.java
@@ -1,101 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
-/**
- * Used in conjunction with more complex paths under CompoundPath, this
- * class provides a way to do simple operations like MOVETO and CLOSE.
- */
-public class SegmentPath implements PathIterator {
- private int ret;
- private int wind;
- private boolean done;
- private double[] coords;
- public SegmentPath(int r, double x1, double y1, double x2, double y2,
- double x3, double y3, int w)
- {
- done = false;
- ret = r;
- coords = new double[6];
- coords[0] = x1;
- coords[1] = y1;
- coords[2] = x2;
- coords[3] = y2;
- coords[4] = x3;
- coords[5] = y3;
- wind = w;
- }
- public int getWindingRule() {
- return wind;
- }
- public boolean isDone() {
- return done;
- }
- public void next() {
- done = true;
- }
- public int currentSegment(double[] c) {
- System.arraycopy(coords, 0, c, 0, 6);
- return ret;
- }
- public int currentSegment(float[] c) {
- for(int i = 0; i < 6; ++i)
- c[i] = (float) coords[i];
- return ret;
- }
- public static PathIterator close() {
- return new SegmentPath(PathIterator.SEG_CLOSE, 0, 0, 0, 0, 0, 0,
- PathIterator.WIND_EVEN_ODD);
- }
- public static PathIterator closeNz() {
- return new SegmentPath(PathIterator.SEG_CLOSE, 0, 0, 0, 0, 0, 0,
- PathIterator.WIND_NON_ZERO);
- }
- public static PathIterator moveto(double x, double y) {
- return new SegmentPath(PathIterator.SEG_MOVETO, x, y, 0, 0, 0, 0,
- PathIterator.WIND_EVEN_ODD);
- }
- public static PathIterator movetoNz(double x, double y) {
- return new SegmentPath(PathIterator.SEG_MOVETO, x, y, 0, 0, 0, 0,
- PathIterator.WIND_NON_ZERO);
- }
- public static PathIterator moveto(Point2D p) {
- return moveto(p.getX(), p.getY());
- }
- public static PathIterator movetoNz(Point2D p) {
- return movetoNz(p.getX(), p.getY());
- }
- public static PathIterator lineto(double x, double y) {
- return new SegmentPath(PathIterator.SEG_LINETO, x, y, 0, 0, 0, 0,
- PathIterator.WIND_EVEN_ODD);
- }
- public static PathIterator linetoNz(double x, double y) {
- return new SegmentPath(PathIterator.SEG_LINETO, x, y, 0, 0, 0, 0,
- PathIterator.WIND_NON_ZERO);
- }
- public static PathIterator lineto(Point2D p) {
- return lineto(p.getX(), p.getY());
- }
- public static PathIterator linetoNz(Point2D p) {
- return linetoNz(p.getX(), p.getY());
- }
-}
View
180 src/net/samuel/ben/SquigglyPath.java
@@ -1,180 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
-
-public class SquigglyPath implements PathIterator {
- double x, y, l, p, wl, a, off, last_off, xm, ym;
- int segment;
- public SquigglyPath(Point2D from, Point2D to, double phase,
- double wavelength, double amplitude)
- {
- phase = phase < 0.0 ? 1.0 - phase : phase;
- phase -= Math.floor(phase);
- p = phase;
- l = from.distance(to);
- x = from.getX(); y = from.getY();
- xm = (to.getX() - from.getX()) / l;
- ym = (to.getY() - from.getY()) / l;
- wl = wavelength; a = amplitude;
- last_off = 0.0;
- off = 0.0;
- update_off();
- segment = -1; // moveto ? -1 : 0;
- }
- /**
- Handling phase and number of segments
- At offset 0, the phase starts at "phase". So each point is at real
- phase 0.5 or 0.0
- So if phase is 0.2, the next point will be at offset 0.3
-
- This is called before each point, so it is first called by
- constructor.
- */
- private void update_off() {
- if(off == l) {
- off += 1;
- return;
- }
- // phase is a multiplier of wavelength
- double i = wl * ((p < 0.5 ? 0.5 : 1.0) - p);
- // Check if we're running out of length
- if(off + i > l) {
- // adjust phase for the finalPhase function
- p += (l - off) / wl;
- off = l;
- } else {
- p = p < 0.5 ? 0.5 : 0.0;
- off += i;
- }
- }
- /*
- Path diagram
-
- O--*--O O--*--O O--*--O
- * •• •• •• •• •• *
- O--*--O O--*--O O--*--O
- <-wavelength--><-wavelength-><-wavelength-->
-
- Given the line from start to finish, each point is simply squigglyAmplitude (from the ui object) above or below the center line.
- For simplicity, we always start and finish on the centerline.
- The .. indicate where the line would cross the centerline.
-
- A wavelength goes from phase 0, inclusive to 1, exclusive..
- 0: control point for phase .25 at centerline + amplitude
- control point for phase -0.25 at centerline - amplitude
- 0.25: point at centerline + amplitude
- 0.5: control point for phase .25 at centerline + amplitude
- control point for phase .75 at centerline - amplitude
- 0.75: point at centerline - amplitude
-
- UPDATE: I'm doing points at 0 and 0.5, to simplify the arithmetic a little.
- */
-
- public int currentSegment(double[] coords) {
- if(segment == -1) {
- coords[0] = x;
- coords[1] = y;
- return PathIterator.SEG_LINETO;
- }
- if(off > l) {
- coords[0] = x + xm * l;
- coords[1] = y + ym * l;
- return PathIterator.SEG_LINETO;
- }
-
- // Is this point above the centerline? The final point is on the
- // centerline.
- double up = off == l ? 0.0 : (p < 0.5 ? a : -a);
- // Was the previous point above the centerline? Since we just negate
- // up, we're really just checking for the first segment.
- double last_up = last_off == 0.0 ? 0.0 : -up;
- // Control points are halfway between points
- double ctrl_off = (off + last_off) / 2.0;
- // To get 90 degrees left from our main:
- double xn = -ym;
- double yn = xm;
- // last point's second control point
- coords[0] = x + xm * ctrl_off + xn * last_up;
- coords[1] = y + ym * ctrl_off + yn * last_up;
- coords[2] = x + xm * ctrl_off + xn * up;
- coords[3] = y + ym * ctrl_off + yn * up;
- coords[4] = x + xm * off + xn * up;
- coords[5] = y + ym * off + yn * up;
- return PathIterator.SEG_CUBICTO;
- }
- public int currentSegment(float[] coords) {
- if(segment == -1) {
- coords[0] = (float) x;
- coords[1] = (float) y;
- return PathIterator.SEG_LINETO;
- }
- if(off > l) {
- coords[0] = (float) (x + xm * l);
- coords[1] = (float) (y + ym * l);
- return PathIterator.SEG_LINETO;
- }
-
- // Is this point above the centerline? The final point is on the
- // centerline.
- float up = off == l ? 0.0f : ((float) p < 0.5f ? (float) a : (float) -a);
- // Was the previous point above the centerline? Since we just negate
- // up, we're really just checking for the first segment.
- float last_up = last_off == 0.0f ? 0.0f : (float) -up;
- // Control points are halfway between points
- float ctrl_off = (float) (off + last_off) / 2.0f;
- // To get 90 degrees left from our main:
- float xn = (float) -ym;
- float yn = (float) xm;
- // last point's second control point
- coords[0] = (float) x + (float) xm * ctrl_off + xn * last_up;
- coords[1] = (float) y + (float) ym * ctrl_off + yn * last_up;
- coords[2] = (float) x + (float) xm * ctrl_off + xn * up;
- coords[3] = (float) y + (float) ym * ctrl_off + yn * up;
- coords[4] = (float) x + (float) xm * (float) off + xn * up;
- coords[5] = (float) y + (float) ym * (float) off + yn * up;
- return PathIterator.SEG_CUBICTO;
- }
- public boolean isDone() {
- return segment >= 0 && off > l;
- }
- public void next() {
- if(segment >= 0) {
- last_off = off;
- update_off();
- }
- segment++;
- return;
- }
- public int getWindingRule() {
- return PathIterator.WIND_NON_ZERO;
- }
- /**
- * Calculate the starting phase after a length.
- */
- public static double nextPhase(double p, double wl, double l) {
- p += Math.abs(l) / wl;
- p = p < 0.0 ? 1.0 - p : p;
- p -= Math.floor(p);
- return p;
- }
-}
View
39 src/net/samuel/ben/UnsetArg.java
@@ -1,39 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-import java.util.Collections;
-import java.util.List;
-
-public class UnsetArg implements Node {
- protected Class<?> t;
- protected Node o;
- public UnsetArg(Node node, Class<?> type) { t = type; o = node; }
- public List<? extends Node> getIns() { return Collections.emptyList(); }
- public Node getOut() { return o; }
- public Class<?> getType() { return t; }
- public Object getValue() { return null; }
- public boolean canAddIns() { return false; }
- public void addIn(Node n) { throw new RuntimeException(); }
- public void setIn(int i, Node n) { throw new RuntimeException(); }
- public void setOut(Node n) { o = n; }
- public NodeStyle getStyle() { return NodeStyle.semicircle_top; }
- public String getLabel() { return t.getSimpleName(); }
-}
View
53 src/net/samuel/ben/UnusedReturn.java
@@ -1,53 +0,0 @@
-/*
- Copyright 2009 Benjamin Samuel. All rights reserved.
- This file is part of VisualExpressionBuilder, a component for the
- Swing UI for Java. Java is a trademark of Sun.
-
- VisualExpressionBuilder is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation, either version 3 of the License, or (at
- your option) any later version.
-
- VisualExpressionBuilder is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with VisualExpressionBuilder, in the file COPYING in the root directory of
- the distribution. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.samuel.ben;
-import java.util.ArrayList;
-import java.util.List;
-
-public class UnusedReturn implements Node {
- protected Class<?> t;
- protected Node i;
- protected List<Node> il;
- public UnusedReturn(Node node, Class<?> type) {
- t = type;
- i = node;
- il = new ArrayList<Node>();
- il.add(i);
- }
- public List<? extends Node> getIns() { return il; }
- public Class<?> getType() { return t; }
- public Node getOut() { return null; }
- public Object getValue() { return null; }
- public NodeStyle getStyle() { return NodeStyle.semicircle_bottom; }
- public String getLabel() { return t.getSimpleName(); }
- public boolean canAddIns() { return false; }
- public void addIn(Node n) { throw new RuntimeException(); }
- public void setIn(int idx, Node n) {
- if(idx != 0)
- throw new RuntimeException();
- i = n;
- il.set(0, n);
- }
- public void setOut(Node n) {
- if(n != null)
- throw new RuntimeException();
- }
-}
View
188 src/quicktests/OnePiece.java
@@ -1,93 +1,109 @@
package quicktests;
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.geom.*;
-import java.util.*;
-import javax.swing.*;
-import net.samuel.ben.*;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+
+import veb.swing.NibPath;
+import veb.swing.SegmentPath;
+import veb.swing.SquigglyPath;
+
public class OnePiece extends JPanel {
- public OnePiece() {
- super();
- inset = new Rectangle2D.Double();
- strk = new BasicStroke(1.0f);
- }
- Rectangle2D.Double inset;
- BasicStroke strk;
-
- private Point2D p(double mx, double my) {
- Rectangle2D r = inset;
- return new Point2D.Double(r.getX() + mx * r.getWidth(), r.getY() + my * r.getHeight());
- }
- private double px(double x) {
- Rectangle2D r = inset;
- return r.getX() + x * r.getWidth();
- }
- private double py(double y) {
- Rectangle2D r = inset;
- return r.getY() + y * r.getHeight();
- }
- private double dx(double x) {
- Rectangle2D r = inset;
- return x * r.getWidth();
- }
- private double dy(double y) {
- Rectangle2D r = inset;
- return y * r.getHeight();
- }
-/*public SquigglyPath(Point2D from, Point2D to, double phase, double wavelength, double amplitude)
+ private static final long serialVersionUID = -2574375926597058507L;
+
+ public OnePiece() {
+ super();
+ inset = new Rectangle2D.Double();
+ strk = new BasicStroke(1.0f);
+ }
+ Rectangle2D.Double inset;
+ BasicStroke strk;
+
+ private Point2D p(final double mx, final double my) {
+ final Rectangle2D r = inset;
+ return new Point2D.Double(r.getX() + mx * r.getWidth(), r.getY() + my * r.getHeight());
+ }
+ private double px(final double x) {
+ final Rectangle2D r = inset;
+ return r.getX() + x * r.getWidth();
+ }
+ private double py(final double y) {
+ final Rectangle2D r = inset;
+ return r.getY() + y * r.getHeight();
+ }
+ private double dx(final double x) {
+ final Rectangle2D r = inset;
+ return x * r.getWidth();
+ }
+ private double dy(final double y) {
+ final Rectangle2D r = inset;
+ return y * r.getHeight();
+ }
+ /*public SquigglyPath(Point2D from, Point2D to, double phase, double wavelength, double amplitude)
public static double nextPhase(double p, double wl, double l)
public NibPath(double _x, double _y, double _w, double _h, Class<?> c) */
- public void paint(Graphics g) {
- Rectangle2D r = getBounds();
- inset.setRect(r.getX() + 0.05 * r.getWidth(),
- r.getY() + 0.05 * r.getHeight(), r.getWidth() * 0.9, r.getHeight() * 0.9);
+ @Override
+ public void paint(final Graphics g) {
+ final Rectangle2D r = getBounds();
+ inset.setRect(r.getX() + 0.05 * r.getWidth(),
+ r.getY() + 0.05 * r.getHeight(), r.getWidth() * 0.9, r.getHeight() * 0.9);
+
+ final GeneralPath gp = new GeneralPath();
+ gp.append(SegmentPath.moveto(p(0.0, 0.0)), false);
+ final double w = dx(0.3); final double a = 3.0;
+ // North border
+ double hp = 0.0;
+ gp.append(new SquigglyPath(p(0.0, 0.0), p(0.4, 0.0), hp, w, a), false);
+ gp.append(NibPath.rpf(px(0.4), py(0.0), dx(0.2), dy(0.2),
+ 0x384a3315).forwardPath(), false);
+ hp = SquigglyPath.nextPhase(hp, w, dx(0.6));
+ gp.append(new SquigglyPath(p(0.6, 0.0), p(1.0, 0.0), hp, w, a), false);
+ // East
+ double vp = 0.3;
+ gp.append(new SquigglyPath(p(1.0, 0.0), p(1.0, 0.8), vp, w, a), false);
+ // South
+ hp = 0.5;
+ gp.append(new SquigglyPath(p(1.0, 0.8), p(0.6, 0.8), hp, w, a), false);
+ gp.append(NibPath.rpf(px(0.4), py(0.8), dx(0.2), dy(0.2),
+ 0x384a3315).reversePath(), false);
+ hp = SquigglyPath.nextPhase(hp, w, dx(0.6));
+ gp.append(new SquigglyPath(p(0.4, 0.8), p(0.0, 0.8), hp, w, a), false);
+ // West
+ vp = 0.8;
+ gp.append(new SquigglyPath(p(0.0, 0.8), p(0.0, 0.0), vp, w, a), false);
+ gp.append(SegmentPath.close(), false);
+ final Graphics2D g2d = (Graphics2D) g;
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ //g2d.fill(inset);
+ //gp.append(new CompoundPath(p), false);
+ g2d.setPaint(Color.GRAY);
+ g2d.fill(gp);
+ g2d.setPaint(Color.BLACK);
+ g2d.setStroke(strk);
+ g2d.draw(gp);
+ }
- GeneralPath gp = new GeneralPath();
- gp.append(SegmentPath.moveto(p(0.0, 0.0)), false);
- double w = dx(0.3); double a = 3.0;
- // North border
- double hp = 0.0;
- gp.append(new SquigglyPath(p(0.0, 0.0), p(0.4, 0.0), hp, w, a), false);
- gp.append(NibPath.rpf(px(0.4), py(0.0), dx(0.2), dy(0.2),
- 0x384a3315).forwardPath(), false);
- hp = SquigglyPath.nextPhase(hp, w, dx(0.6));
- gp.append(new SquigglyPath(p(0.6, 0.0), p(1.0, 0.0), hp, w, a), false);
- // East
- double vp = 0.3;
- gp.append(new SquigglyPath(p(1.0, 0.0), p(1.0, 0.8), vp, w, a), false);
- // South
- hp = 0.5;
- gp.append(new SquigglyPath(p(1.0, 0.8), p(0.6, 0.8), hp, w, a), false);
- gp.append(NibPath.rpf(px(0.4), py(0.8), dx(0.2), dy(0.2),
- 0x384a3315).reversePath(), false);
- hp = SquigglyPath.nextPhase(hp, w, dx(0.6));
- gp.append(new SquigglyPath(p(0.4, 0.8), p(0.0, 0.8), hp, w, a), false);
- // West
- vp = 0.8;
- gp.append(new SquigglyPath(p(0.0, 0.8), p(0.0, 0.0), vp, w, a), false);
- gp.append(SegmentPath.close(), false);
- Graphics2D g2d = (Graphics2D) g;
- g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
- //g2d.fill(inset);
- //gp.append(new CompoundPath(p), false);
- g2d.setPaint(Color.GRAY);
- g2d.fill(gp);
- g2d.setPaint(Color.BLACK);
- g2d.setStroke(strk);
- g2d.draw(gp);
- }
-
- public static void main(String args[]) {
- JFrame f = new JFrame("OnePiece");
- f.addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {System.exit(0);}
- });
- OnePiece op = new OnePiece();
- f.getContentPane().add("Center", op);
- f.setSize(300, 300);
- f.pack();
- f.setVisible(true);
- }
+ public static void main(final String args[]) {
+ final JFrame f = new JFrame("OnePiece");
+ f.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(final WindowEvent e) {System.exit(0);}
+ });
+ final OnePiece op = new OnePiece();
+ f.getContentPane().add("Center", op);
+ f.setSize(300, 300);
+ f.pack();
+ f.setVisible(true);
+ }
}
View
35 src/quicktests/OnePiece2.java
@@ -1,15 +1,27 @@
package quicktests;
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.geom.*;
-import javax.swing.*;
+import java.awt.BasicStroke;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
public class OnePiece2 extends JPanel {
- public void paint(Graphics g) {
- Graphics2D g2d = (Graphics2D) g;
- g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6304004113864637817L;
+
+ @Override
+ public void paint(final Graphics g) {
+ final Graphics2D g2d = (Graphics2D) g;
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.translate((getBounds().getWidth() - PieceWidth()) / 2, (getBounds().getHeight() - PieceHeight()) / 2);
g2d.setStroke(new BasicStroke(1.0f));
@@ -31,12 +43,13 @@ private Shape BorderShape() {
return null;
}
- public static void main(String args[]) {
- JFrame f = new JFrame("OnePiece");
+ public static void main(final String args[]) {
+ final JFrame f = new JFrame("OnePiece");
f.addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {System.exit(0);}
+ @Override
+ public void windowClosing(final WindowEvent e) {System.exit(0);}
});
- OnePiece op = new OnePiece();
+ final OnePiece op = new OnePiece();
f.getContentPane().add("Center", op);
f.setSize(300, 300);
f.pack();
View
296 src/space/Area.java
@@ -0,0 +1,296 @@
+package space;
+
+import java.util.Iterator;
+import space.Vector.cardinal;
+
+/**
+ * @author ben
+ *
+ */
+public final class Area implements Iterable<Area>, Comparable<Area> {
+ /**
+ * The column the area starts on; also the westernmost column.
+ */
+ final public int sx;
+ /**
+ * The first column that is not part of the area.
+ * That is, for every column x, x is in the area iff sx <= x < ex.
+ */
+ final public int ex;
+ /**
+ * The row the area starts on; also the "southernmost" row.
+ */
+ final public int sy;
+ /**
+ * The first row that is not part of the area.
+ * That is, for every row y, y is in the area iff sy <= y < ey.
+ */
+ final public int ey;
+ /**
+ * @param sx First column of the area.
+ * @param sy First row of the area.
+ * @param ex Column after the last column.
+ * @param ey Row after the last row.
+ */
+ public Area(final int sx, final int sy, final int ex, final int ey) {
+ assert ex >= sx && ey >= sy && sx >= 0 && sy >= 0;
+ this.sx = sx;
+ this.ex = ex;
+ this.sy = sy;
+ this.ey = ey;
+ }
+ /**
+ * @return number of columns in area.
+ */
+ public int width() { return ex - sx; }
+ /**
+ * @return number of rows in area.
+ */
+ public int height() { return ey - sy; }
+ /**
+ * @return width * height
+ */
+ public int area() { return (ex - sx) * (ey - sy); }
+ /**
+ * @param s Scaling factor.
+ * @return New area with origin and area scaled by s.
+ */
+ public Area scale(final int s) {
+ if(s >= 0)
+ return new Area(sx * s, sy * s, ex * s, ey * s);
+ else
+ return new Area(ex * s, ey * s, sx * s, sy * s);
+ }
+ public Area inset(final int i) {
+ return new Area(sx + i, sy + i, ex - i, ey - i);
+ }
+ public Area offset(final int x, final int y) {
+ return new Area(sx + x, sy + y, ex + x, ey + y);
+ }
+ public boolean overlap(final Area o) {
+ if(o == null)
+ return false;
+ return sx < o.ex && o.sx < ex && sy < o.ey && o.sy < ey;
+ }
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return String.format("Area [sx=%s, ex=%s, sy=%s, ey=%s]", sx, ex, sy,
+ ey);
+ }
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ex;
+ result = prime * result + ey;
+ result = prime * result + sx;
+ result = prime * result + sy;
+ return result;
+ }
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof Area))
+ return false;
+ final Area other = (Area) obj;
+ if (ex != other.ex)
+ return false;
+ if (ey != other.ey)
+ return false;
+ if (sx != other.sx)
+ return false;
+ if (sy != other.sy)
+ return false;
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see java.lang.Iterable#iterator()
+ */
+ @Override
+ public Iterator<Area> iterator() {
+ return new Iterator<Area>() {
+ int x = sx;
+ int y = sy;
+ @Override
+ public boolean hasNext() {
+ return y < ey;
+ }
+ @Override
+ public Area next() {
+ final Area a = new Area(x, y, x + 1, y + 1);
+ x++;
+ if(x >= ex) {
+ x = sx;
+ y++;
+ }
+ return a;
+ }
+ @Override
+ public void remove() {
+ throw new AssertionError();
+ }
+ };
+ }
+ /**
+ * Number of empty columns between two areas.
+ * @param other area
+ * @return distance
+ */
+ public int xdist(final Area o) {
+ if(sx < o.ex && o.sx < ex)
+ return 0;
+ if(o.ex < sx)
+ return o.ex - sx;
+ if(o.sx > ex)
+ return o.sx - ex;
+ throw new AssertionError(o);
+ }
+ /**
+ * Number of empty rows between two areas.
+ * @param other area
+ * @return distance
+ */
+ public int ydist(final Area o) {
+ if(sy < o.ey && o.sy < ey)
+ return 0;
+ if(o.ey < sy)
+ return o.ey - sy;
+ if(o.sy > ey)
+ return o.sy - ey;
+ throw new AssertionError(o);
+ }
+ /**
+ * Creates an area adjacent to this one that is one row or column thick.
+ * @param axis indicates the cardinal direction in which to extend the area.
+ * @return New area created.
+ */
+ public Area adjacent(final cardinal axis) {
+ int vx = axis.v.x.intVal(),
+ vy = axis.v.y.intVal();
+ return new Area(
+ vx > 0 ? ex : sx + vx,
+ vy > 0 ? ey : sy + vy,
+ vx < 0 ? sx : ex + vx,
+ vy < 0 ? sy : ey + vy
+ );
+ }
+ /**
+ * @return new area at origin
+ */
+ public Area zeroize() {
+ return new Area(0, 0, ex - sx, ey - sy);
+ }
+ public final static Area ZERO_AREA = new Area(0, 0, 0, 0);
+ /**
+ * @return an area that covers all the areas in iterable.
+ */
+ public static Area coverage(final Iterable<Area> ax) {
+ final Iterator<Area> i = ax.iterator();
+ if(!i.hasNext())
+ return ZERO_AREA;
+ int lx, ly, hx, hy;
+ final Area a = i.next();
+ lx = a.sx; ly = a.sy; hx = a.ex; hy = a.ey;
+ while(i.hasNext()) {
+ if(a.sx < lx) lx = a.sx;
<