예제 #1
0
파일: vfx_line.cpp 프로젝트: ishani/Oddity
// ---------------------------------------------------------------------------------------------------------------------
void WuLine(pixel* frame, Fix16 x1, Fix16 y1, Fix16 x2, Fix16 y2, ColourChoice cc)
{
  byte r = 0;
  byte g = 0;

  Fix16 dx = x2 - x1;
  Fix16 dy = y2 - y1;

  bool swapXY = false;
  if (Fix16::abs(dx) < Fix16::abs(dy))
  {
    XORByteSwap(x1.value, y1.value);
    XORByteSwap(x2.value, y2.value);
    XORByteSwap(dx.value, dy.value);
    swapXY = true;
  }

  if (x2 < x1)
  {
    XORByteSwap(x1.value, x2.value);
    XORByteSwap(y1.value, y2.value);
  }

  Fix16 gradient = dy / dx;

  Fix16 xend = round(x1);
  Fix16 yend = y1 + gradient * (xend - x1);
  Fix16 xgap = rfpart(x1 + 0.5f);
  int16_t xpxl1 = xend.asInt();  // this will be used in the main loop
  int16_t ypxl1 = ipart(yend).asInt();

  GetBasicColour(rfpart(yend) * xgap, cc, r, g);
  setLED(frame, xpxl1, ypxl1, r, g, true, swapXY);

  GetBasicColour(fpart(yend) * xgap, cc, r, g);
  setLED(frame, xpxl1, ypxl1 + 1, r, g, true, swapXY);


  Fix16 intery = yend + gradient; // first y-intersection for the main loop


  // handle second endpoint
  xend = round(x2);
  yend = y2 + gradient * (xend - x2);
  xgap = fpart(x2 + 0.5f);
  int16_t xpxl2 = xend.asInt();  // this will be used in the main loop
  int16_t ypxl2 = ipart(yend).asInt();

  GetBasicColour(rfpart(yend) * xgap, cc, r, g);
  setLED(frame, xpxl2, ypxl2, r, g, true, swapXY);

  GetBasicColour(fpart(yend) * xgap, cc, r, g);
  setLED(frame, xpxl2, ypxl2 + 1, r, g, true, swapXY);

  int16_t xa = xpxl1 + 1;
  int16_t xb = xpxl2 - 1;
  
  if (xb - xa > 120)
    return;

  for (; xa <= xb; xa ++)
  {
    GetBasicColour(rfpart(intery), cc, r, g);
    setLED(frame, xa, ipart(intery).asInt(), r, g, true, swapXY);

    GetBasicColour(fpart(intery), cc, r, g);
    setLED(frame, xa, ipart(intery).asInt() + 1, r, g, true, swapXY);

    intery = intery + gradient;
  }
}
void drawLine(sf::RenderTarget& target, float x1, float y1, float x2, float y2, const sf::Color& color)
{
    float dx = x2 - x1;
    float dy = y2 - y1;

    // Store all points in an arrry
    sf::VertexArray va(sf::Points);

    if (std::fabs(dx) > std::fabs(dy))
    {
        if(x2 < x1)
        {
            std::swap(x1, x2);
            std::swap(y1, y2);
        }

        float gradient = dy / dx;
        float xend = static_cast<float>(round(x1));
        float yend = y1 + gradient * (xend - x1);
        float xgap = rfpart(x1 + 0.5f);

        int xpxl1 = static_cast<int>(xend);
        int ypxl1 = ipart(yend);

        // Add the first endpoint
        plot(va, xpxl1, ypxl1, rfpart(yend) * xgap, color);
        plot(va, xpxl1, ypxl1 + 1, fpart(yend) * xgap, color);

        float intery = yend + gradient;

        xend = static_cast<float>(round(x2));
        yend = y2 + gradient * (xend - x2);
        xgap = fpart(x2 + 0.5f);

        int xpxl2 = static_cast<int>(xend);
        int ypxl2 = ipart(yend);

        // Add the second endpoint
        plot(va, xpxl2, ypxl2, rfpart(yend) * xgap, color);
        plot(va, xpxl2, ypxl2 + 1, fpart(yend) * xgap, color);

        // Add all the points between the endpoints
        for(int x = xpxl1 + 1; x <= xpxl2 - 1; ++x)
        {
            plot(va, x, ipart(intery), rfpart(intery), color);
            plot(va, x, ipart(intery) + 1, fpart(intery), color);
            intery += gradient;
        }
    }
    else
    {
        if(y2 < y1)
        {
            std::swap(x1, x2);
            std::swap(y1, y2);
        }

        float gradient = dx / dy;
        float yend = static_cast<float>(round(y1));
        float xend = x1 + gradient * (yend - y1);
        float ygap = rfpart(y1 + 0.5f);

        int ypxl1 = static_cast<int>(yend);
        int xpxl1 = ipart(xend);

        // Add the first endpoint
        plot(va, xpxl1, ypxl1, rfpart(xend) * ygap, color);
        plot(va, xpxl1, ypxl1 + 1, fpart(xend) * ygap, color);

        float interx = xend + gradient;

        yend = static_cast<float>(round(y2));
        xend = x2 + gradient * (yend - y2);
        ygap = fpart(y2 + 0.5f);

        int ypxl2 = static_cast<int>(yend);
        int xpxl2 = ipart(xend);

        // Add the second endpoint
        plot(va, xpxl2, ypxl2, rfpart(xend) * ygap, color);
        plot(va, xpxl2, ypxl2 + 1, fpart(xend) * ygap, color);

        // Add all the points between the endpoints
        for(int y = ypxl1 + 1; y <= ypxl2 - 1; ++y)
        {
            plot(va, ipart(interx), y, rfpart(interx), color);
            plot(va, ipart(interx) + 1, y, fpart(interx), color);
            interx += gradient;
        }
    }

    target.draw(va);
}
예제 #3
0
void MapGenerator::processScanPoint(double start_x, double start_y, double angle, double distance) {
    // anti-aliased ray tracing, taken from:
    // http://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
    double x0 = (start_x - x_min) / map_resolution;
    double y0 = (start_y - y_min) / map_resolution;

    // account for robot itself
    for (int i = -2; i <= 2; i++) {
        for (int j = -2; j <= 2; j++) {
            updateOdds(x0 + i, y0 + j, start_x, start_y, distance);
        }
    }

    double end_x = start_x + range_max * cos(angle);
    double end_y = start_y + range_max * sin(angle);
    double x1 = (end_x - x_min) / map_resolution;
    double y1 = (end_y - y_min) / map_resolution;

    double dx = x1 - x0;
    double dy = y1 - y0;
    bool steep = false;
    if (fabs(dx) < fabs(dy)) {
        swap(&x0, &y0);
        swap(&x1, &y1);
        swap(&dx, &dy);
        steep = true;
    }
    if (x1 < x0) {
        swap(&x0, &x1);
        swap(&y0, &y1);
    }
    double gradient = dy / dx;

    double xend = round(x0);
    double yend = y0 + gradient * (xend - x0);
    double xgap = rfpart(x0 + 0.5);
    int xpxl1 = (int) xend;
    int ypxl1 = (int) yend;

    if (steep) {
        updateOdds(ypxl1, xpxl1, start_x, start_y, distance);
        updateOdds(ypxl1+1, xpxl1, start_x, start_y, distance);
    } else {
        updateOdds(xpxl1, ypxl1, start_x, start_y, distance);
        updateOdds(xpxl1, ypxl1+1, start_x, start_y, distance);
    }
    double intery = yend + gradient;

    xend = round(x1);
    yend = y1 + gradient * (xend - x1);
    xgap = fpart(x1 + 0.5);
    int xpxl2 = (int) xend;
    int ypxl2 = (int) yend;
    // plot xpxl2, ypxl2, rfpart(yend) * xgap
    // plot xpxl2, ypxl2 + 1, fpart(yend) * xgap

    // main loop
    for (int x = xpxl1 + 1; x <= xpxl2 - 1; x++) {
        // plot x,
        if (steep) {
            updateOdds((int) intery, x, start_x, start_y, distance);
            updateOdds((int) (intery+1), x, start_x, start_y, distance);
        } else {
            updateOdds(x, (int) intery, start_x, start_y, distance);
            updateOdds(x, (int) (intery+1), start_x, start_y, distance);
        }
        intery += gradient;
    }
}
예제 #4
0
void muiBBWindow::DrawLineFloat(float x0, float y0, float x1, float y1, muiColor clr)
// Xiaolin Wu's line algorithm 
{
	if (!pclrBitmap) return;

	int ix, iy, ie;

    float dx = x1 - x0, x;
    float dy = y1 - y0, y;
	float c, v, gradient, xend, yend, gap;
   
	if (fabsf(dx) > fabsf(dy)) {
		
		// Handle "horizontal" lines
		if (x1 < x0) {
			swap(x0, x1);
			swap(y0, y1);
		}	
		gradient = dy / dx;
   
		// Handle 1st endpoint
		xend = fround(x0);
		yend = y0 + gradient * (xend - x0);
		gap = rfpart(x0 + 0.5f);
		ix = int(floorf(xend));
		iy = int(floorf(yend));
		c = fpart(yend);

		DrawPixelBlend({ ix, iy++ }, clr, (1.0f - c) * gap);
		DrawPixelBlend({ ix++, iy }, clr, (c)* gap);
     
		y = yend + gradient; // first y-intersection for the main loop
 
		// Handle 2nd endpoint
		xend = fround(x1);
		yend = y1 + gradient * (xend - x1);
		gap = fpart(x1 + 0.5f);
		ie = int(ipart(xend));
		iy  = int(ipart(yend));
		c = fpart(yend);

		DrawPixelBlend({ ie, iy++ }, clr, (1.0f - c) * gap);
		DrawPixelBlend({ ie--, iy }, clr, (c)* gap);

		// Handle mid-points
		while (ix <= ie) {

			v = ipart(y);
			iy = int(v);
			c = y - v;
			y += gradient;

			DrawPixelBlend({ ix, iy++ }, clr, (1.0f - c));
			DrawPixelBlend({ ix++, iy }, clr, (c));
		}

	} else {
		// Handle "vertical" lines
		if (y1 < y0) {
			swap(y0, y1);
			swap(x0, x1);
		}	
		gradient = dx / dy;
   
		// Handle 1st endpoint
		yend = fround(y0);
		xend = x0 + gradient * (yend - y0);
		gap = rfpart(y0 + 0.5f);
		iy = int(ipart(yend));
		ix = int(ipart(xend));
		c = fpart(xend);

		DrawPixelBlend({ ix++, iy }, clr, (1.0f - c) * gap);
		DrawPixelBlend({ ix, iy++ }, clr, (c)* gap);
     
		x = xend + gradient; // first x-intersection for the main loop
 
		// Handle 2nd endpoint
		yend = fround(y1);
		xend = x1 + gradient * (yend - y1);
		gap = fpart(y1 + 0.5f);
		ie = int(ipart(yend));
		ix  = int(ipart(xend));
		c = fpart(xend);

		DrawPixelBlend({ ix++, ie }, clr, (1.0f - c) * gap);
		DrawPixelBlend({ ix, ie-- }, clr, (c)* gap);

		// Handle mid-points
		while (iy <= ie) {

			v = ipart(x);
			ix = int(v);
			c = x - v;
			x += gradient;

			DrawPixelBlend({ ix++, iy }, clr, (1.0f - c));
			DrawPixelBlend({ ix, iy++ }, clr, (c));
		}
	}
}
예제 #5
0
파일: Pen.cpp 프로젝트: dparks1134/Art
// Draw antialiased line using Wu's algorithm.
void Line::lineWu(int x0, int y0, int x1, int y1, std::vector<Point>& points, std::vector<float>& alpha)
{
	bool bSteep = abs(int(y1 - y0)) > abs(int(x1 - x0));
 
	if(bSteep)
	{
		std::swap(x0, y0);
		std::swap(x1, y1);
	}

	if(x0 > x1)
	{
		std::swap(x0, x1);
		std::swap(y0, y1);
	}
 
	float dx = float(x1 - x0);
	float dy = float(y1 - y0);
	float gradient = float(dy) / dx;
 
	// handle first endpoint
	uint xend = round(float(x0));
	float yend = y0 + gradient * (xend - x0);
	float xgap = rfpart(x0 + 0.5f);
	uint xpxl1 = xend;   //this will be used in the main loop
	uint ypxl1 = ipart(yend);

	if(bSteep)
	{
		points.push_back(Point(ypxl1, xpxl1));
		alpha.push_back(rfpart(yend) * xgap);

		points.push_back(Point(ypxl1+1, xpxl1));
		alpha.push_back(fpart(yend) * xgap);
	}
	else
	{
		points.push_back(Point(xpxl1, ypxl1));
		alpha.push_back(rfpart(yend) * xgap);

		points.push_back(Point(xpxl1, ypxl1+1));
		alpha.push_back(fpart(yend) * xgap);
	}

	float intery = yend + gradient; // first y-intersection for the main loop
 
     // handle second endpoint
	xend = round(float(x1));
	yend = y1 + gradient * (xend - x1);
	xgap = fpart(x1 + 0.5f);
	uint xpxl2 = xend; //this will be used in the main loop
	uint ypxl2 = ipart(yend);
	if(bSteep)
	{
		points.push_back(Point(ypxl2, xpxl2));
		alpha.push_back(rfpart(yend) * xgap);

		points.push_back(Point(ypxl2+1, xpxl2));
		alpha.push_back(fpart(yend) * xgap);
	}
	else
	{
		points.push_back(Point(xpxl2, ypxl2));
		alpha.push_back(rfpart(yend) * xgap);

		points.push_back(Point(xpxl2, ypxl2+1));
		alpha.push_back(fpart(yend) * xgap);
	}

	// main loop
	for(uint x = xpxl1 + 1; x < xpxl2; ++x)
	{
		if(bSteep)
		{
			points.push_back(Point(ipart(intery), x));
			alpha.push_back(rfpart(intery));

			points.push_back(Point(ipart(intery)+1, x));
			alpha.push_back(fpart(intery));
		}
		else
		{
			points.push_back(Point(x, ipart(intery)));
			alpha.push_back(rfpart(intery));

			points.push_back(Point(x, ipart(intery)+1));
			alpha.push_back(fpart(intery));
		}
		intery = intery + gradient;
	}
}