Javascript 平滑点在5x5显示器上,如何避免楼梯效果?

Javascript 平滑点在5x5显示器上,如何避免楼梯效果?,javascript,graphics,antialiasing,bbc-microbit,Javascript,Graphics,Antialiasing,Bbc Microbit,我最近得到了BBC Micro:bit,它有一个小的5x5 led显示屏 我想让代码在没有楼梯效果的情况下画出平滑的移动点,但我正在努力使它在移动时垂直和水平平滑 这就是我所拥有的,它只在垂直方向上平滑圆点: while (true) { basic.clearScreen() plotAA(input.acceleration(Dimension.X), input.acceleration(Dimension.Y), 255, 255) basic.p

我最近得到了BBC Micro:bit,它有一个小的5x5 led显示屏

我想让代码在没有楼梯效果的情况下画出平滑的移动点,但我正在努力使它在移动时垂直和水平平滑

这就是我所拥有的,它只在垂直方向上平滑圆点:

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)
}
要测试此代码,请使用顶部的selectjavascript


如何使其在垂直和水平方向上同时平滑移动?

我想我可以计算出4个led与所选点之间的距离。根据它们的距离,我可以设置led的亮度。这是我所知道的最准确的方法

编辑:已解决


稍后我将对其进行调整。

我想我可以计算出4个led与选定点之间的距离。根据它们的距离,我可以设置led的亮度。这是我所知道的最准确的方法

编辑:已解决


稍后我会稍微调整一下。

亚像素精度如何。。。通过出血的亮度,以所有像素的覆盖率接触点。。。但这是可行的,只有当你可以设置每个像素单独的亮度,例如通过PWM或其他。。。。所以问题是你的显示器怎么样connected@Spektre我想我可以计算出4个led之间的距离。根据它们的距离,我可以设置它们的亮度。我认为这是最准确的方法。它与双线性插值正好相反。。。。您可以使用/tweak | dot|u position-pixel|u center |作为亮度比。不过5x5的分辨率很小,所以不要指望它能带来奇迹……我不指望它能完美工作,我只希望它能更平滑一点,应该足够好。亚像素精度呢。。。通过出血的亮度,以所有像素的覆盖率接触点。。。但这是可行的,只有当你可以设置每个像素单独的亮度,例如通过PWM或其他。。。。所以问题是你的显示器怎么样connected@Spektre我想我可以计算出4个led之间的距离。根据它们的距离,我可以设置它们的亮度。我认为这是最准确的方法。它与双线性插值正好相反。。。。您可以使用/tweak | dot|u position-pixel|u center |作为亮度比。不过5x5的分辨率很小,所以不要指望它能带来奇迹…我不指望它能完美工作,我只希望它能更平滑一点,应该足够好。在中发现了伽马校正,效果非常好!我认为有更好的方法可以做到这一点,但我不认为我需要在一帧中画这么多的点,以至于它会变得滞后。这不是最好的解决方案,但效果很好!一个点大约用1ms绘制,所以我可以有41个点,led每秒更新24次24 FPS,这就足够了。添加了在中发现的伽马校正,效果非常好!我认为有更好的方法可以做到这一点,但我不认为我需要在一帧中画这么多的点,以至于它会变得滞后。这不是最好的解决方案,但效果很好!一个点大约在1ms内绘制,所以我可以有41个点,led每秒更新24次24 FPS,这就足够了。
// 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)
}