举报

easyx 绘图库建议:开放绘图函数,所有构成绘制图形图像的像素点坐标及运动轨迹路线数据,供创造者二次使用。

3

0.标题

easyx 绘图库建议:f规定好坐标点的绘图函数绘制过程像素点运动路径坐标,供创造者使用。

1.发现

就是本身有一些绘制函数,构造他们 ,就需要大量的数学知识,并且大量产生与绘制的运动轨迹坐标点 ,我们使用绘图库的时候,老是需要重复造轮子来驱使运动这些绘图函数,但本身绘图函数,他就是一个造好的轮子,为什么不用轮子来驱使轮子呢?我称之为绘图函数绘制运动轨迹坐标的递归。

2.例如

我画一条规定好坐标直线,让一个小球前后运动反复在这条直线上来回运动,直线很简单,就是一个变量数字加和减,
但是我让这个小球运动在一条规定坐标了直斜线上呢?问题可不就是加和减这么简单,多了一个要素就是斜率。
意思一般情况下就是让一个小球斜着运动,就得重新造一个类似于画直斜线的算法,让他反复去运动,
但是绘图函数直线本身就可以画斜线呀  ,如果可以直接得到绘图函数画的这条斜线上所有构成直斜线像素点的坐标,再通过循环把它循环坐标出来,不就是重新利用,不需要再写算法的吗?不需要再次计算了吗,直斜线只是一条例子,比如矩形,圆形,还有扇形,多段线曲线,等其他绘图函数,呢?开放构成他们图形的绘制路径像素坐标点,就可以让其他绘图函数运动在这个点上,不需要在设计类似于此函数的运动算法。用魔法来打败魔法

3.建议

我的提案是绘图函数,可以组成一个全新的一个绘图数据类型,即构成该绘图函数本身可以通过规定坐标,所有像素点坐标运动轨迹数据类型,该函数可以不绘制出图形,但是可以绘制它的运动轨迹数据,供其他绘图函数使用,估计最好用的例子就是多段线,曲线。

4.程序源码实例

以下是实现一个简单用坐标定位并计算获取所有构成直斜线图像像素点坐函数标例子

使用函数画直斜线,并把画直斜线的运动轨迹坐标保存至数组,再次循环使用,用小球来回前后重复运动可视化直斜线绘制过程。

#include <graphics.h>
#include<math.h>
// 缓冲区画点。
void putpixelqBuffer(DWORD* pibu, int x, int y, int w, int h, COLORREF color)    
{   long zb = (h * y), zb1 = (w - x), ab2 = zb - zb1;
    pibu[abs(-ab2)] = BGR(WHITE);
}
// 交换值。
void abd(int* x1, int* x2, int* y1, int* y2, int* i)
{   *i = *x1; *x1 = *x2; *x2 = *i;
    *i = *y1; *y1 = *y2; *y2 = *i;
}
// 计算求斜率。
long k(int i, float x, float y){return (long)round((x / y) * i);}  
// 点缓冲画任意直线。
int line_s1(int x1, int y1, int x2, int y2, int line_xy[][2])   
{
    int w1 = getwidth(), h1 = getheight(), i, w, h, len = 0;
    if (x1 >= w1 || x2 >= w1 || x1 <=0 || x2<=0|| y1 >= h1 || y2 >= h1 || y1 <= 0 || y2 <= 0)return 0;
   
    DWORD* p = GetImageBuffer();
    if ((w = abs(x1 - x2)) >= (h = abs(y1 - y2)))
    {  if (x1 > x2)abd(&x1, &x2, &y1, &y2, &i);
        if (y1 < y2)
            for (i = 0; i < w; ++i)
                putpixelqBuffer(p, line_xy[i][0] = x1 + i, line_xy[i][1] = y1 + k(i, h, w), w1, h1, WHITE);
        else
            for (i = 0; i < w; ++i)
                putpixelqBuffer(p, line_xy[i][0] = x1 + i, line_xy[i][1] = y1 - k(i, h, w), w1, h1, WHITE);
    }
    else
    {    if (y1 > y2)abd(&x1, &x2, &y1, &y2, &i);
        if (x1 < x2)
            for (i = 0; i < h; ++i)
                putpixelqBuffer(p, line_xy[i][0] = x1 + k(i, w, h), line_xy[i][1] = y1 + i, w1, h1, WHITE);
        else
            for (i = 0; i < h; ++i)
                putpixelqBuffer(p, line_xy[i][0] = x1 - k(i, w, h), line_xy[i][1] = y1 + i, w1, h1, WHITE);
    }
    putpixelqBuffer(p, x2, y2, w1, h1, WHITE);
    return i;
}

int main()
{   initgraph(900, 900);
    // 定义消息变量
    ExMessage m;		
    bool tr = true;
   
    int i = 0, len = 0, xx1 = 1, yy1 = 1, xx2 = 600, yy2 = 600;
    // 存放一条直线的绘制过程的 x_y 坐标二次使用。
    int line_xy[2000][2] = { 0 };
    BeginBatchDraw();
        while(true)
        {   // 改造后的画直线函数,使用二级数组记录画直斜线的所以像素点坐标,并返回像素点坐标长度,搭配 FOR 循环就可以读取。
            len = line_s1(xx1, yy1, xx2, yy2, line_xy);
            if (tr == true)
            {
                if (tr == true)
                    if (i < len)
                    {   // 画跟随规定好坐标直斜线上向下的运动红色小球,
                        i++;
                       setlinecolor(WHITE);
                       fillcircle(line_xy[i][0], line_xy[i][1], 20);
                       setlinecolor(RED);
                       fillcircle(line_xy[i][0], line_xy[i][1], 15);
                       Sleep(5);
                       FlushBatchDraw();
                    }
                if (i == len)
                {tr = false;
                }
            }
            else if (tr == false)
            {
                if (tr == false)
                    if (i > 0)
                    {   // 画跟随规定好坐标直斜线上向上的运动红色小球,
                        i--;
                        setlinecolor(WHITE);
                        fillcircle(line_xy[i][0], line_xy[i][1], 20);
                        setlinecolor(RED);
                        fillcircle(line_xy[i][0], line_xy[i][1], 15);
                        Sleep(5);
                        FlushBatchDraw();
                    }
                if (i == 0)
                {tr = true;
                }
            }
        }
    EndBatchDraw();
    getmessage(EX_CHAR);
    closegraph();
    return 0;
}
ava
随波烂倒

2023-3-3

举报
3

首先,这个功能势必会影响性能。在性能和功能面前如何选择,是个学问。

目前来看,大部分人不需要这个功能。如果加了这个功能,对大部分人来说,都会受到性能影响。少部分需要的,可以通过图形学算法自己实现,并不复杂。

除了性能,还有实现方式上的问题。比如,如果要实现,那应该使用回调函数的形式提供每个点的坐标。但是很多时候,通过回调函数的方式并不方便,例如,你想实现一个小球沿着一条斜线运动,画直线函数可以返回直线上的每个点坐标,并通过回调函数让用户得到每个点的坐标,但这个时候,用户不能在回调函数里加 Sleep 延时,也就没有办法在回调函数里实现让一个小球沿着这条斜线运动。

所以其实,程序自己实现比较方便些。codebus 就有一些作品这么做了,自己写了图形学算法获得需要的每个点坐标并进行后续的处理。

ava
慢羊羊

2023-3-4

我的看法吧,主要是对其他运动轨迹算法不熟纯纯的小白,所以才想偷懒,不过代码巴士里的开源代码的定很顶, -  市蒂露露  2023-3-5
举报
技术讨论社区