Esempio n. 1
0
// Cohen–Sutherland clipping algorithm clips a line from
// P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with 
// diagonal from (xmin, ymin) to (xmax, ymax).
bool Graph::Clip(Line &r) const
{
	// compute outcodes for P0, P1, and whatever point lies outside the clip rectangle

	uint8_t ca = ComputeOutCode(r.a);
	uint8_t cb = ComputeOutCode(r.b);

	for (;;) 
	{
		if (!(ca | cb)) 
		{ 
			// Bitwise OR is 0. Trivially accept and get out of loop
			return true;
		}
		else if (ca & cb) 
		{ 
			// Bitwise AND is not 0. Trivially reject and get out of loop
			return false;
		} 
		else 
		{
			// failed both tests, so calculate the line segment to clip
			// from an outside point to an intersection with clip edge

			// At least one endpoint is outside the clip rectangle; pick it.
			uint8_t c = ca ? ca : cb;

			// Now find the intersection point;
			// use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0)
			Point p;
			if (c & TOP) {           // point is above the clip rectangle
				p.x = r.a.x + (r.b.x - r.a.x) * (_view->b.y - r.a.y) / (r.b.y - r.a.y);
				p.y = _view->b.y;
			} else if (c & BOTTOM) { // point is below the clip rectangle
				p.x = r.a.x + (r.b.x - r.a.x) * (_view->a.y - r.a.y) / (r.b.y - r.a.y);
				p.y = _view->a.y;
			} else if (c & RIGHT) {  // point is to the right of clip rectangle
				p.y = r.a.y + (r.b.y - r.a.y) * (_view->b.x - r.a.x) / (r.b.x - r.a.x);
				p.x = _view->b.x;
			} else {   // point is to the left of clip rectangle
				p.y = r.a.y + (r.b.y - r.a.y) * (_view->a.x - r.a.x) / (r.b.x - r.a.x);
				p.x = _view->a.x;
			}

			// Now we move outside point to intersection point to clip
			// and get ready for next pass.
			if (c == ca) {
				r.a = p;
				ca = ComputeOutCode(r.a);
			} else {
				r.b = p;
				cb = ComputeOutCode(r.b);
			}
		}
	}
}
Esempio n. 2
0
// Cohen–Sutherland clipping algorithm clips a line from
// P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with
// diagonal from (xmin, ymin) to (xmax, ymax).
void drawline(rgbData data[][WIDTH], int x0, int y0, int x1, int y1,
              struct rgbData color) {
    // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle
    OutCode outcode0 = ComputeOutCode(x0, y0);
    OutCode outcode1 = ComputeOutCode(x1, y1);
    bool accept = false;

    while (true) {
        if (!(outcode0 | outcode1)) { // Bitwise OR is 0. Trivially accept and get out of loop
            accept = true;
            break;
        } else if (outcode0 & outcode1) { // Bitwise AND is not 0. Trivially reject and get out of loop
            break;
        } else {
            // failed both tests, so calculate the line segment to clip
            // from an outside point to an intersection with clip edge
            double x, y;

            // At least one endpoint is outside the clip rectangle; pick it.
            OutCode outcodeOut = outcode0 ? outcode0 : outcode1;

            // Now find the intersection point;
            // use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0)
            if (outcodeOut & TOP) {           // point is above the clip rectangle
                x = x0 + (x1 - x0) * (HEIGHT - 1 - y0) / (double)(y1 - y0);
                y = HEIGHT - 1;
            } else if (outcodeOut & BOTTOM) { // point is below the clip rectangle
                x = x0 + (x1 - x0) * (0 - y0) / (double)(y1 - y0);
                y = 0;
            } else if (outcodeOut & RIGHT) {  // point is to the right of clip rectangle
                y = y0 + (y1 - y0) * (WIDTH - 1 - x0) / (double)(x1 - x0);
                x = WIDTH - 1;
            } else if (outcodeOut & LEFT) {   // point is to the left of clip rectangle
                y = y0 + (y1 - y0) * (0 - x0) / (double)(x1 - x0);
                x = 0;
            }

            // Now we move outside point to intersection point to clip
            // and get ready for next pass.
            if (outcodeOut == outcode0) {
                x0 = (int)x;
                y0 = (int)y;
                outcode0 = ComputeOutCode(x0, y0);
            } else {
                x1 = (int)x;
                y1 = (int)y;
                outcode1 = ComputeOutCode(x1, y1);
            }
        }
    }
    if (accept)
        drawlineUnsafe(data, x0, y0, x1, y1, color);
}
Esempio n. 3
0
File: t.c Progetto: adammaj1/c
// http://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland
// Cohen–Sutherland clipping algorithm clips a line from
// P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with 
// diagonal from (xmin, ymin) to (xmax, ymax).
//void CohenSutherlandLineClipAndDraw(
void dDrawLine(unsigned char A[],double x0, double y0, double x1, double y1, int RayNumber, int color )
{
  // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle
  int outcode0 = ComputeOutCode(x0, y0);
  int outcode1 = ComputeOutCode(x1, y1);
  int accept = 0;
  unsigned int ix0, iy0; // screen coordinate = indices of virtual 2D array 
  unsigned int ix1, iy1; // screen coordinate = indices of virtual 2D array

  while (1) {
    if (!(outcode0 | outcode1)) { // Bitwise OR is 0. Trivially accept and get out of loop
      accept = 1;
      break;
    } else if (outcode0 & outcode1) { // Bitwise AND is not 0. Trivially reject and get out of loop
      break;
    } else {
      // failed both tests, so calculate the line segment to clip
      // from an outside point to an intersection with clip edge
      double x, y;

      // At least one endpoint is outside the clip rectangle; pick it.
      int outcodeOut = outcode0 ? outcode0 : outcode1;

      // Now find the intersection point;
      // use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0)
      if (outcodeOut & TOP) {           // point is above the clip rectangle
	x = x0 + (x1 - x0) * (ZyMax - y0) / (y1 - y0);
	y = ZyMax;
      } else if (outcodeOut & BOTTOM) { // point is below the clip rectangle
	x = x0 + (x1 - x0) * (ZyMin - y0) / (y1 - y0);
	y = ZyMin;
      } else if (outcodeOut & RIGHT) {  // point is to the right of clip rectangle
	y = y0 + (y1 - y0) * (ZxMax - x0) / (x1 - x0);
	x = ZxMax;
      } else if (outcodeOut & LEFT) {   // point is to the left of clip rectangle
	y = y0 + (y1 - y0) * (ZxMin - x0) / (x1 - x0);
	x = ZxMin;
      }

      // Now we move outside point to intersection point to clip
      // and get ready for next pass.
      if (outcodeOut == outcode0) {
	x0 = x;
	y0 = y;
	outcode0 = ComputeOutCode(x0, y0);
      } else {
	x1 = x;
	y1 = y;
	outcode1 = ComputeOutCode(x1, y1);
      }
    }
  }



  if (accept) 
    { // draw line clipped to view window 

     
      // SaveTurns(x0,y0,x1,y1,RayNumber);
      // all segment is inside a window 
      ix0= (x0- ZxMin)/PixelWidth; 
      iy0 = (ZyMax - y0)/PixelHeight; // inverse Y axis 
      ix1= (x1- ZxMin)/PixelWidth; 
      iy1= (ZyMax - y1)/PixelHeight; // inverse Y axis 
      iDrawLine(A, ix0,iy0,ix1,iy1,RayNumber,color) ;}
	
}
Esempio n. 4
0
bool Graph::Clip(Point &p) const
{
	uint8_t ca = ComputeOutCode(p);
	return ca == INSIDE;
}
void oledc_drawLinePrimative(int x0, int y0, int x1, int y1, unsigned int color)
{

  // check rotation, move pixel around if necessary
  switch (TFTROTATION) {
    case 1:
      gfx_swap(x0, y0);
      gfx_swap(x1, y1);
      x0 = TFTWIDTH - x0 - 1;
      x1 = TFTWIDTH - x1 - 1;
      //gfx_swap(x0, x1);
      break;
    case 2:
      gfx_swap(x0, x1);
      gfx_swap(y0, y1);
      x0 = TFTWIDTH - x0 - 1;
      y0 = TFTHEIGHT - y0 - 1;
      x1 = TFTWIDTH - x1 - 1;
      y1 = TFTHEIGHT - y1 - 1;
      break;
    case 3:
      gfx_swap(x0, y0);
      gfx_swap(x1, y1);
      y0 = TFTHEIGHT - y0 - 1;
      y1 = TFTHEIGHT - y1 - 1;
      //gfx_swap(y0, y1);
      break;
  }


  // Cohen–Sutherland clipping algorithm clips a line from
  // P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with
  // diagonal from (xmin, ymin) to (xmax, ymax).
  // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle

  OutCode outcode0 = ComputeOutCode(x0, y0);
  OutCode outcode1 = ComputeOutCode(x1, y1);
  char accept = 0;

  while (1) {
    if (!(outcode0 | outcode1)) { // Bitwise OR is 0. Trivially accept and get out of loop
      accept = 1;
      break;
    } else if (outcode0 & outcode1) { // Bitwise AND is not 0. Trivially reject and get out of loop
      break;
    } else {
      // failed both tests, so calculate the line segment to clip
      // from an outside point to an intersection with clip edge
      int x, y;

      // At least one endpoint is outside the clip rectangle; pick it.
      OutCode outcodeOut = outcode0 ? outcode0 : outcode1;

      // Now find the intersection point;
      // use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0)
      if (outcodeOut & TOP) { // point is above the clip rectangle
        x = x0 + (x1 - x0) * (0 - y0) / (y1 - y0);
        y = 0;
      } else if (outcodeOut & BOTTOM) {           // point is below the clip rectangle
        x = x0 + (x1 - x0) * (TFTHEIGHT - y0 - 1) / (y1 - y0);
        y = TFTHEIGHT - 1;
      } else if (outcodeOut & RIGHT) {  // point is to the right of clip rectangle
        y = y0 + (y1 - y0) * (TFTWIDTH - x0 - 1) / (x1 - x0);
        x = TFTWIDTH - 1;
      } else if (outcodeOut & LEFT) {   // point is to the left of clip rectangle
        y = y0 + (y1 - y0) * (0 - x0) / (x1 - x0);
        x = 0;
      }

      // Now we move outside point to intersection point to clip
      // and get ready for next pass.
      if (outcodeOut == outcode0) {
        x0 = x;
        y0 = y;
        outcode0 = ComputeOutCode(x0, y0);
      } else {
        x1 = x;
        y1 = y;
        outcode1 = ComputeOutCode(x1, y1);
      }
    }
  }
  
  if (accept) {

    oledc_writeCommand(SSD1331_CMD_DRAWLINE, 0);

    oledc_writeCommand(x0, 0);
    oledc_writeCommand(y0, 0);
    oledc_writeCommand(x1, 0);
    oledc_writeCommand(y1, 0);

    oledc_writeCommand((color >> 11) << 1, 0);
    oledc_writeCommand((color >> 5) & 0x3F, 0);
    oledc_writeCommand((color << 1) & 0x3F, 0);

    int _tMark = CNT + (CLKFREQ / 100000);
    while (_tMark > CNT);                         // Wait for system clock target

  }
}
Esempio n. 6
0
// Cohen–Sutherland clipping algorithm clips a line from
// P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with 
// diagonal from (xmin, ymin) to (xmax, ymax).
bool clipLine(const pb_rect &bounds, int &x0, int &y0, int &x1, int &y1)
{
	// compute outcodes for P0, P1, and whatever point lies outside the clip rectangle
	OutCode outcode0 = ComputeOutCode(bounds, x0, y0);
	OutCode outcode1 = ComputeOutCode(bounds, x1, y1);
	bool accept = false;
	double xmin = bounds.x;
	double xmax = bounds.x + bounds.width - 1;
	double ymin = bounds.y;
	double ymax = bounds.y + bounds.height - 1;


	while (true) {
		if (!(outcode0 | outcode1)) { // Bitwise OR is 0. Trivially accept and get out of loop
			accept = true;
			break;
		}
		else if (outcode0 & outcode1) { // Bitwise AND is not 0. Trivially reject and get out of loop
			break;
		}
		else {
			// failed both tests, so calculate the line segment to clip
			// from an outside point to an intersection with clip edge
			double x = 0;
			double y=0;

			// At least one endpoint is outside the clip rectangle; pick it.
			OutCode outcodeOut = outcode0 ? outcode0 : outcode1;

			// Now find the intersection point;
			// use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0)
			if (outcodeOut & LN_TOP) {           // point is above the clip rectangle
				x = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0);
				y = ymax;
			}
			else if (outcodeOut & LN_BOTTOM) { // point is below the clip rectangle
				x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0);
				y = ymin;
			}
			else if (outcodeOut & LN_RIGHT) {  // point is to the right of clip rectangle
				y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0);
				x = xmax;
			}
			else if (outcodeOut & LN_LEFT) {   // point is to the left of clip rectangle
				y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0);
				x = xmin;
			}

			// Now we move outside point to intersection point to clip
			// and get ready for next pass.
			if (outcodeOut == outcode0) {
				x0 = x;
				y0 = y;
				outcode0 = ComputeOutCode(bounds, x0, y0);
			}
			else {
				x1 = x;
				y1 = y;
				outcode1 = ComputeOutCode(bounds, x1, y1);
			}
		}
	}

	return accept;
}
Esempio n. 7
0
void Segmenter:: compute_junctions(const Spot   *spot,
                                   const Vertex &self,
                                   const Vertex &other,
                                   const Tracer *to)
{
    const Coord   klo = spot->klo;
    const Coord   kup = spot->kup;
    
    const Vertex lo( X[klo.x], Y[klo.y]);
    const Vertex up( X[kup.x], Y[kup.y]);
    assert( INSIDE == ComputeOutCode(self,lo,up));
    
    const OutCode other_code = ComputeOutCode(other, lo, up);
    
    if( other_code & LEFT)
    {
        assert( other.x < self.x);
        Segment  &seg = Vert(klo.x);
        Junction *J   = seg.append();
#if JUNCTION_TAG == 1
        J->kind       = Junction::Vert;
        J->tag        = klo.x;
#endif
        J->vertex.x   = seg.value;
        J->alpha      = ( J->vertex.x - self.x)/(other.x - self.x);
        J->vertex.y   = self.y + (J->alpha)*(other.y - self.y);
        FinalizeJunction(J,spot->handle,to);
    }
    
    if( other_code & RIGHT)
    {
        assert( other.x > self.x);
        Segment  &seg = Vert(kup.x);
        Junction *J   = seg.append();
#if JUNCTION_TAG == 1
        J->kind       = Junction::Vert;
        J->tag        = kup.x;
#endif
        J->vertex.x   = seg.value;
        J->alpha      = ( J->vertex.x - self.x)/(other.x - self.x);
        J->vertex.y   = self.y + (J->alpha)*(other.y - self.y);
        FinalizeJunction(J,spot->handle,to);
    }
    
    if( other_code & BOTTOM )
    {
        assert( other.y < self.y );
        Segment  &seg = Horz(klo.y);
        Junction *J   = seg.append();
#if JUNCTION_TAG == 1
        J->kind       = Junction::Horz;
        J->tag        = klo.y;
#endif
        J->vertex.y   = seg.value;
        J->alpha      = (J->vertex.y - self.y)/(other.y-self.y);
        J->vertex.x   = self.x + (J->alpha)*(other.x-self.x);
        FinalizeJunction(J,spot->handle,to);
    }
    
    
    if( other_code & TOP )
    {
        assert( other.y > self.y );
        Segment  &seg = Horz(kup.y);
        Junction *J   = seg.append();
#if JUNCTION_TAG == 1
        J->kind       = Junction::Horz;
        J->tag        = kup.y;
#endif
        J->vertex.y   = seg.value;
        J->alpha      = (J->vertex.y - self.y)/(other.y-self.y);
        J->vertex.x   = self.x + (J->alpha)*(other.x-self.x);
        FinalizeJunction(J,spot->handle,to);
    }
    
    
}
Esempio n. 8
0
// Cohen–Sutherland clipping algorithm clips a line from
// P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with 
// diagonal from (xmin, ymin) to (xmax, ymax).
// Based on http://en.wikipedia.org/wiki/Cohen-Sutherland_algorithm
// return false if line segment outside of bounding box
bool GenGeomAlgs::ClipToBB(double& x0, double& y0, double& x1, double& y1,
						   const double& xmin, const double& ymin,
						   const double& xmax, const double& ymax)
{
	// compute outcodes for P0, P1,
	// and whatever point lies outside the clip rectangle
	int outcode0 = ComputeOutCode(x0, y0, xmin, ymin, xmax, ymax);
	int outcode1 = ComputeOutCode(x1, y1, xmin, ymin, xmax, ymax);
	bool accept = false;
	
	while (true) {
		if (!(outcode0 | outcode1)) {
			// Bitwise OR is 0. Trivially accept and get out of loop
			accept = true;
			break;
		} else if (outcode0 & outcode1) {
			// Bitwise AND is not 0. Trivially reject and get out of loop
			break;
		} else {
			// failed both tests, so calculate the line segment to clip
			// from an outside point to an intersection with clip edge
			double x, y;
			
			// At least one endpoint is outside the clip rectangle; pick it.
			int outcodeOut = outcode0 ? outcode0 : outcode1;
			
			// Now find the intersection point;
			// use formulas y = y0 + slope * (x - x0),
			//   x = x0 + (1 / slope) * (y - y0)
			if (outcodeOut & TOP) {
				// point is above the clip rectangle
				x = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0);
				y = ymax;
			} else if (outcodeOut & BOTTOM) {
				// point is below the clip rectangle
				x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0);
				y = ymin;
			} else if (outcodeOut & RIGHT) {
				// point is to the right of clip rectangle
				y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0);
				x = xmax;
			} else if (outcodeOut & LEFT) {
				// point is to the left of clip rectangle
				y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0);
				x = xmin;
			}
			
			// Now we move outside point to intersection point to clip
			// and get ready for next pass.
			if (outcodeOut == outcode0) {
				x0 = x;
				y0 = y;
				outcode0 = ComputeOutCode(x0, y0, xmin, ymin, xmax, ymax);
			} else {
				x1 = x;
				y1 = y;
				outcode1 = ComputeOutCode(x1, y1, xmin, ymin, xmax, ymax);
			}
		}
	}
	return accept;
}
Esempio n. 9
0
static inline
OutCode ComputeOutCode( const Vertex &r, const Vertex &lo, const Vertex &up) throw()
{
    return ComputeOutCode(r.x, r.y, lo.x, up.x, lo.y, up.y);
}
SDL_bool
SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2,
                         int *Y2)
{
    int x = 0;
    int y = 0;
    int x1, y1;
    int x2, y2;
    int rectx1;
    int recty1;
    int rectx2;
    int recty2;
    int outcode1, outcode2;

    if (!rect) {
        SDL_InvalidParamError("rect");
        return SDL_FALSE;
    }

    if (!X1) {
        SDL_InvalidParamError("X1");
        return SDL_FALSE;
    }

    if (!Y1) {
        SDL_InvalidParamError("Y1");
        return SDL_FALSE;
    }

    if (!X2) {
        SDL_InvalidParamError("X2");
        return SDL_FALSE;
    }

    if (!Y2) {
        SDL_InvalidParamError("Y2");
        return SDL_FALSE;
    }

    /* Special case for empty rect */
    if (SDL_RectEmpty(rect)) {
        return SDL_FALSE;
    }

    x1 = *X1;
    y1 = *Y1;
    x2 = *X2;
    y2 = *Y2;
    rectx1 = rect->x;
    recty1 = rect->y;
    rectx2 = rect->x + rect->w - 1;
    recty2 = rect->y + rect->h - 1;

    /* Check to see if entire line is inside rect */
    if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 &&
        y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) {
        return SDL_TRUE;
    }

    /* Check to see if entire line is to one side of rect */
    if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) ||
        (y1 < recty1 && y2 < recty1) || (y1 > recty2 && y2 > recty2)) {
        return SDL_FALSE;
    }

    if (y1 == y2) {
        /* Horizontal line, easy to clip */
        if (x1 < rectx1) {
            *X1 = rectx1;
        } else if (x1 > rectx2) {
            *X1 = rectx2;
        }
        if (x2 < rectx1) {
            *X2 = rectx1;
        } else if (x2 > rectx2) {
            *X2 = rectx2;
        }
        return SDL_TRUE;
    }

    if (x1 == x2) {
        /* Vertical line, easy to clip */
        if (y1 < recty1) {
            *Y1 = recty1;
        } else if (y1 > recty2) {
            *Y1 = recty2;
        }
        if (y2 < recty1) {
            *Y2 = recty1;
        } else if (y2 > recty2) {
            *Y2 = recty2;
        }
        return SDL_TRUE;
    }

    /* More complicated Cohen-Sutherland algorithm */
    outcode1 = ComputeOutCode(rect, x1, y1);
    outcode2 = ComputeOutCode(rect, x2, y2);
    while (outcode1 || outcode2) {
        if (outcode1 & outcode2) {
            return SDL_FALSE;
        }

        if (outcode1) {
            if (outcode1 & CODE_TOP) {
                y = recty1;
                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
            } else if (outcode1 & CODE_BOTTOM) {
                y = recty2;
                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
            } else if (outcode1 & CODE_LEFT) {
                x = rectx1;
                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
            } else if (outcode1 & CODE_RIGHT) {
                x = rectx2;
                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
            }
            x1 = x;
            y1 = y;
            outcode1 = ComputeOutCode(rect, x, y);
        } else {
            if (outcode2 & CODE_TOP) {
                y = recty1;
                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
            } else if (outcode2 & CODE_BOTTOM) {
                y = recty2;
                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
            } else if (outcode2 & CODE_LEFT) {
                x = rectx1;
                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
            } else if (outcode2 & CODE_RIGHT) {
                x = rectx2;
                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
            }
            x2 = x;
            y2 = y;
            outcode2 = ComputeOutCode(rect, x, y);
        }
    }
    *X1 = x1;
    *Y1 = y1;
    *X2 = x2;
    *Y2 = y2;
    return SDL_TRUE;
}
bool CohenSutherlandLineClipAndDraw(float &x0, float &y0, float &z0, float &x1, float &y1, float &z1)
{
	// compute outcodes for P0, P1, and whatever point lies outside the clip rectangle
	OutCode outcode0 = ComputeOutCode(x0, y0,z0);
	OutCode outcode1 = ComputeOutCode(x1, y1,z1);

	while (true) {
		//std::cout<<x0<<"    "<<y0<<"     "<<z0<<"  "<<std::endl;
		if (!(outcode0 | outcode1)) { // Bitwise OR is 0. Trivially accept and get out of loop
	//		std::cout<<x0<<"    "<<y0<<"     "<<z0<<"  "<<std::endl;
  	//		std::cout<<x1<<"    "<<y1<<"     "<<z1<<"  "<<std::endl<<std::endl;
			return true;
		} else if (outcode0 & outcode1) { // Bitwise AND is not 0. Trivially reject and get out of loop
			return false;
		} else {
			// failed both tests, so calculate the line segment to clip
			// from an outside point to an intersection with clip edge
			float x, y, z;

			// At least one endpoint is outside the clip rectangle; pick it.
			OutCode outcodeOut = outcode0 ? outcode0 : outcode1;

			// Now find the intersection point;
			if (outcodeOut & TOP) {           // point is above the clip rectangle
				x = x0 + (x1 - x0) * (YMAX - y0) / (y1 - y0);
				y = YMAX;
				z = z0 + (z1 - z0) * (YMAX - y0) / (y1 - y0);
			} else if (outcodeOut & BOTTOM) { // point is below the clip rectangle
				x = x0 + (x1 - x0) * (YMIN - y0) / (y1 - y0);
				y = YMIN;
				z = z0 + (z1 - z0) * (YMIN - y0) / (y1 - y0);
			} else if (outcodeOut & RIGHT) {  // point is to the right of clip rectangle
				y = y0 + (y1 - y0) * (XMAX - x0) / (x1 - x0);
				x = XMAX;
				z = z0 + (z1 - z0) * (XMAX - x0) / (x1 - x0);
			} else if (outcodeOut & LEFT) {   // point is to the left of clip rectangle
				y = y0 + (y1 - y0) * (XMIN - x0) / (x1 - x0);
				x = XMIN;
				z = z0 + (z1 - z0) * (XMIN - x0) / (x1 - x0);
			} else if (outcodeOut & BEHIND) {   // point is to the left of clip rectangle
				y = y0 + (y1 - y0) * (ZMIN - z0) / (z1 - z0);
				x = x0 + (x1 - x0) * (ZMIN - z0) / (z1 - z0);
				z = ZMIN;
			} else if (outcodeOut & FRONT) {   // point is to the left of clip rectangle
				y = y0 + (y1 - y0) * (ZMAX - z0) / (z1 - z0);
				x = x0 + (x1 - x0) * (ZMAX - z0) / (z1 - z0);
				z = ZMAX;
			}
			// Now we move outside point to intersection point to clip
			// and get ready for next pass.
			if (outcodeOut == outcode0) {
				x0 = x;
				y0 = y;
				z0 = z;
				outcode0 = ComputeOutCode(x0, y0, z0);
			} else {
				x1 = x;
				y1 = y;
				z1 = z;
				outcode1 = ComputeOutCode(x1, y1,z1);
			}
		}
	}
}
Esempio n. 12
0
void CohenSutherland(double x0, double y0, double x1, double y1)
{
	outcode outcode0, outcode1, outcodeOut;
	bool accept=false, done=false;
	outcode0=ComputeOutCode(x0,y0);
	outcode1=ComputeOutCode(x1,y1);
	do
	{
		if(!(outcode0|outcode1))
		{
			accept=true;
			done=true;
		}
		else if(outcode0&outcode1)
			done=true;
		else
		{
			double x, y;
			outcodeOut=outcode0?outcode0:outcode1;
			if(outcodeOut&TOP)
			{
				x=x0+(x1-x0)*(ymax-y0)/(y1-y0);
				y=ymax;
			}
			else if(outcodeOut&BOTTOM)
			{
				x=x0+(x1-x0)*(ymin-y0)/(y1-y0);
				y=ymin;
			}
			else if(outcodeOut&RIGHT)
			{
				y=y0+(y1-y0)*(xmax-x0)/(x1-x0);
				x=xmax;
			}
			else
			{
				y=y0+(y1-y0)*(xmin-x0)/(x1-x0);
				x=xmin;
			}
			if(outcodeOut==outcode0)
			{
				x0=x;
				y0=y;
				outcode0=ComputeOutCode(x0,y0);
			}
			else
			{
				x1=x;
				y1=y;
				outcode1=ComputeOutCode(x1,y1);
			}
		}
	}while(!done);
	if(accept)
	{
		double sx=(xvmax-xvmin)/(xmax-xmin);
		double sy=(yvmax-yvmin)/(ymax-ymin);
		double vx0=xvmin+(x0-xmin)*sx;
		double vy0=yvmin+(y0-ymin)*sy;
		double vx1=xvmin+(x1-xmin)*sx;
		double vy1=yvmin+(y1-ymin)*sy;
		glColor3f(1.0,0.0,0.0);
		glBegin(GL_LINE_LOOP);
			glVertex2f(xvmin, yvmin);
			glVertex2f(xvmax, yvmin);
			glVertex2f(xvmax, yvmax);
			glVertex2f(xvmin, yvmax);
		glEnd();
		glColor3f(0.0,0.0,1.0);
		glBegin(GL_LINES);
			glVertex2d(vx0,vy0);
			glVertex2d(vx1,vy1);
		glEnd();
	}
}
Esempio n. 13
0
/** Cohen-Sutherland clipping algorithm clips a line from
    P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with 
    diagonal from (xmin, ymin) to (xmax, ymax). **/
void
cohen_sutherland_clip (int * x0, int * y0,int * x1, int * y1, int xmin, int ymin,
                       int xmax, int ymax)
{
  //Outcodes for P0, P1, and whatever point lies outside the clip rectangle
  outcode outcode0, outcode1, outcodeOut;
  bool accept = false, done = false;
  int tx0 = *x0, ty0 = *y0, tx1 = *x1, ty1 = *y1;
 
  //compute outcodes
  outcode0 = ComputeOutCode (tx0, ty0, xmin, ymin, xmax, ymax);
  outcode1 = ComputeOutCode (tx1, ty1, xmin, ymin, xmax, ymax);
 
  do{
    if (!(outcode0 | outcode1))      //logical or is 0. Trivially accept and get out of loop
      {
        accept = true;
        done = true;
      }
    else if (outcode0 & outcode1)   //logical and is not 0. Trivially reject and get out of loop
      done = true;
    else
      {
        //failed both tests, so calculate the line segment to clip
        //from an outside point to an intersection with clip edge
        double x, y;
        //At least one endpoint is outside the clip rectangle; pick it.
        outcodeOut = outcode0? outcode0: outcode1;
        //Now find the intersection point;
        //use formulas y = y0 + slope * (x - x0), x = x0 + (1/slope)* (y - y0)
        if (outcodeOut & TOP)          //point is above the clip rectangle
          {
            x = tx0 + (tx1 - tx0) * (ymax - ty0)/(ty1 - ty0);
            y = ymax;
          }
        else if (outcodeOut & BOTTOM)  //point is below the clip rectangle
          {
            x = tx0 + (tx1 - tx0) * (ymin - ty0)/(ty1 - ty0);
            y = ymin;
          }
        else if (outcodeOut & RIGHT)   //point is to the right of clip rectangle
          {
            y = ty0 + (ty1 - ty0) * (xmax - tx0)/(tx1 - tx0);
            x = xmax;
          }
        else                           //point is to the left of clip rectangle
          {
            y = ty0 + (ty1 - ty0) * (xmin - tx0)/(tx1 - tx0);
            x = xmin;
          }
        //Now we move outside point to intersection point to clip
        //and get ready for next pass.
        if (outcodeOut == outcode0)
          {
            tx0 = x;
            ty0 = y;
            outcode0 = ComputeOutCode (tx0, ty0, xmin, ymin, xmax, ymax);
          }
        else 
          {
            tx1 = x;
            ty1 = y;
            outcode1 = ComputeOutCode (tx1, ty1, xmin, ymin, xmax, ymax);
          }
      }
  }while (!done);
 
  if (accept)
    {
      *x0 = tx0; *x1 = tx1;
      *y0 = ty0; *y1 = ty1;
    }
 
}