[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gzz-commits] gzz/gfx/libcoords Coords.cxx
From: |
Asko Soukka |
Subject: |
[Gzz-commits] gzz/gfx/libcoords Coords.cxx |
Date: |
Tue, 22 Oct 2002 08:01:20 -0400 |
CVSROOT: /cvsroot/gzz
Module name: gzz
Changes by: Asko Soukka <address@hidden> 02/10/22 08:01:20
Modified files:
gfx/libcoords : Coords.cxx
Log message:
Culling coordsys proto, needs interface for testing and fixing and
enhancing (assuming, that I didn't missunderstood the whole task ;)
CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gfx/libcoords/Coords.cxx.diff?tr1=1.41&tr2=1.42&r1=text&r2=text
Patches:
Index: gzz/gfx/libcoords/Coords.cxx
diff -u gzz/gfx/libcoords/Coords.cxx:1.41 gzz/gfx/libcoords/Coords.cxx:1.42
--- gzz/gfx/libcoords/Coords.cxx:1.41 Sun Oct 20 05:50:06 2002
+++ gzz/gfx/libcoords/Coords.cxx Tue Oct 22 08:01:20 2002
@@ -631,6 +631,163 @@
};
+ /** Culling coordsys can decide not to be drawn when its
+ * parents' unit squares do not intersect.
+ */
+ class CullingCoordSys : public CoordSys {
+ CoordSys *clipSuper;
+ /** 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
+ */
+ 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);
+ }
+ /** Finds the bounding box of coordsys' unit square after
+ * transformation. Assumes linear coordsys and transforms only
+ * corner's of the unit square.
+ * @param cs coordinate system for the unit square
+ * @param p1 "lower left corner"
+ * @param p2 "upper right corner"
+ */
+ void findBoundingBox(CoordSys *cs, ZPt &p1, ZPt &p2) {
+ int i, j;
+ float x1, y1, x2, y2;
+ for (i=0; i<=1; i++) {
+ for (j=0; j<=1; j++) {
+ if (i==0 && j==0) {
+ /** Initializing. */
+ ZPt tmpPt = cs->transform(ZPt(i, j, 0));
+ x1 = tmpPt.x; y1 = tmpPt.y;
+ x2 = tmpPt.x; y2 = tmpPt.y;
+ } else {
+ /** Comparing. */
+ ZPt tmpPt = cs->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' unit square after
+ * transformation. Because the coordsys may be distorted,
+ * searches bounfing box's coners also within vertices.
+ * @param cs coordinate system for the unit square
+ * @param p1 "lower left corner"
+ * @param p2 "upper right corner"
+ */
+ void findDistortedBoundingBox(CoordSys *cs, ZPt &p1, ZPt &p2) {
+ double i;
+ float x1, y1, x2, y2;
+ /** Initializing. */
+ ZPt o = cs->transform(ZPt(0, 0, 0));
+ x1 = o.x; y1 = o.y;
+ x2 = o.x; y2 = o.y;
+
+ /** Sweeps the unit square's vertices. */
+ /** Vertice (0,0) -> (1,0). */
+ for (i=0.1; i <= 1.0; i+=0.1) {
+ ZPt tmpPt = cs->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,1). */
+ for (i=0.1; i <= 1.0; i+=0.1) {
+ ZPt tmpPt = cs->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,1) -> (1,1) */
+ for (i=0.1; i >= 1.0; i+=0.1) {
+ ZPt tmpPt = cs->transform(ZPt(i, 1, 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 (1,0) -> (1,1) */
+ for (i=0.1; i < 1.0; i+=0.1) {
+ ZPt tmpPt = cs->transform(ZPt(1, 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);
+ }
+ public:
+ CullingCoordSys() : clipSuper(0) { }
+ CullingCoordSys(CoordSys *parent, CoordSys *clip)
+ : CoordSys(parent), clipSuper(clip) { }
+ virtual void setSuper(CoordSys **super) {
+ CoordSys::setSuper(super);
+ this->clipSuper = super[1];
+ }
+ enum { NParams = 0, NPrevious = 2, NParents = 2 };
+ virtual void setParams(float *params) { }
+ virtual CoordSys *createInverse() {
+ return new ConcatCoordSys(super->getInverse(),
clipSuper->getInverse());
+ }
+ virtual void vertex(const ZPt &p) const {
+ super->vertex(p);
+ clipSuper->vertex(p);
+ }
+ virtual ZPt transform(const ZPt &p) const {
+ return super->transform(p);
+ }
+ virtual float nonlinearity(const ZPt &p, float radius) {
+ float n1 = super->nonlinearity(p, radius);
+ float n2 = clipSuper->nonlinearity(super->transform(p), radius);
+ return (n1 > n2 ? n1 : n2);
+ }
+ virtual bool canPerformGL() {
+ return super->canPerformGL() && clipSuper->canPerformGL();
+ }
+ virtual bool performGL() {
+ if(!super->performGL()) return false;
+ return clipSuper->performGL();
+ }
+ /** Cullin coordsys' shouldBeDrawn() returns false if and only if
+ * it's sure that its parents' unit squares do not intersect.
+ */
+ virtual bool shouldBeDrawn() {
+ /** Lower left and upper right points of bounding boxes for
+ * parents' unit squares (after transformation).
+ */
+ ZPt p1, p2, p3, p4;
+
+ if (super->nonlinearity(ZPt(0.5, 0.5, 0), 1/sqrt(2)) != 0)
+ findDistortedBoundingBox(super, p1, p2);
+ else findBoundingBox(super, p1, p2);
+
+ if (clipSuper->nonlinearity(ZPt(0.5, 0.5, 0), 1/sqrt(2)) != 0)
+ findDistortedBoundingBox(clipSuper, p3, p4);
+ else findDistortedBoundingBox(clipSuper, p3, p4);
+
+ return (parallelRectIntersect(p1, p2, p3, p4));
+ }
+ };
+
struct SomeFactory {
virtual int nparams() = 0;
virtual int nprevious() = 0;