簡體   English   中英

你如何在像素陣列中畫一條線

[英]how do you draw a line in a pixel array

我喜歡最大程度地控制屏幕,所以我必須控制每個像素,這有利有弊。 一個缺點是我沒有真正得到任何內置函數的幫助。 所以我不知道如何畫一條線。 我試圖制作一個處理線條繪制的函數,但我無法讓它工作! 這是我用來畫線的代碼

  int startX;
  int startY;
  int deltaX = x1/x2;
  int deltaY = y1/y2;
  float deltaPixl = deltaX/deltaY;
  for(int i=0;i<deltaY;i=i+1){
    if(x1>x2){ startX = x2;}else{ startX=x1;}
    if(y1>y2){ startY = y2;}else{ startY=y1;}
    pixl(startX+i,round(startY+(deltaPixl*i)),0);
  }

它使用了一個名為 pixl 的函數,因此它可以輕松地將像素繪制到像素數組中,只是為了說明為什么在代碼中有一個名為 pixl 的函數。

當我嘗試使用此代碼時,它不會崩潰,就像處理通常在出現錯誤時所做的那樣! 它只是不起作用,而只是什么都不做!

我想要一些關於這個問題的幫助,請。

你可以簡單地使用PGraphics 這個想法是一旦你有了一個 PGraphics 實例,你就可以使用點表示法來訪問曾經使用過的繪圖函數(只要它們在.beginDraw().endDraw()之間被調用)。

使用noSmooth()你可以讓它看起來像素完美。

這是一個基本的草圖來說明這個想法:

// disable anti-aliasing
noSmooth();
// create a PGraphics layer
PGraphics layer = createGraphics(25, 25);
// render a line
layer.beginDraw();
layer.line(0, 24, 24, 0);
layer.endDraw();
// render the line at 100%
image(layer, 0, 0);
// render the line scaled up
image(layer, 0, 0, width, height);

100% 和 400% 比例的光柵化線圖,沒有平滑(鋸齒)

這應該適用於大多數情況。 (只有非常小的值和透明度的更棘手的情況可能會讓您頭疼)

如果由於某種原因您需要更多控制,您可以始終實現自己的光柵化方法。 你可以從一個地方開始是Bresenham's line algorithm

關於您的代碼,有一些事情可能會出錯:

  • float deltaPixl = deltaX/deltaY; :如果 deltaY 為零,您將遇到異常
  • 您正在對deltaXdeltaY進行整數除法(可能使兩個值中的任何一個都為 0)
  • 您應該在帶有開始/結束值的 for 循環之前嘗試println()語句,以了解該循環是否會實際執行。 此外,在for循環中,您可以println(i)來查看是否獲得了您期望的值。

總的來說,我建議查看Kevin Workman 的如何調試指南

此外,您可以使用lerp()計算線的起點和終點之間的線性插值位置。 傳遞每個坐標和歸一化(0.0、1.0 之間)值,其中 0.0 = 在起點,1.0 = 在終點,中間的任何值都在直線上(例如 0.5 = 沿直線的 50%)。

這是一個基本示例:

void drawLinePoints(int x1, int y1, int x2, int y2, int numberOfPoints){
    // for each point  
    for(int i = 0; i < numberOfPoints; i++){
      // map the counter to a normalized (0.0 to 1.0) value for lerp
      // 0.0 = 0 % along the line, 0.5 = 50% along the line, 1.0 = 100% along the line
      float t = map(i, 0, numberOfPoints, 0.0, 1.0);
      // linearly interpolate between the start / end points (and snap to whole pixels (casting to integer type))
      int x = (int)lerp(x1, x2, t);
      int y = (int)lerp(y1, y2, t);
      // render the point
      point(x, y);
    }
  
}

void setup(){
  // render points are large squares
  strokeWeight(6);
  strokeCap(PROJECT);
}

void draw(){
  // clear frame
  background(255);
  // calculate distance
  float distance = dist(10, 10, mouseX, mouseY);
  // map distance the number of points to illustrate interpolation (more points = continuous line)
  int numPoints = (int)distance / 8;
  // render points along the line
  drawLinePoints(10, 10, mouseX, mouseY, numPoints);
}

沿垂直線的插值點呈現為白色背景上的黑色方塊

沿對角線的插值點呈現為白色背景上的黑色方塊

為了完整起見,這里是上面使用pixels[]片段:

void drawLinePoints(int x1, int y1, int x2, int y2, int numberOfPoints){
    // for each point  
    for(int i = 0; i < numberOfPoints; i++){
      // map the counter to a normalized (0.0 to 1.0) value for lerp
      // 0.0 = 0 % along the line, 0.5 = 50% along the line, 1.0 = 100% along the line
      float t = map(i, 0, numberOfPoints, 0.0, 1.0);
      // linearly interpolate between the start / end points (and snap to whole pixels (casting to integer type))
      int x = (int)lerp(x1, x2, t);
      int y = (int)lerp(y1, y2, t);
      // convert the x, y coordinate to pixels array index and render the point in black
      pixels[x + (y * width)] = color(0);
    }
  
}

void setup(){
  noSmooth();
}

void draw(){
  // clear frame
  loadPixels();
  java.util.Arrays.fill(pixels, color(255));
  // calculate distance
  float distance = dist(10, 10, mouseX, mouseY);
  // map distance the number of points to illustrate interpolation (more points = continuous line)
  int numPoints = (int)distance;
  // render points along the line
  drawLinePoints(10, 10, mouseX, mouseY, numPoints);
  // update pixels
  updatePixels();
}

在 100x100 光柵中的捕捉像素處渲染的插值線

我有點晚了,但我在這個網站上找到了一種非常簡單的方法來繪制像素陣列。 這是我在 Monogame 中制作的一個簡單實現(順便說一句,抱歉它沒有使用處理 - 我從未使用過它):

public void drawLine(int x1, int y1, int x2, int y2)
{
    //this will store the colour data of the canvas pixels
    Color[] canvasData = new Color[canvas.Width * canvas.Height];
    //store the pixel data of the canvas in canvasData
    canvas.GetData<Color>(canvasData);

    //drawing line starts here
    int dx = x2 - x1;
    int dy = y2 - y1;

    for (int x = x1; x < x2; x++)
    {
        int y = y1 + dy * (x - x1) / dx;
        //[y*canvas.Width+x] converts the 2d array index to a 1d array index
        canvasData[y * canvas.Width + x] = Color.Black;
    }
    //line drawing ended

    //setting the canvas' pixels to the modified pixels with the line
    canvas.SetData<Color>(canvasData);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM