# HG changeset patch # User Sascha L. Teichmann # Date 1260801403 0 # Node ID 555483213f78f6c13eaf32ca7d42d34012742fa0 # Parent ec95d32485767d301def064652fdca7834e21a33 Added buffer creator in index (i, j) space. gnv-artifacts/trunk@419 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r ec95d3248576 -r 555483213f78 gnv-artifacts/ChangeLog --- a/gnv-artifacts/ChangeLog Fri Dec 11 11:18:21 2009 +0000 +++ b/gnv-artifacts/ChangeLog Mon Dec 14 14:36:43 2009 +0000 @@ -1,3 +1,9 @@ +2009-12-14 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/utils/IndexBuffer.java: + Creates SQL-WHERE clauses for buffers around a list of + line segments in index (i, j) space. + 2009-12-11 Ingo Weinzierl * src/main/java/de/intevation/gnv/state/profile/horizontal/HorizontalProfileOutputState.java: diff -r ec95d3248576 -r 555483213f78 gnv-artifacts/src/main/java/de/intevation/gnv/utils/IndexBuffer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/IndexBuffer.java Mon Dec 14 14:36:43 2009 +0000 @@ -0,0 +1,169 @@ +package de.intevation.gnv.utils; + +import java.awt.geom.Point2D; + +import java.awt.Point; + +import java.util.List; + +/** + * Create buffers around integer pairs (i_1..n), j_1..n). + * + * @author Sascha L. Teichmann (sascha.teichmann@intevation.de) + */ +public class IndexBuffer +{ + public static final double EPSILON = 1e-6d; + public static final double OFFSET = 1.0d; + + public static final String I_COLUMN = "IPOSITION"; + public static final String J_COLUMN = "JPOSITION"; + + public static final class Segment { + + private Segment next; + + private Point2D.Double n; + private double d1; + private double d2; + + private int iMin; + private int iMax; + + private int jMin; + private int jMax; + + public Segment(Point a, Point b, Segment next) { + + this.next = next; + + iMin = Math.min(a.x, b.x)-1; + iMax = Math.max(a.x, b.x)+1; + + jMin = Math.min(a.y, b.y)-1; + jMax = Math.max(a.y, b.y)+1; + + if (a.x > b.x) { + Point p = a; a = b; b = p; + } + + Point2D.Double p1, p2, p3; + + if (a.y < b.y) { + p1 = new Point2D.Double(a.x - OFFSET, a.y + 1 + OFFSET); + p2 = new Point2D.Double(b.x - OFFSET, b.y + 1 + OFFSET); + p3 = new Point2D.Double(a.x + 1 + OFFSET, a.y - OFFSET); + } + else { + p1 = new Point2D.Double(a.x + 1 + OFFSET, a.y + 1 + OFFSET); + p2 = new Point2D.Double(b.x + 1 + OFFSET, b.y + 1 + OFFSET); + p3 = new Point2D.Double(b.x - OFFSET, b.y - OFFSET); + } + + n = normalize(orthogonal(sub(p1, p2))); + + d1 = dot(n, p1); + d2 = dot(n, p3); + + if (d1 > d2) { + double d = d1; + d1 = d2; + d2 = d; + } + } + + public boolean check(int i, int j) { + if (i < iMin || i > iMax || j < jMin || j > jMax) { + return false; + } + double v = dot(n, i, j); + return v >= d1 && v <= d2; + } + + public void toWhereClause(StringBuilder sb, String iColumn, String jColumn) { + sb.append('(') + .append(iColumn).append(" >= ").append(iMin).append(" AND ") + .append(iColumn).append(" <= ").append(iMax).append(" AND ") + .append(jColumn).append(" >= ").append(jMin).append(" AND ") + .append(jColumn).append(" <= ").append(jMax).append(" AND (") + .append(n.x).append('*').append(iColumn).append(" + ") + .append(n.y).append('*').append(jColumn) + .append(") BETWEEN ").append(d1).append(" AND ").append(d2).append(')'); + } + } // class Segment + + protected Segment head; + + protected String iColumn; + protected String jColumn; + + public IndexBuffer(List points) { + this(points, I_COLUMN, J_COLUMN); + } + + public IndexBuffer(List points, String iColumn, String jColumn) { + this.iColumn = iColumn; + this.jColumn = jColumn; + + for (int i = 1, N = points.size(); i < N; ++i) { + Point p1 = (Point)points.get(i-1); + Point p2 = (Point)points.get(i); + head = new Segment(p1, p2, head); + } + } + + public boolean check(int i, int j) { + + Segment current = head; + while (current != null) { + if (current.check(i, j)) { + return true; + } + current = current.next; + } + return false; + } + + public String toWhereClause() { + + StringBuilder sb = new StringBuilder(); + + Segment current = head; + + while (current != null) { + if (current != head) { + sb.append(" OR "); + } + current.toWhereClause(sb, iColumn, jColumn); + current = current.next; + } + + return sb.toString(); + } + + public static Point2D.Double sub(Point2D.Double p1, Point2D.Double p2) { + return new Point2D.Double(p1.x - p2.x, p1.y - p2.y); + } + + public static final double dot(Point2D.Double p1, Point2D.Double p2) { + return p1.x*p2.x + p1.y*p2.y; + } + + public static final double dot(Point2D.Double p1, double x, double y) { + return p1.x*x + p1.y*y; + } + + public static final Point2D.Double scale(Point2D.Double p, double s) { + return new Point2D.Double(s*p.x, s*p.y); + } + + public static final Point2D.Double normalize(Point2D.Double p) { + double len2 = Math.sqrt(dot(p, p)); + return len2 > EPSILON ? scale(p, 1d/len2) : p; + } + + public static final Point2D.Double orthogonal(Point2D.Double p) { + return new Point2D.Double(p.y, -p.x); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: