如何在Bresenham线图算法中添加颜色梯度功能?

发布于 2025-02-05 19:02:28 字数 775 浏览 3 评论 0原文

我找到了此线程在stackoverflow上,但是我的python理解不太好,无法将其正确地翻译成C,我' M试图将该梯度功能添加到此行绘图算法中:

#define sign(x) ((x > 0)? 1 : ((x < 0)? -1: 0))

x = x1; 
y = y1;
dx = abs(x2 - x1); 
dy = abs(y2 - y1);
s1 = sign(x2 - x1); 
s2 = sign(y2 - y1);
swap = 0;

if (dy > dx) {
    temp = dx;
    dx = dy;
    dy = temp;
    swap = 1;
}

D = 2*dy - dx;
for (i = 0; i < dx; i++) {
    display_pixel (x, y); 
    while (D >= 0) { 
        D = D - 2*dx;
        if (swap)
            x += s1;
        else
            y += s2;
    } 
    D = D + 2*dy;
    if (swap)
        y += s2;
    else
        x += s1; 
} 

我很难问一项琐碎的任务,但我真的不明白python侧的发生了什么,或者是如何表示颜色的(我的是int(0xttrrggbb)) )

I've found this thread on StackOverflow but my python understanding isn't that good to properly translate it to C, I'm trying to add that gradient feature to this line drawing algorithm:

#define sign(x) ((x > 0)? 1 : ((x < 0)? -1: 0))

x = x1; 
y = y1;
dx = abs(x2 - x1); 
dy = abs(y2 - y1);
s1 = sign(x2 - x1); 
s2 = sign(y2 - y1);
swap = 0;

if (dy > dx) {
    temp = dx;
    dx = dy;
    dy = temp;
    swap = 1;
}

D = 2*dy - dx;
for (i = 0; i < dx; i++) {
    display_pixel (x, y); 
    while (D >= 0) { 
        D = D - 2*dx;
        if (swap)
            x += s1;
        else
            y += s2;
    } 
    D = D + 2*dy;
    if (swap)
        y += s2;
    else
        x += s1; 
} 

I feel bad for asking such a trivial task but I really can't understand what is going on on the python side nor how the colours are represented (mine are int(0xttrrggbb))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

习ぎ惯性依靠 2025-02-12 19:02:29

弄清楚了:

#define GAMMA 0.43

//Returns a linear value in the range [0,1]
//for sRGB input in [0,255].
double ChannelInvCompanding(int c)
{
    double y;

    c = c & 0xFF;
    y = (double) c;
    y = y / 255.0;
    if (c <= 0.04045)
        y = y / 12.92;
    else
        y = pow(((y + 0.055) / 1.055), 2.4);
    return (y);
}

//Convert color from 0..255 to 0..1
//Inverse Srgb Companding for 
//Red, Green, and Blue
double  *InverseSrgbCompanding(int c)
{
    double  *r = malloc(4 * sizeof(double));

    r[0] = (double) get_t(c);
    r[1] = ChannelInvCompanding(get_r(c));
    r[2] = ChannelInvCompanding(get_g(c));
    r[3] = ChannelInvCompanding(get_b(c));

    return (r);
}

//Apply companding to Red, Green, and Blue
double ChannelCompanding(double c)
{
    double x;

    if (c <= 0.0031308)
        x = 12.92 * c; 
    else
        x = (1.055 * pow(c, (1/2.4))) - 0.055;
    return (x);
}

//return new color. Convert 0..1 back into 0..255
//Srgb Companding for Red, Green, and Blue
int SrgbCompanding(double *c)
{
    int t;
    int r;
    int g;
    int b;

    t = (int)c[0];
    r = (int)(ChannelCompanding(c[1]) * 255);
    g = (int)(ChannelCompanding(c[2]) * 255);
    b = (int)(ChannelCompanding(c[3]) * 255);
    free(c);
    return (create_trgb(t, r, g, b));
}

//sums channels
//does not include transperancy
double sumChannels(double *c)
{
    double x = c[1] + c[2] + c[3];
    return (x);
}

//Lerping see
//https://en.wikipedia.org/wiki/Linear_interpolation
//#Programming_language_support
double lerp_int(double c1, double c2, double t)
{
    return (c1 * (1 - t) + c2 * t);
    //return ((1 - t) * c1 + t * c2);
}

double  *lerp(double *c1, double *c2, double t)
{
    double  *r = malloc(4 * sizeof(double));

    //r[1] = ((1 - t) * c1[1] + t * c2[1]);
    //r[2] = ((1 - t) * c1[2] + t * c2[2]);
    //r[3] = ((1 - t) * c1[3] + t * c2[3]);
    r[1] = (c1[1] * (1 - t)) + c2[1] * t;
    r[2] = (c1[2] * (1 - t)) + c2[2] * t;
    r[3] = (c1[3] * (1 - t)) + c2[3] * t;
    return (r);
}

typedef struct s_bresvars {
    int x; 
    int y;
    int dx; 
    int dy;
    int s1; 
    int s2;
    int swap;
    int temp;
    int d;
    int i;
}   t_bresvars;



int sign(int x)
{
    if (x > 0)
        return (1);
    else if (x < 0)
        return (-1);
    else
        return (0);
}


void    bresenhams_alg(int x1, int y1, int x2, int y2, int scolor, int ecolor, t_vars *vars)
{
    double step;
    double *color;
    double intensity;
    double total;
    int temp;
    int d;
    int clr;

    double *color1_lin = InverseSrgbCompanding(scolor);
    double bright1 = pow(sumChannels(c.color1_lin), GAMMA);
    double *color2_lin = InverseSrgbCompanding(ecolor);
    double bright2 = pow(sumChannels(c.color2_lin), GAMMA);

    int x = x1; 
    int y = y1;
    int dx = abs(x2 - x1); 
    int dy = abs(y2 - y1);
    int s1 = sign(x2 - x1); 
    int s2 = sign(y2 - y1);
    int swap = 0;
    int i = 0;
    double step_c = 0;

    if (dy > dx) {
        temp = dx;
        dx = dy;
        dy = temp;
        swap = 1;
    }

    d = 2*dy - dx;
    step = (1.0 / dx);
    while (i < dx)
    {
        step_c += step;
        intensity = pow(lerp_int(bright1, bright2, step), (1 / GAMMA));
        color = lerp(color1_lin, color2_lin, step);
        total = sumChannels(color);
        if (total != 0)
            c[1] = (c[1] * intensity / total);
            c[2] = (c[2] * intensity / total);
            c[3] = (c[3] * intensity / total);
        clr = SrgbCompanding(color);
        pixel_put(x, y, clr); 
        while (v.d >= 0)
        { 
            v.d = v.d - 2 * v.dx;
            if (v.swap)
                v.x += v.s1;
            else
                v.y += v.s2;
        } 
        v.d = v.d + 2 * v.dy;
        if (v.swap)
            v.y += v.s2;
        else
            v.x += v.s1;
        v.i++;
    }
    free(color1_lin);
    free(color2_lin);
}

Figured it out:

#define GAMMA 0.43

//Returns a linear value in the range [0,1]
//for sRGB input in [0,255].
double ChannelInvCompanding(int c)
{
    double y;

    c = c & 0xFF;
    y = (double) c;
    y = y / 255.0;
    if (c <= 0.04045)
        y = y / 12.92;
    else
        y = pow(((y + 0.055) / 1.055), 2.4);
    return (y);
}

//Convert color from 0..255 to 0..1
//Inverse Srgb Companding for 
//Red, Green, and Blue
double  *InverseSrgbCompanding(int c)
{
    double  *r = malloc(4 * sizeof(double));

    r[0] = (double) get_t(c);
    r[1] = ChannelInvCompanding(get_r(c));
    r[2] = ChannelInvCompanding(get_g(c));
    r[3] = ChannelInvCompanding(get_b(c));

    return (r);
}

//Apply companding to Red, Green, and Blue
double ChannelCompanding(double c)
{
    double x;

    if (c <= 0.0031308)
        x = 12.92 * c; 
    else
        x = (1.055 * pow(c, (1/2.4))) - 0.055;
    return (x);
}

//return new color. Convert 0..1 back into 0..255
//Srgb Companding for Red, Green, and Blue
int SrgbCompanding(double *c)
{
    int t;
    int r;
    int g;
    int b;

    t = (int)c[0];
    r = (int)(ChannelCompanding(c[1]) * 255);
    g = (int)(ChannelCompanding(c[2]) * 255);
    b = (int)(ChannelCompanding(c[3]) * 255);
    free(c);
    return (create_trgb(t, r, g, b));
}

//sums channels
//does not include transperancy
double sumChannels(double *c)
{
    double x = c[1] + c[2] + c[3];
    return (x);
}

//Lerping see
//https://en.wikipedia.org/wiki/Linear_interpolation
//#Programming_language_support
double lerp_int(double c1, double c2, double t)
{
    return (c1 * (1 - t) + c2 * t);
    //return ((1 - t) * c1 + t * c2);
}

double  *lerp(double *c1, double *c2, double t)
{
    double  *r = malloc(4 * sizeof(double));

    //r[1] = ((1 - t) * c1[1] + t * c2[1]);
    //r[2] = ((1 - t) * c1[2] + t * c2[2]);
    //r[3] = ((1 - t) * c1[3] + t * c2[3]);
    r[1] = (c1[1] * (1 - t)) + c2[1] * t;
    r[2] = (c1[2] * (1 - t)) + c2[2] * t;
    r[3] = (c1[3] * (1 - t)) + c2[3] * t;
    return (r);
}

typedef struct s_bresvars {
    int x; 
    int y;
    int dx; 
    int dy;
    int s1; 
    int s2;
    int swap;
    int temp;
    int d;
    int i;
}   t_bresvars;



int sign(int x)
{
    if (x > 0)
        return (1);
    else if (x < 0)
        return (-1);
    else
        return (0);
}


void    bresenhams_alg(int x1, int y1, int x2, int y2, int scolor, int ecolor, t_vars *vars)
{
    double step;
    double *color;
    double intensity;
    double total;
    int temp;
    int d;
    int clr;

    double *color1_lin = InverseSrgbCompanding(scolor);
    double bright1 = pow(sumChannels(c.color1_lin), GAMMA);
    double *color2_lin = InverseSrgbCompanding(ecolor);
    double bright2 = pow(sumChannels(c.color2_lin), GAMMA);

    int x = x1; 
    int y = y1;
    int dx = abs(x2 - x1); 
    int dy = abs(y2 - y1);
    int s1 = sign(x2 - x1); 
    int s2 = sign(y2 - y1);
    int swap = 0;
    int i = 0;
    double step_c = 0;

    if (dy > dx) {
        temp = dx;
        dx = dy;
        dy = temp;
        swap = 1;
    }

    d = 2*dy - dx;
    step = (1.0 / dx);
    while (i < dx)
    {
        step_c += step;
        intensity = pow(lerp_int(bright1, bright2, step), (1 / GAMMA));
        color = lerp(color1_lin, color2_lin, step);
        total = sumChannels(color);
        if (total != 0)
            c[1] = (c[1] * intensity / total);
            c[2] = (c[2] * intensity / total);
            c[3] = (c[3] * intensity / total);
        clr = SrgbCompanding(color);
        pixel_put(x, y, clr); 
        while (v.d >= 0)
        { 
            v.d = v.d - 2 * v.dx;
            if (v.swap)
                v.x += v.s1;
            else
                v.y += v.s2;
        } 
        v.d = v.d + 2 * v.dy;
        if (v.swap)
            v.y += v.s2;
        else
            v.x += v.s1;
        v.i++;
    }
    free(color1_lin);
    free(color2_lin);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文