多边形填充完美绘制
c4droid吧
全部回复
仅看楼主
level 12
无锯齿,从左到右纵向画线,高效率,边数可随意调节[酷]
2015年09月05日 06点09分 1
level 12
//放代码
#include "SDL2/SDL.h"
#include<math.h>
#define N 9
int w,h;
SDL_Window *win = NULL;//窗口
SDL_Renderer *render = NULL;//渲染器
int main(int,char**)
{
SDL_Init (SDL_INIT_EVERYTHING);
win=SDL_CreateWindow
("SDL_Window",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, 400,
240, SDL_WINDOW_SHOWN);
render=SDL_CreateRenderer
(win, -1, NULL); //初始化
SDL_GetWindowSize (win,&w,&h);
//获取屏幕宽高
float x=w/2,y=h/2;//多边形坐标
float r=200;//多边形半径
float i;//计步循环体(从左至右绘图)
float t=tan((180-360/(float)N)
/2/180*3.14),
rx=r,b=0,ta,tb,tc;
//主要实现:t为一半的顶角的正切,
//rx为变化半径
//b与i同步以计算rx
int times=0;//控制变化周期次数
SDL_SetRenderDrawColor(render,
0x9f,0x9f,0x9f,0xff);
SDL_RenderClear(render);
SDL_SetRenderDrawColor(render,
0x64,0xff,0x64,0xff);
tc=cos((180-360/(float)N)/2/180*3.14)
*r*2*
cos((180-360/(float)N)/2/180*3.14);
tb=tc;
ta=r;
for (i=-r+1;;i++)
{
b=(ta+i)/tb*tc;
rx=sqrt ((t*b)*(t*b)+(r-b)*(r-b));
//设置变化半径
SDL_RenderDrawLine(render,
i+x,sqrt(rx*rx-i*i)+y,
i+x,-sqrt(rx*rx-i*i)+y);
/*变化一个周期*/
if (b>=tc)
{
b=0;
times+=1;
if (times==(int )N/2)
break;//结束运算
ta=cos(times*(360/N)/180.0*3.14)*r;
tb=ta-cos((times+1)*(360/N)
/180.0*3.14)*r;
}
}
SDL_RenderPresent(render);
SDL_Delay(1000000);
}
2015年09月05日 06点09分 2
level 12
2015年09月05日 06点09分 3
2015年09月05日 06点09分
2015年09月05日 08点09分
level 11
666
2015年09月05日 06点09分 4
level 13
专用楼层[haha][笑眼][OK]
2015年09月05日 08点09分 5
纵向划线可能真的比画斜线速度快哎,前提是SDL的开发者考虑过这种情况,
2015年09月05日 08点09分
@wuli🌺美女 重点是比较均匀
2015年09月05日 08点09分
@硫硝酸酸雨ლ 你为什么不直接弄成函数呢。
2015年09月05日 08点09分
@wuli🌺美女 有道理呀。。。
2015年09月05日 08点09分
level 12
下面讲讲原理,首先看一个画圆
for (i=-r;i<=r;i++)
SDL_RenderDrawLine
(render,
x+i,y+sqrt(r*r-i*i),
x+i,y-sqrt(r*r-i*i));
2015年09月05日 08点09分 6
level 12
不难发现,他是用勾股定理实现的,从左到右依次画线
2015年09月05日 08点09分 7
level 12
那么对于多边形,是否试用呢?
2015年09月05日 08点09分 8
level 12
显然不行,因为多边形的半径随着绘图的点移动而变化
2015年09月05日 08点09分 9
level 12
幸好它的变化是有周期性的
2015年09月05日 08点09分 10
level 12
因此想法就是,反复模拟第一周期的变化,套用上面画圆的算法
2015年09月05日 08点09分 11
level 12
设变化半径为rx,于是得到
2015年09月05日 08点09分 12
level 12
那么如何计算b呢,b应该与循环体i在周期内的位置同步,于是
2015年09月05日 09点09分 13
值得注意的是三角函数所算得的是左正右负,而循环体i是右正左负,所以是ta+i
2015年09月05日 09点09分
level 12
最后通过判断b与tc的大小来实现周期变化的判定,就是这样啦
2015年09月05日 09点09分 14
level 13
火前留
2015年09月05日 09点09分 15
level 12
/*@music_fans_i
函数就在下面啦*/
void drawpoly
(float x,float y,int n,float r)
{
float i;//计步循环体(从左至右绘图)
float
t=tan((180-360/(float)n)/2/180*3.14);
float rx=r,b=0,ta,tb,tc;
//主要实现:t为一半的顶角的正切,
//rx为变化半径
//b与i同步以计算rx
int times=0;//控制变化周期次数
tc=
cos((180-360/(float)n)/2/180*3.14)*r*2*cos((180-360/(float)n)/2/180*3.14);
tb=tc;
ta=r;
for (i=-r+1;;i++)
{
b=(ta+i)/tb*tc;
rx=sqrt ((t*b)*(t*b)+(r-b)*(r-b));
//设置变化半径
SDL_RenderDrawLine(render,
i+x,sqrt(rx*rx-i*i)+y,
i+x,-sqrt(rx*rx-i*i)+y);
/*变化一个周期*/
if (b>=tc)
{
b=0;
times+=1;
if (times==(int )n/2)
break;//结束运算
ta=cos(times*(360/n)/180.0*3.14)*r;
tb=ta-cos((times+1)*(360/n)
/180.0*3.14)*r;
}
}
return ;
}
2015年09月05日 09点09分 16
level 13
填充圆呢?!
2015年09月05日 13点09分 18
level 9
别说什么高效!圆心部重复了n次了…
2015年09月05日 22点09分 19
不是从中心放射式的,是从左到右扫描式的,每个点只画一次
2015年09月06日 10点09分
2015年09月06日 11点09分
level 9
学以致用+1
2015年09月12日 14点09分 20
大量使用三角函数并不能有很好的效率,应尽量使用整数运算
2015年09月12日 15点09分
level 9
我准备做一个任意多边形及曲线填充的方法,这是初步设想,还有一些bug
2015年09月12日 14点09分 21
1 2 尾页