ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 被拉到窗口的恶意线

2019-08-28 17:05:40  阅读:217  来源: 互联网

标签:2d sfml c math graphics


我正在使用SFML库在C中制作图形程序.到目前为止,我已经能够在屏幕上绘制一个功能.我一路上遇到了两个问题.
第一个是从我的函数结束开始,似乎返回到我的飞机原点的一条线.

你可以在这张图片中看到它:

正如你所看到的那样,这条“流氓”线似乎在接近原点时会改变颜色.我的第一个问题是这条线是什么,如何从窗口消除它?

在这张图片中可以看到第二个问题,这个问题略微不相关且更具数学性:

enter image description here

正如您所见,渐近线是绘制图形未定义或不连续的点.这引出了我的第二个问题:是否有一种方法(在代码中)识别渐近线而不是将其绘制到窗口中.

绘制到窗口的任何内容的代码是:

VertexArray axis(Lines, 4);
VertexArray curve(PrimitiveType::LinesStrip, 1000);

axis[0].position = Vector2f(100000, 0);
axis[1].position = Vector2f(-100000, 0);
axis[2].position = Vector2f(0, -100000);
axis[3].position = Vector2f(0, 100000);

float x;

for (x = -pi; x < pi; x += .0005f)
{
    curve.append(Vertex(Vector2f(x, -tan(x)), Color::Green));
}

我非常感谢任何输入:)

更新:

感谢众多人的输入,这段代码似乎可以很好地解决渐近线问题:

for (x = -30*pi; x < 30*pi; x += .0005f)
{
    x0 = x1; y0 = y1;
    x1 = x; y1 = -1/sin(x);
    a = 0; 
    a = fabs(atan2(y1 - y0, x1 - x0));
    if (a > .499f*pi)
    {
        curve.append(Vertex(Vector2f(x1, y1), Color::Transparent));
    }
    else
    {
        curve.append(Vertex(Vector2f(x1, y1), Color::Green));
    }
}

更新2:

以下代码摆脱了流氓行:

VertexArray curve(Lines, 1000);
float x,y;
for (x = -30 * pi; x < 30 * pi; x += .0005f)
{
    y = -asin(x);
    curve.append(Vertex(Vector2f(x, y)));
}
for (x = -30 * pi + .0005f; x < 30 * pi; x += .0005f)
{
    y = -asin(x);
    curve.append(Vertex(Vector2f(x, y)));
}

解决方法:

第一个问题看起来像是错误的折线/曲线处理.不知道您使用什么API进行渲染,但有些像GDI需要正确启动笔位置.例如,如果你这样绘制:

Canvas->LineTo(x[0],y[0]);
Canvas->LineTo(x[1],y[1]);
Canvas->LineTo(x[2],y[2]);
Canvas->LineTo(x[3],y[3]);
...

然后你应该这样做:

Canvas->MoveTo(x[0],y[0]);
Canvas->LineTo(x[1],y[1]);
Canvas->LineTo(x[2],y[2]);
Canvas->LineTo(x[3],y[3]);
...

如果您的API需要MoveTo命令而您没有设置它,则使用最后位置(或默认值(0,0)),它将曲线的起点与最后一次绘制或默认笔位置的直线连接起来.

第二个问题

在连续数据中,您可以通过检查后续y值来阈值渐近线或不连续点.如果您的曲线渲染如下所示:

Canvas->MoveTo(x[0],y[0]);
for (i=1;i<n;i++) Canvas->LineTo(x[i],y[i]);

然后你可以把它改成这样的东西:

y0=y[0]+2*threshold;
for (i=0;i<n;i++)
 {
 if (y[1]-y0>=threshold) Canvas->MoveTo(x[i],y[i]);
  else                   Canvas->LineTo(x[i],y[i]);
 y0=y[i];
 }

问题是选择阈值,因为它取决于采样点的x密度和y数据的第一个推导x(倾斜角度)

如果要堆叠更多函数,曲线追加将创建不需要的行…而是将每个数据作为单独的绘制处理或将MoveTo命令放在它们之间

[EDIT1]

我觉得这样(假分裂):

double x0,y0,x1,y1,a;
for (e=1,x = -pi; x < pi; x += .0005f)
    {
    // last point
    x0=x1; y0=y1;
    // your actual point
    x1=x; y1=-tan(x);
    // test discontinuity
    if (e) { a=0; e=0; } else a=fabs(atan2(y1-y0,x1-x0));
    if (a>0.499*M_PI) curve.append(Vertex(Vector2f(x1,y1), Color::Black));
     else             curve.append(Vertex(Vector2f(x1,y1), Color::Green));
    }

0.499 * M_PI是你的阈值越近越接近0.5 * M_PI它检测到的跳跃越大……我伪造的曲线被黑色(背景)分开,它会在轴交叉处产生间隙(除非使用透明度)……但是不需要曲线列表……

标签:2d,sfml,c,math,graphics
来源: https://codeday.me/bug/20190828/1754020.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有