5x5显示器圆点平滑,如何避免阶梯效应?
Smooth dot on 5x5 display, how to avoid staircase effect?
我最近买了 BBC-Micro:bit,它有一个小的 5x5 LED "display"。
我想编写没有阶梯效应的绘制平滑移动点的代码,但我正在努力使其在移动时垂直和水平平滑。
这是我的,它只垂直平滑点:
while (true) {
basic.clearScreen()
plotAA(input.acceleration(Dimension.X), input.acceleration(Dimension.Y),
255, 255)
basic.pause(15)
}
function plotAA(_x: number, _y: number, _brightness: number, _scale: number) {
/*
* Draw a dot without "staircase effect"/aliasing.
* _x : from 0 to 4 but in _scale scale
* _y : from 0 to 4 but in _scale scale
* _brightness : led brightness
*
* Half of _scale is a number of [0,0] pixel center
*/
// Keep in mind that numbers are 32 bit signed integers!
let px = (_x + _scale) % _scale * 2 // subpixel x position
let py = (_y + _scale) % _scale * 2 // subpixel y position
// It should be _x / _scale, but to fix a bug I use this...
let rx = (_x + _scale) / _scale - 1 // real x position (ceil)
let ry = (_y + _scale) / _scale - 1 // real y position (ceil)
led.plotBrightness(rx, ry, ((_scale - py) + /* Add something here? */0) * _brightness / _scale)
led.plotBrightness(rx + 1, ry, ((_scale - py)) * _brightness / _scale)
led.plotBrightness(rx, ry + 1, (py) * _brightness / _scale)
led.plotBrightness(rx + 1, ry + 1, (py) * _brightness / _scale)
}
要测试此代码,请使用 https://makecode.microbit.org/(顶部的 select JavaScript)。
如何让它在垂直方向和水平方向同时平滑移动?
我想我可以计算出 4 个 LED 与选定点之间的距离。根据它们的距离,我可以设置 LED 的亮度。这是我所知道的最准确的方法。
编辑:已解决。
// numbers are 32bit signed integers!
while (true) {
basic.pause(30)
basic.clearScreen()
plotAA(input.acceleration(Dimension.X) + 255 * 2, input.acceleration(Dimension.Y) + 255 * 2, 255, 255)
//plotAAY(255 * 2, input.acceleration(Dimension.Y) + 255 * 2, 255, 255)
//plotAAX(input.acceleration(Dimension.X) + 255 * 2, 255 * 2, 255, 255)
}
function plotAAX(_x: number, _y: number, _brightness: number, _scale: number) {
let vertical = false;
/*
* Draw a dot without "staircase effect"/aliasing.
* _x : from 0 to 4 but in _scale scale
* _y : from 0 to 4 but in _scale scale
* _brightness : led brightness
*
* Half of _scale is a number of pixel center
*/
let px = (_x + _scale) % _scale * 2 // subpixel x position
let rx = (_x + _scale) / _scale - 1 // real x position (ceil)
let ry = (_y + _scale) / _scale - 1 // real y position (ceil)
led.plotBrightness(rx, ry, (_scale - px) * _brightness / _scale)
led.plotBrightness(rx + 1, ry, px * _brightness / _scale)
}
function plotAAY(_x: number, _y: number, _brightness: number, _scale: number) {
/*
* Draw a dot without "staircase effect"/aliasing.
* _x : from 0 to 4 but in _scale scale
* _y : from 0 to 4 but in _scale scale
* _brightness : led brightness
*
* Half of _scale is a number of pixel center
*/
let py = (_y + _scale) % _scale * 2 // subpixel y position
let rx = (_x + _scale) / _scale - 1 // real x position (ceil)
let ry = (_y + _scale) / _scale - 1 // real y position (ceil)
led.plotBrightness(rx, ry, (_scale - py) * _brightness / _scale)
led.plotBrightness(rx, ry + 1, py * _brightness / _scale)
}
function plotAA(_x: number, _y: number, _brightness: number, _scale: number) {
/*
* Draw a dot without "staircase effect"/aliasing.
* _x : from 0 to 4 but in _scale scale
* _y : from 0 to 4 but in _scale scale
* _brightness : led brightness
*
* Half of _scale is a number of pixel center
*/
let px = (_x + _scale) % _scale // subpixel x position
let py = (_y + _scale) % _scale // subpixel y position
// -(half of scale) to (half of scale)
let rx = (_x + _scale) / _scale - 1 // real x position (ceil)
let ry = (_y + _scale) / _scale - 1 // real y position (ceil)
led.plotBrightness(rx, ry, Math.max(_scale - distance(0, 0, px, py), 0) * _brightness / _scale)
led.plotBrightness(rx, ry + 1, Math.max(_scale - distance(0, _scale, px, py), 0) * _brightness / _scale)
led.plotBrightness(rx + 1, ry, Math.max(_scale - distance(_scale, 0, px, py), 0) * _brightness / _scale)
led.plotBrightness(rx + 1, ry + 1, Math.max(_scale - distance(_scale, _scale, px, py), 0) * _brightness / _scale)
}
function distance(_1x: number, _1y: number, _2x: number, _2y: number) {
_1x -= _2x
_1y -= _2y
return Math.sqrt(_1x * _1x + _1y * _1y)
}
稍后我会稍微调整一下。
我最近买了 BBC-Micro:bit,它有一个小的 5x5 LED "display"。
我想编写没有阶梯效应的绘制平滑移动点的代码,但我正在努力使其在移动时垂直和水平平滑。
这是我的,它只垂直平滑点:
while (true) {
basic.clearScreen()
plotAA(input.acceleration(Dimension.X), input.acceleration(Dimension.Y),
255, 255)
basic.pause(15)
}
function plotAA(_x: number, _y: number, _brightness: number, _scale: number) {
/*
* Draw a dot without "staircase effect"/aliasing.
* _x : from 0 to 4 but in _scale scale
* _y : from 0 to 4 but in _scale scale
* _brightness : led brightness
*
* Half of _scale is a number of [0,0] pixel center
*/
// Keep in mind that numbers are 32 bit signed integers!
let px = (_x + _scale) % _scale * 2 // subpixel x position
let py = (_y + _scale) % _scale * 2 // subpixel y position
// It should be _x / _scale, but to fix a bug I use this...
let rx = (_x + _scale) / _scale - 1 // real x position (ceil)
let ry = (_y + _scale) / _scale - 1 // real y position (ceil)
led.plotBrightness(rx, ry, ((_scale - py) + /* Add something here? */0) * _brightness / _scale)
led.plotBrightness(rx + 1, ry, ((_scale - py)) * _brightness / _scale)
led.plotBrightness(rx, ry + 1, (py) * _brightness / _scale)
led.plotBrightness(rx + 1, ry + 1, (py) * _brightness / _scale)
}
要测试此代码,请使用 https://makecode.microbit.org/(顶部的 select JavaScript)。
如何让它在垂直方向和水平方向同时平滑移动?
我想我可以计算出 4 个 LED 与选定点之间的距离。根据它们的距离,我可以设置 LED 的亮度。这是我所知道的最准确的方法。
编辑:已解决。
// numbers are 32bit signed integers!
while (true) {
basic.pause(30)
basic.clearScreen()
plotAA(input.acceleration(Dimension.X) + 255 * 2, input.acceleration(Dimension.Y) + 255 * 2, 255, 255)
//plotAAY(255 * 2, input.acceleration(Dimension.Y) + 255 * 2, 255, 255)
//plotAAX(input.acceleration(Dimension.X) + 255 * 2, 255 * 2, 255, 255)
}
function plotAAX(_x: number, _y: number, _brightness: number, _scale: number) {
let vertical = false;
/*
* Draw a dot without "staircase effect"/aliasing.
* _x : from 0 to 4 but in _scale scale
* _y : from 0 to 4 but in _scale scale
* _brightness : led brightness
*
* Half of _scale is a number of pixel center
*/
let px = (_x + _scale) % _scale * 2 // subpixel x position
let rx = (_x + _scale) / _scale - 1 // real x position (ceil)
let ry = (_y + _scale) / _scale - 1 // real y position (ceil)
led.plotBrightness(rx, ry, (_scale - px) * _brightness / _scale)
led.plotBrightness(rx + 1, ry, px * _brightness / _scale)
}
function plotAAY(_x: number, _y: number, _brightness: number, _scale: number) {
/*
* Draw a dot without "staircase effect"/aliasing.
* _x : from 0 to 4 but in _scale scale
* _y : from 0 to 4 but in _scale scale
* _brightness : led brightness
*
* Half of _scale is a number of pixel center
*/
let py = (_y + _scale) % _scale * 2 // subpixel y position
let rx = (_x + _scale) / _scale - 1 // real x position (ceil)
let ry = (_y + _scale) / _scale - 1 // real y position (ceil)
led.plotBrightness(rx, ry, (_scale - py) * _brightness / _scale)
led.plotBrightness(rx, ry + 1, py * _brightness / _scale)
}
function plotAA(_x: number, _y: number, _brightness: number, _scale: number) {
/*
* Draw a dot without "staircase effect"/aliasing.
* _x : from 0 to 4 but in _scale scale
* _y : from 0 to 4 but in _scale scale
* _brightness : led brightness
*
* Half of _scale is a number of pixel center
*/
let px = (_x + _scale) % _scale // subpixel x position
let py = (_y + _scale) % _scale // subpixel y position
// -(half of scale) to (half of scale)
let rx = (_x + _scale) / _scale - 1 // real x position (ceil)
let ry = (_y + _scale) / _scale - 1 // real y position (ceil)
led.plotBrightness(rx, ry, Math.max(_scale - distance(0, 0, px, py), 0) * _brightness / _scale)
led.plotBrightness(rx, ry + 1, Math.max(_scale - distance(0, _scale, px, py), 0) * _brightness / _scale)
led.plotBrightness(rx + 1, ry, Math.max(_scale - distance(_scale, 0, px, py), 0) * _brightness / _scale)
led.plotBrightness(rx + 1, ry + 1, Math.max(_scale - distance(_scale, _scale, px, py), 0) * _brightness / _scale)
}
function distance(_1x: number, _1y: number, _2x: number, _2y: number) {
_1x -= _2x
_1y -= _2y
return Math.sqrt(_1x * _1x + _1y * _1y)
}
稍后我会稍微调整一下。