- LineClipper added start(x0,y0), clipNext(x1,y1) 'state' clipping mode
- use vec4 array for extrusion colors -> set color only once for all tiles - use full range for direction vector in extrusion vertex
This commit is contained in:
@@ -14,8 +14,6 @@
|
||||
*/
|
||||
package org.oscim.utils;
|
||||
|
||||
import android.graphics.Point;
|
||||
|
||||
/**
|
||||
* @author Hannes Janetzek
|
||||
* taken from http://en.wikipedia.org/wiki/Cohen%E2%80%93
|
||||
@@ -24,14 +22,11 @@ import android.graphics.Point;
|
||||
|
||||
public class LineClipper {
|
||||
|
||||
public static final int INSIDE = 0; // 0000
|
||||
public static final int LEFT = 1; // 0001
|
||||
public static final int RIGHT = 2; // 0010
|
||||
public static final int BOTTOM = 4; // 0100
|
||||
public static final int TOP = 8; // 1000
|
||||
|
||||
// Compute the bit code for a point (x, y) using the clip rectangle
|
||||
// bounded diagonally by (xmin, ymin), and (xmax, ymax)
|
||||
private static final int INSIDE = 0; // 0000
|
||||
private static final int LEFT = 1; // 0001
|
||||
private static final int RIGHT = 2; // 0010
|
||||
private static final int BOTTOM = 4; // 0100
|
||||
private static final int TOP = 8; // 1000
|
||||
|
||||
private int xmin, xmax, ymin, ymax;
|
||||
|
||||
@@ -42,41 +37,71 @@ public class LineClipper {
|
||||
this.ymax = maxy;
|
||||
}
|
||||
|
||||
public boolean clip(Point p1, Point p2) {
|
||||
return clip(p1.x, p1.y, p2.x, p2.y);
|
||||
private int mPrevOutcode;
|
||||
private int mPrevX;
|
||||
private int mPrevY;
|
||||
|
||||
public void clipStart(int x0, int y0) {
|
||||
mPrevX = x0;
|
||||
mPrevY = y0;
|
||||
|
||||
int outcode = INSIDE;
|
||||
if (x0 < xmin)
|
||||
outcode |= LEFT;
|
||||
else if (x0 > xmax)
|
||||
outcode |= RIGHT;
|
||||
if (y0 < ymin)
|
||||
outcode |= BOTTOM;
|
||||
else if (y0 > ymax)
|
||||
outcode |= TOP;
|
||||
|
||||
mPrevOutcode = outcode;
|
||||
}
|
||||
|
||||
public int outCode(int x, int y) {
|
||||
int code;
|
||||
public boolean clipNext(int x1, int y1) {
|
||||
boolean accept;
|
||||
|
||||
code = INSIDE; // initialised as being inside of clip window
|
||||
int outcode = INSIDE;
|
||||
if (x1 < xmin)
|
||||
outcode |= LEFT;
|
||||
else if (x1 > xmax)
|
||||
outcode |= RIGHT;
|
||||
if (y1 < ymin)
|
||||
outcode |= BOTTOM;
|
||||
else if (y1 > ymax)
|
||||
outcode |= TOP;
|
||||
|
||||
if (x < xmin) // to the left of clip window
|
||||
code |= LEFT;
|
||||
else if (x > xmax) // to the right of clip window
|
||||
code |= RIGHT;
|
||||
if (y < ymin) // below the clip window
|
||||
code |= BOTTOM;
|
||||
else if (y > ymax) // above the clip window
|
||||
code |= TOP;
|
||||
if ((mPrevOutcode | outcode) == 0) {
|
||||
// Bitwise OR is 0. Trivially accept
|
||||
accept = true;
|
||||
} else if ((mPrevOutcode & outcode) != 0) {
|
||||
// Bitwise AND is not 0. Trivially reject
|
||||
accept = false;
|
||||
} else {
|
||||
accept = clip(mPrevX, mPrevY, x1, y1, xmin, ymin, xmax, ymax, mPrevOutcode, outcode);
|
||||
}
|
||||
mPrevOutcode = outcode;
|
||||
mPrevX = x1;
|
||||
mPrevY = y1;
|
||||
|
||||
return code;
|
||||
return accept;
|
||||
}
|
||||
|
||||
// CohenSutherland clipping algorithm clips a line from
|
||||
// P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with
|
||||
// diagonal from (xmin, ymin) to (xmax, ymax).
|
||||
public boolean clip(int x0, int y0, int x1, int y1) {
|
||||
// compute outcodes for P0, P1, and whatever point lies outside the clip rectangle
|
||||
int outcode0 = outCode(x0, y0);
|
||||
int outcode1 = outCode(x1, y1);
|
||||
private static boolean clip(int x0, int y0, int x1, int y1,
|
||||
int xmin, int ymin, int xmax, int ymax, int outcode0, int outcode1) {
|
||||
|
||||
boolean accept = false;
|
||||
|
||||
while (true) {
|
||||
if ((outcode0 | outcode1) == 0) { // Bitwise OR is 0. Trivially accept and get out of loop
|
||||
if ((outcode0 | outcode1) == 0) {
|
||||
// Bitwise OR is 0. Trivially accept and get out of loop
|
||||
accept = true;
|
||||
break;
|
||||
} else if ((outcode0 & outcode1) != 0) { // Bitwise AND is not 0. Trivially reject and get out of loop
|
||||
} else if ((outcode0 & outcode1) != 0) {
|
||||
// Bitwise AND is not 0. Trivially reject and get out of loop
|
||||
break;
|
||||
} else {
|
||||
// failed both tests, so calculate the line segment to clip
|
||||
@@ -92,32 +117,45 @@ public class LineClipper {
|
||||
if ((outcodeOut & TOP) != 0) { // point is above the clip rectangle
|
||||
x = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0);
|
||||
y = ymax;
|
||||
} else if ((outcodeOut & BOTTOM) != 0) { // point is below the clip rectangle
|
||||
} else if ((outcodeOut & BOTTOM) != 0) {
|
||||
// point is below the clip rectangle
|
||||
x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0);
|
||||
y = ymin;
|
||||
} else if ((outcodeOut & RIGHT) != 0) { // point is to the right of clip rectangle
|
||||
} else if ((outcodeOut & RIGHT) != 0) {
|
||||
// point is to the right of clip rectangle
|
||||
y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0);
|
||||
x = xmax;
|
||||
} else if ((outcodeOut & LEFT) != 0) { // point is to the left of clip rectangle
|
||||
} else if ((outcodeOut & LEFT) != 0) {
|
||||
// point is to the left of clip rectangle
|
||||
y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0);
|
||||
x = xmin;
|
||||
}
|
||||
|
||||
int outcode = INSIDE;
|
||||
if (x < xmin)
|
||||
outcode |= LEFT;
|
||||
else if (x > xmax)
|
||||
outcode |= RIGHT;
|
||||
if (y < ymin)
|
||||
outcode |= BOTTOM;
|
||||
else if (y > ymax)
|
||||
outcode |= TOP;
|
||||
|
||||
// Now we move outside point to intersection point to clip
|
||||
// and get ready for next pass.
|
||||
if (outcodeOut == outcode0) {
|
||||
x0 = x;
|
||||
y0 = y;
|
||||
outcode0 = outCode(x0, y0);
|
||||
outcode0 = outcode;
|
||||
} else {
|
||||
x1 = x;
|
||||
y1 = y;
|
||||
outcode1 = outCode(x1, y1);
|
||||
outcode1 = outcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO do sth with the result x0...
|
||||
// TODO could do sth with the result x0...
|
||||
return accept;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user