SforzandoCF

vector paths

Jan 22nd, 2026 (edited)
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.33 KB | None | 0 0
  1. public class PathComponent {
  2.     private final PathSegment[] segments;
  3.    
  4.     public HashMap<String, Object> properties = new HashMap<String, Object>();
  5.    
  6.     public PathComponent (PathSegment[] segments) {
  7.         this.segments = segments;
  8.     }
  9.    
  10.     public void draw (Graphics k, int aaSampleCount) {
  11.         PathPoint maximum = this.points[0];
  12.         for (int i = 0; i < this.points.length; i++) {
  13.             PathPoint p = this.points[i];
  14.             if (p.getX() > maximum.getX()) maximum.setX(p.getX());
  15.             if (p.getY() > maximum.getY()) maximum.setY(p.getY());
  16.         }
  17.         BufferedImage buffer1 = new BufferedImage((maximum.getX() + this.getInt("stroke")) * aaSampleCount, (maximum.getY() + this.getInt("stroke")) * aaSampleCount, BufferedImage.TYPE_INT_ARGB);
  18.         Graphics g = buffer1.createGraphics();
  19.         ArrayList<Point> polyPoints = new ArrayList<Point>();
  20.         for (PathSegment s : this.segments) {
  21.             long max = 0x0010000000000000L >> getInt("precision");
  22.             for (long l = 0; l < max; l++) {
  23.                 double t = Double.longBitsToDouble(l) - 1;
  24.                 polyPoints.add(s.getPoint(t));
  25.                 drawPoint(g, s, t, this.getInt("stroke"), this.<Color>getObject("strokeColor", Color.class, null), aaSampleCount);
  26.             }
  27.         }
  28.         int[] xpoly = new int[polyPoints.size()];
  29.         int[] ypoly = new int[polyPoints.size()];
  30.         for (int i = 0; i < polyPoints.size(); i++) {
  31.             xpoly[i] = ((int) polyPoints.get(i).getX() + this.getInt("stroke")) * aaSampleCount;
  32.             ypoly[i] = ((int) polyPoints.get(i).getY() + this.getInt("stroke")) * aaSampleCount;
  33.         }
  34.         BufferedImage buffer2 = new BufferedImage(buffer1.getWidth(), buffer1.getHeight(), BufferedImage.TYPE_INT_ARGB);
  35.         g = this.buffer2.createGraphics();
  36.         g.setColor(this.<Color>getObject("fillColor", Color.class, new Color(0, 0, 0, 255)));
  37.         g.fillPolygon(xpoly, ypoly, xpoly.length);
  38.         g.drawImage(buffer1, 0, 0, null);
  39.         k.drawImage(buffer2, this.getInt("x") - this.getInt("stroke"), this.getInt("y") - this.getInt("stroke"), null);
  40.     }
  41.    
  42.     private int getInt (String s) {
  43.         return this.<Integer>getObject(s, Integer.class, Integer.valueOf(0)).intValue();
  44.     }
  45.    
  46.     private <T> T getObject (String s, Class<T> type, T fallback) {
  47.         Object o = this.properties.get(s);
  48.         if (o == null) return fallback;
  49.         if (type.isInstance(o)) return type.cast(o);
  50.         return fallback;
  51.     }
  52.    
  53.     private static void drawPoint (Graphics g, PathSegment s, double t, int stroke, Color color, int aaSampleCount) {
  54.         Point p = s.getPoint(t);
  55.         double hs = (stroke / 2.0) * aaSampleCount;
  56.         g.setColor(color);
  57.         g.fillOval((int) ((p.getX() * aaSampleCount) - hs), (int) ((p.getX() * aaSampleCount) - hs), stroke * aaSampleCount, stroke * aaSampleCount);
  58.     }
  59.    
  60.     public PathSegment[] getSegments () {
  61.         return this.segments;
  62.     }
  63. }
  64.  
  65. public class PathSegment {
  66.     public final int degree;
  67.    
  68.     public final Point[] controls;
  69.    
  70.     public PathSegment (int degree, Point[] controls) {
  71.         this.degree = degree;
  72.         this.controls = controls;
  73.     }
  74.    
  75.     public Point getPoint (double t) {
  76.         if (this.degree == 0) {
  77.             Point p = new Point();
  78.             p.setX(-1);
  79.             p.setY(-1);
  80.             return p;
  81.         }
  82.         return bezier(this.degree, t, this.controls);
  83.     }
  84.    
  85.     public static Point bezier (int degree, double time, Point... controls) {
  86.         if (controls.length < degree) throw new IllegalArgumentException("controls.length < degree");
  87.         Point sum = new Point();
  88.         for (int i = 0; i < degree; i++) {
  89.             double x = controls[i].getX();
  90.             double y = controls[i].getY();
  91.             double d = ((int) binomialCoefficient(n, i)) * Math.pow(1 - time, i) * Math.pow(time, i);
  92.             sum.setX(sum.getX() + (d * x));
  93.             sum.setY(sum.getY() + (d * y));
  94.         }
  95.         return sum;
  96.     }
  97.    
  98.     private static long binomialCoefficient (int n, int k) {
  99.         if (k > n - k)
  100.             k = n - k;
  101.         long b = 1;
  102.         for (int i = 1, m = n; i <= k; i++, m--)
  103.             b = b * m / i;
  104.         return b;
  105.     }
  106. }
  107.  
  108. public class PathSerializer {
  109.     public static PathComponent read (DataInput i) {
  110.         int segmentCount = i.readUnsignedShort();
  111.         PathSegment[] segments = new PathSegment[segmentCount];
  112.         for (int j = 0; j < segmentCount; j++)
  113.             segments[j] = readSegment(i);
  114.         PathComponent comp = new PathComponent(segments);
  115.         comp.properties.put("x", Integer.valueOf(i.readUnsignedShort()));
  116.         comp.properties.put("y", Integer.valueOf(i.readUnsignedShort()));
  117.         int ps = i.readUnsignedShort();
  118.         comp.properties.put("precision", Integer.valueOf((ps & 0xF000) >> 12));
  119.         comp.properties.put("stroke", Integer.valueOf(ps & 0x0FFF));
  120.         comp.properties.put("strokeColor", new Color(i.readInt(), true));
  121.         comp.properties.put("fillColor", new Color(i.readInt(), true));
  122.         return comp;
  123.     }
  124.    
  125.     public static boolean write (PathComponent comp, DataOutput o) {
  126.         PathSegment[] segments = comp.getSegments();
  127.         if ((segments.length & 0xFFFF) != segments.length) return false;
  128.         o.writeShort(segments.length);
  129.         for (int i = 0; i < segments.length; i++)
  130.             if (writeSegment(segments[i], o)) return false;
  131.         try {
  132.             o.writeShort(getInt("x", comp.properties));
  133.             o.writeShort(getInt("y", comp.properties));
  134.             int p = getInt("precision", comp.properties);
  135.             if ((p & 0x0F) != p) return false;
  136.             int s = getInt("stroke", comp.properties);
  137.             if ((s & 0x0FFF) != s) return false;
  138.             o.writeShort((p << 12) | s);
  139.         } catch (IllegalArgumentException iae) {
  140.             return false;
  141.         }
  142.         Object color1 = comp.properties.get("strokeColor");
  143.         if (color1 == null || !(color1 instanceof Color)) return false;
  144.         o.writeInt(color1.getRGB());
  145.         Object color2 = comp.properties.get("fillColor");
  146.         if (color2 == null || !(color2 instanceof Color)) return false;
  147.         o.writeInt(color2.getRGB());
  148.     }
  149.    
  150.     private static int getShort (String s, HashMap<String, Object> map) {
  151.         Object o = map.get(s);
  152.         if (o == null || !(o instanceof Integer)) throw new IllegalArgumentException();
  153.         int i = ((Integer) o).intValue();
  154.         if ((i & 0xFFFF) != i) throw new IllegalArgumentException();
  155.         return i;
  156.     }
  157.    
  158.     private static PathSegment readSegment (DataInput i) {
  159.         int degree = i.readUnsignedByte();
  160.         Point[] controls = new Point[degree + 1];
  161.         for (int j = 0; j <= degree; j++) {
  162.             controls[j] = new Point();
  163.             controls[j].setX(i.readUnsignedShort());
  164.             controls[j].setY(i.readUnsignedShort());
  165.         }
  166.         return new PathSegment(degree, controls);
  167.     }
  168.    
  169.     private static boolean writeSegment (PathSegment s, DataOutput o) {
  170.         if ((s.degree & 0xFF) != s.degree) return false;
  171.         o.writeByte(s.degree);
  172.         for (Point c : s.controls) {
  173.             o.writeShort((int) c.getX());
  174.             o.writeShort((int) c.getY());
  175.         }
  176.     }
  177. }
Advertisement
Add Comment
Please, Sign In to add comment