39 |
#define F <vob/trans/LinearPrimitives.hxx> |
#define F <vob/trans/LinearPrimitives.hxx> |
40 |
#include <vob/trans/leaf.hxx> |
#include <vob/trans/leaf.hxx> |
41 |
|
|
42 |
|
#include <vob/intersect.hxx> |
43 |
#include <vob/Debug.hxx> |
#include <vob/Debug.hxx> |
44 |
|
|
45 |
|
using Util::findBoundingBox; |
46 |
|
using Util::findDistortedBoundingBox; |
47 |
|
using Util::parallelRectIntersect; |
48 |
|
|
49 |
namespace Vob { |
namespace Vob { |
50 |
namespace Primitives { |
namespace Primitives { |
51 |
|
|
122 |
|
|
123 |
return (parallelRectIntersect(p1, p2, p3, p4)); |
return (parallelRectIntersect(p1, p2, p3, p4)); |
124 |
} |
} |
|
|
|
|
protected: |
|
|
/** Checks if two parallel rectangle intersects. |
|
|
* "Two rectangles, represented by lower left and upper right points (p1, p2) |
|
|
* and (p3, p4), intersects if and only if the conjunction |
|
|
* (x2 >= x3) && (x4 >= x1) && (y2 >= y3) && (y4 >= y1) |
|
|
* is true. (The rectangles must intersect in both dimensions.)" |
|
|
* @param p1 first rectangle, "lower left corner" |
|
|
* @param p2 first rectangle, "upper right corner" |
|
|
* @param p3 second rectangle, "lower left corner" |
|
|
* @param p4 second rectangle, "upper right corner" |
|
|
* @return true if the given rectangles intersect |
|
|
*/ |
|
|
static bool parallelRectIntersect(ZPt &p1, ZPt &p2, |
|
|
ZPt &p3, ZPt &p4) { |
|
|
return (p2.x > p3.x) && (p4.x > p1.x) && (p2.y > p3.y) && (p4.y > p1.y); |
|
|
} |
|
|
|
|
|
/** Checks if two parallel rectangle are within each other. |
|
|
* @param p1 first rectangle, "lower left corner" |
|
|
* @param p2 first rectangle, "upper right corner" |
|
|
* @param p3 second rectangle, "lower left corner" |
|
|
* @param p4 second rectangle, "upper right corner" |
|
|
* @return true if the given rectangles are within each other. |
|
|
*/ |
|
|
static bool parallelRectWithin(ZPt &p1, ZPt &p2, |
|
|
ZPt &p3, ZPt &p4) { |
|
|
return (p1.x <= p3.x) && (p1.y <= p3.y) && (p4.x <= p2.x) && (p4.y <= p2.y); |
|
|
} |
|
|
|
|
|
/** Finds the bounding box of coordsys' box after |
|
|
* transformation. Assumes linear transform and transforms only |
|
|
* corner's of the box. |
|
|
* @param t the coordinate system, whose box to use |
|
|
* @param p1 "lower left corner" |
|
|
* @param p2 "upper right corner" |
|
|
*/ |
|
|
static void findBoundingBox(const Transform *t, ZPt &p1, ZPt &p2) { |
|
|
float i, j; |
|
|
Pt box = t->getSqSize(); |
|
|
float x1=0, y1=0, x2=0, y2=0; |
|
|
for (i=0; i<=box.x; i+=box.x) { |
|
|
for (j=0; j<=box.y; j+=box.y) { |
|
|
if (i==0 && j==0) { |
|
|
/** Initializing. */ |
|
|
ZPt tmpPt = t->transform(ZPt(i, j, 0)); |
|
|
x1 = tmpPt.x; y1 = tmpPt.y; |
|
|
x2 = tmpPt.x; y2 = tmpPt.y; |
|
|
} else { |
|
|
/** Comparing. */ |
|
|
ZPt tmpPt = t->transform(ZPt(i, j, 0)); |
|
|
if (tmpPt.x < x1) x1 = tmpPt.x; |
|
|
else if (tmpPt.x > x2) x2 = tmpPt.x; |
|
|
if (tmpPt.y < y1) y1 = tmpPt.y; |
|
|
else if (tmpPt.y > y2) y2 = tmpPt.y; |
|
|
} |
|
|
} |
|
|
} |
|
|
p1 = ZPt(x1, y1, 0); |
|
|
p2 = ZPt(x2, y2, 0); |
|
|
} |
|
|
|
|
|
/** Finds the bounding box of coordsys' box after |
|
|
* transformation. Because the transform may be distorted, |
|
|
* searches bounding box's coners also along vertices. |
|
|
* @param t the coordinate system, whose box to use |
|
|
* @param p1 "lower left corner" |
|
|
* @param p2 "upper right corner" |
|
|
*/ |
|
|
static void findDistortedBoundingBox(const Transform *t, ZPt &p1, ZPt &p2) { |
|
|
double i, step_x, step_y; |
|
|
Pt box = t->getSqSize(); |
|
|
float x1, y1, x2, y2; |
|
|
int check_dist; |
|
|
|
|
|
/** Initializing. */ |
|
|
check_dist = 100; // XXX Adjusts the scanning frequency. |
|
|
|
|
|
ZPt o = t->transform(ZPt(0, 0, 0)); |
|
|
ZPt u = t->transform(ZPt(box.x, box.y, 0)); |
|
|
|
|
|
if (fabs(o.x - u.x) / check_dist > box.x) |
|
|
step_x = box.x/(fabs(o.x - u.x) / check_dist); |
|
|
else step_x = box.x; |
|
|
if (fabs(o.y - u.y) / check_dist > box.y) |
|
|
step_y = box.y/(fabs(o.y - u.y) / check_dist); |
|
|
else step_y = box.y; |
|
|
|
|
|
x1 = u.x; y1 = u.y; |
|
|
x2 = u.x; y2 = u.y; |
|
|
|
|
|
/** Sweeps the box's vertices. */ |
|
|
/** Vertice (0,0) -> (w,0). */ |
|
|
for (i=0; i < box.x; i+=step_x) { |
|
|
ZPt tmpPt = t->transform(ZPt(i, 0, 0)); |
|
|
if (tmpPt.x < x1) x1 = tmpPt.x; |
|
|
else if (tmpPt.x > x2) x2 = tmpPt.x; |
|
|
if (tmpPt.y < y1) y1 = tmpPt.y; |
|
|
else if (tmpPt.y > y2) y2 = tmpPt.y; |
|
|
} |
|
|
|
|
|
/** Vertice (0,0) -> (0,h). */ |
|
|
for (i=step_y; i < box.y; i+=step_y) { |
|
|
ZPt tmpPt = t->transform(ZPt(0, i, 0)); |
|
|
if (tmpPt.x < x1) x1 = tmpPt.x; |
|
|
else if (tmpPt.x > x2) x2 = tmpPt.x; |
|
|
if (tmpPt.y < y1) y1 = tmpPt.y; |
|
|
else if (tmpPt.y > y2) y2 = tmpPt.y; |
|
|
} |
|
|
|
|
|
/** Vertice (0,h) -> (w,h) */ |
|
|
for (i=0; i < box.x; i+=step_x) { |
|
|
ZPt tmpPt = t->transform(ZPt(i, box.y, 0)); |
|
|
if (tmpPt.x < x1) x1 = tmpPt.x; |
|
|
else if (tmpPt.x > x2) x2 = tmpPt.x; |
|
|
if (tmpPt.y < y1) y1 = tmpPt.y; |
|
|
else if (tmpPt.y > y2) y2 = tmpPt.y; |
|
|
} |
|
|
|
|
|
/** Vertice (w,0) -> (w,h) */ |
|
|
for (i=0; i < box.y; i+=step_y) { |
|
|
ZPt tmpPt = t->transform(ZPt(box.x, i, 0)); |
|
|
if (tmpPt.x < x1) x1 = tmpPt.x; |
|
|
else if (tmpPt.x > x2) x2 = tmpPt.x; |
|
|
if (tmpPt.y < y1) y1 = tmpPt.y; |
|
|
else if (tmpPt.y > y2) y2 = tmpPt.y; |
|
|
} |
|
|
|
|
|
p1 = ZPt(x1, y1, 0); |
|
|
p2 = ZPt(x2, y2, 0); |
|
|
} |
|
125 |
}; |
}; |
126 |
VOB_PRIMITIVETRANS_DEFINED(Cull, "cull"); |
VOB_PRIMITIVETRANS_DEFINED(Cull, "cull"); |
127 |
} |
} |