有什么方法可以让 y = k*m 但只能是整数吗?
Is there some way to have y = k*m but in integers only?
我正在尝试在 LCD 上写出像素。我在 X、Y 坐标上绘制它们,我正在使用此代码:
void SSD1306_draw_line(uint8_t x0, uint8_t x1, uint8_t y0, uint8_t y1){
uint8_t k = (x1 - x0)/(y1 - y0);
uint8_t y = y0;
for(uint8_t x = x0; x < x1; x++){
pixel(x, y, true);
y += k;
}
}
问题在于,如果 k 变为十进制数,例如 1.98,则 k 仍为 1。如果 k = 2.01,则由于 uint8_t
数据类型,k = 2。
假设我们要绘制直线 (0,0), (40, 20)
{x,y}。
当然,现在 k 将是 2。这行得通!
但是假设如果我们绘制线 (0,0), (35, 20)
{x,y}。
现在 k 将是一个浮点数 1.75。这对我不起作用。
有没有办法找到更好的k?
我已经试过了,但是线不符合坐标。
void SSD1306_draw_line(uint8_t x0, uint8_t x1, uint8_t y0, uint8_t y1){
float k = 0;
if(y1 > x1){
k = (y1 - y0)/(x1 - x0);
}else{
k = (x1 - x0)/(y1 - y0);
}
float y = y0;
for(uint8_t x = x0; x < x1; x++){
pixel(x, (uint8_t) y, true);
y += k;
}
}
将 k
和 y
更改为数据类型 float
的做法是正确的。
但除此之外,您还需要确保
的右侧
k = (y1 - y0)/(x1 - x0);
也将是一个浮点值。目前,由于只涉及整数值,因此右侧表达式的结果将是整数。所以 k
永远不会收到任何小数部分。
到"enforce"浮点除法,其中一个操作数是float
类型就可以了。您可以通过显式强制转换来实现此目的。写,例如:
k = ((float)(y1 - y0))/(x1 - x0);
与其尝试 FP 数学,不如研究 Bresenham's line algorithm 全整数解法。
未经测试的代码:
void SSD1306_draw_line(uint8_t x0, uint8_t x1, uint8_t y0, uint8_t y1) {
int dx = x1 - x0;
int dy = y1 - y0;
int D = 2*dy - dx;
int y = y0;
// code still needs work when x0 > x1 or |dy| > |dx|
for (int x = x0; x <= x1; x++) {
pixel(x,y,true);
if (D > 0) {
y++;
D = D - 2*dx;
}
D = D + 2*dy;
}
}
我正在尝试在 LCD 上写出像素。我在 X、Y 坐标上绘制它们,我正在使用此代码:
void SSD1306_draw_line(uint8_t x0, uint8_t x1, uint8_t y0, uint8_t y1){
uint8_t k = (x1 - x0)/(y1 - y0);
uint8_t y = y0;
for(uint8_t x = x0; x < x1; x++){
pixel(x, y, true);
y += k;
}
}
问题在于,如果 k 变为十进制数,例如 1.98,则 k 仍为 1。如果 k = 2.01,则由于 uint8_t
数据类型,k = 2。
假设我们要绘制直线 (0,0), (40, 20)
{x,y}。
当然,现在 k 将是 2。这行得通!
但是假设如果我们绘制线 (0,0), (35, 20)
{x,y}。
现在 k 将是一个浮点数 1.75。这对我不起作用。
有没有办法找到更好的k?
我已经试过了,但是线不符合坐标。
void SSD1306_draw_line(uint8_t x0, uint8_t x1, uint8_t y0, uint8_t y1){
float k = 0;
if(y1 > x1){
k = (y1 - y0)/(x1 - x0);
}else{
k = (x1 - x0)/(y1 - y0);
}
float y = y0;
for(uint8_t x = x0; x < x1; x++){
pixel(x, (uint8_t) y, true);
y += k;
}
}
将 k
和 y
更改为数据类型 float
的做法是正确的。
但除此之外,您还需要确保
k = (y1 - y0)/(x1 - x0);
也将是一个浮点值。目前,由于只涉及整数值,因此右侧表达式的结果将是整数。所以 k
永远不会收到任何小数部分。
到"enforce"浮点除法,其中一个操作数是float
类型就可以了。您可以通过显式强制转换来实现此目的。写,例如:
k = ((float)(y1 - y0))/(x1 - x0);
与其尝试 FP 数学,不如研究 Bresenham's line algorithm 全整数解法。
未经测试的代码:
void SSD1306_draw_line(uint8_t x0, uint8_t x1, uint8_t y0, uint8_t y1) {
int dx = x1 - x0;
int dy = y1 - y0;
int D = 2*dy - dx;
int y = y0;
// code still needs work when x0 > x1 or |dy| > |dx|
for (int x = x0; x <= x1; x++) {
pixel(x,y,true);
if (D > 0) {
y++;
D = D - 2*dx;
}
D = D + 2*dy;
}
}