VB中给圆填充颜色的算法怎么写

幻日 2013-10-23 12:08:44
这是我画的一个圆
 Dim a As Single
Dim b As Single

Private Sub picdraw_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
a = X
b = Y
End Sub

Private Sub picdraw_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = 1 Then
Picdraw.Cls
Picdraw.Circle ((a + X) / 2, (b + Y) / 2), (((a - X) ^ 2 + (b - Y) ^ 2) ^ 0.5) / 2, RGB(0, 0, 0)
End If

End Sub
...全文
1574 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2013-11-07
  • 打赏
  • 举报
回复
扫描线种子填充算法参考下面:
//试题编号:0186
//海龟圈地
//难度级别:D; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
//试题描述
//  海龟小蛮在沙滩上趾高气扬地走来走去,并且蛮横地宣布:“凡我足迹所到之处均为本海龟的领地。”
//  海龟的任何行动均可分解为下面三个基本动作:
//      f 向前爬一格
//      l 原地左转90度
//      r 原地右转90度
//  由于小蛮不允许别的海龟经过它的领地,所以,由它足迹围成的封闭区域也就都成了它的领地。
//  你的任务是编程序根据文件输入的小蛮的一系列基本动作,计算出小蛮共霸占了多少格的领地。
//  程序文件主名为turtle。
//  为加深对题意的理解,我们观察下面的基本动作序列:
//      flffflfffrfrrffflf
//  小蛮在出发点当然会留下足迹#,如果把它开始的方向设为向下,可以把它的足迹(用*标出的位置)画成下面的示意图:
//       ****
//       * *
//      #  *
//      ****
//  显然,小蛮的领地总数为15格。
//输入
//  其中只有一个长度不超过1000的字符串,且该字符串不包含'f'、'l'、'r'之外的字符。
//输出
//  其中只有一个正整数,即领地总格数。
//输入示例
//  flffflfffrfrrffflf
//输出示例
//  15
//其他说明
//  2011年北京市海淀区中学组赛题
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 1000
static char n[2*MAXN+2][2*MAXN+2];//记录某处被爬过信息:0未爬过|1爬过
char f;//当前方向'N'|'S'|'W'|'E'
int x,y;//当前位置
char p[MAXN+1];
int i,L;
int a,b,h,t;
int sp=0;
int x1[MAXN];
int x2[MAXN];
int y1[MAXN];
int yy1,xx1,xx2;
void push(int ay1,int ax1,int ax2) {
    y1[sp]=ay1;
    x1[sp]=ax1;
    x2[sp]=ax2;
    if (sp<MAXN-1) {
        sp=sp+1;
    } else {
        printf("stack overflow!\n");
        exit(1);
    }
}
void pop(void) {
    sp=sp-1;
    yy1=y1[sp];
    xx1=x1[sp];
    xx2=x2[sp];
}
//void show() {
//  int zy,zx;
//
//  for (zy=0;zy<2*MAXN+2;zy++) {
//      for (zx=0;zx<2*MAXN+2;zx++) {
//          printf("%d",n[zy][zx]);
//      }
//      printf("\n");
//  }
//  printf("\n");
//}
void scanlinefill() {
    int xx,ax1,ax2;
    while (1) {
        if (sp<=0) break;//
        pop();
//      printf("O yy1,xx1,xx2=%d,%d,%d\n",yy1,xx1,xx2);
        for (xx=xx1;xx<=xx2;xx++) n[yy1][xx]=2;//填充本条线
        yy1++;
        if (yy1<=2*MAXN)
        for (xx=xx1;xx<=xx2;xx++) {//从左往右考查紧挨下面一条线各点
            if (n[yy1][xx  ]==0) {
                ax1=xx-1;
                while (1) {//向左找非0点
                    if (n[yy1][ax1]!=0) break;
                    ax1--;
                }
                ax1++;//非0点右边为新扫描线左点
            }
            if (n[yy1][xx  ]==0) {
                ax2=xx+1;
                while (1) {//向右找非0点
                    if (n[yy1][ax2]!=0) break;
                    ax2++;
                }
                ax2--;//非0点左边为新扫描线右点
//              printf("I yy1,ax1,ax2=%d,%d,%d\n",yy1,ax1,ax2);
                push(yy1,ax1,ax2);//记录新扫描线到堆栈中
                xx=ax2+1;//下次循环从该新扫描线右点的右边开始考查
            }
        }
    }
}
int main() {
    scanf("%s",p);
    f='S';
    y=MAXN;
    x=MAXN;
    n[y][x]=1;
    L=strlen(p);
    for (i=0;i<L;i++) {
        switch (p[i]) {
        case 'f':
            switch (f) {
            case 'N':y--;n[y][x]=1;break;
            case 'S':y++;n[y][x]=1;break;
            case 'W':x--;n[y][x]=1;break;
            case 'E':x++;n[y][x]=1;break;
            }
        break;
        case 'l':
            switch (f) {
            case 'N':f='W';break;
            case 'S':f='E';break;
            case 'W':f='S';break;
            case 'E':f='N';break;
            }
        break;
        case 'r':
            switch (f) {
            case 'N':f='E';break;
            case 'S':f='W';break;
            case 'W':f='N';break;
            case 'E':f='S';break;
            }
        break;
        }
    }
//  show();
    for (y=0;y<2*MAXN+2;y++) {n[y][0]=2;n[y   ][2*MAXN+1]=2;}
    for (x=0;x<2*MAXN+2;x++) {n[0][x]=2;n[2*MAXN+1][x   ]=2;}
//  show();
    push(1,1,2*MAXN);//从(y1==1,x1==1,x2==2*MAXN)开始
    scanlinefill();//往下使用扫描线种子填充算法填充2
//  show();
    a=0;
    for (y=0;y<2*MAXN+1;y++) {
        for (x=0;x<2*MAXN+1;x++) {
            if (n[y][x]!=2) a++;
        }
    }
    printf("%d\n",a);
    return 0;
}
lm_whales 2013-10-26
  • 打赏
  • 举报
回复
你这个,我觉得就用直接画直线段的方法,用圆的方程,去做最准确。 如果还想更快什么的,结合填充算法,扫描算法什么的。
幻日 2013-10-25
  • 打赏
  • 举报
回复
引用 19 楼 Chen8013 的回复:
晕,提交后,完全变形了。
前辈费心了
舉杯邀明月 2013-10-25
  • 打赏
  • 举报
回复
晕,提交后,完全变形了。
舉杯邀明月 2013-10-25
  • 打赏
  • 举报
回复
我在字符拼图中找一个“例子”来说明一下: 假设有下面那样一个形状的区域,你在右边“⊕”所在位置点了一下鼠标。 然后左右搜索“边界”,画横线填充(在上下方向进行“扩散”)。 那么,在左边有一块,是填充不到的。
'    ◢██▆▄
'   ◢█████▆▄
'  ◢████████▆▄
' ◢███████████▆▄
'◢██████████████▆▄
'██████◥█████████◤
'◥█████ ████████◤
' ◥████ ███⊕███◤
'  ◥███ ██████◤
'   ◥██ █████◤
'       ████◤
'       ███◤
'       ██◤
这种情况下要把那个区域全部填满,还得用其它的边界搜索算法才行。
舉杯邀明月 2013-10-25
  • 打赏
  • 举报
回复
只是靠“左右搜索”找边界,有些时候是无法把那个区域填充满的。
幻日 2013-10-25
  • 打赏
  • 举报
回复
引用 15 楼 Chen8013 的回复:
要象你那样去“填满整个区域”,没那么简单。
就是用种子发散的办法,具体怎么表述我不太会,只会画条到临界点的线
舉杯邀明月 2013-10-24
  • 打赏
  • 举报
回复
要象你那样去“填满整个区域”,没那么简单。
赵4老师 2013-10-24
  • 打赏
  • 举报
回复
ExtFloodFill The ExtFloodFill function fills an area of the display surface with the current brush. BOOL ExtFloodFill( HDC hdc, // handle to device context int nXStart, // x-coordinate where filling begins int nYStart, // y-coordinate where filling begins COLORREF crColor, // fill color UINT fuFillType // fill type ); Parameters hdc Handle to a device context. nXStart Specifies the logical x-coordinate of the point where filling is to begin. nYStart Specifies the logical y-coordinate of the point where filling is to begin. crColor Specifies the color of the boundary or of the area to be filled. The interpretation of crColor depends on the value of the fuFillType parameter. fuFillType Specifies the type of fill operation to be performed. It must be one of the following values: Value Meaning FLOODFILLBORDER The fill area is bounded by the color specified by the crColor parameter. This style is identical to the filling performed by the FloodFill function. FLOODFILLSURFACE The fill area is defined by the color that is specified by crColor. Filling continues outward in all directions as long as the color is encountered. This style is useful for filling areas with multicolored boundaries. Return Values If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. Windows NT: To get extended error information, callGetLastError. Remarks Following are some of the reasons this function might fail: The filling could not be completed. The specified point has the boundary color specified by the crColor parameter (if FLOODFILLBORDER was requested). The specified point does not have the color specified by crColor (if FLOODFILLSURFACE was requested). The point is outside the clipping region — that is, it is not visible on the device. If the fuFillType parameter is FLOODFILLBORDER, the system assumes that the area to be filled is completely bounded by the color specified by the crColor parameter. The function begins filling at the point specified by the nXStart and nYStart parameters and continues in all directions until it reaches the boundary. If fuFillType is FLOODFILLSURFACE, the system assumes that the area to be filled is a single color. The function begins to fill the area at the point specified by nXStart and nYStart and continues in all directions, filling all adjacent regions containing the color specified by crColor. Only memory device contexts and devices that support raster-display operations support the ExtFloodFill function. To determine whether a device supports this technology, use the GetDeviceCaps function. QuickInfo Windows NT: Requires version 3.1 or later. Windows: Requires Windows 95 or later. Windows CE: Unsupported. Header: Declared in wingdi.h. Import Library: Use gdi32.lib. See Also Bitmaps Overview, Bitmap Functions, FloodFill, GetDeviceCaps
赵4老师 2013-10-24
  • 打赏
  • 举报
回复
FloodFill The FloodFill function fills an area of the display surface with the current brush. The area is assumed to be bounded as specified by the crFill parameter. Note The FloodFill function is included only for compatibility with 16-bit versions of Windows. For Win32-based applications, use the ExtFloodFill function with FLOODFILLBORDER specified. BOOL FloodFill( HDC hdc, // handle to device context int nXStart, // x-coordinate, where fill begins int nYStart, // y-coordinate, where fill begins COLORREF crFill // fill color ); Parameters hdc Handle to a device context. nXStart Specifies the logical x-coordinate of the point where filling is to begin. nYStart Specifies the logical y-coordinate of the point where filling is to begin. crFill Specifies the color of the boundary or of the area to be filled. Return Values If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. Windows NT: To get extended error information, callGetLastError. Remarks Following are reasons this function might fail: The fill could not be completed. The given point has the boundary color specified by the crFill parameter. The given point lies outside the current clipping region — that is, it is not visible on the device. See Also Bitmaps Overview, Bitmap Functions, ExtFloodFill
幻日 2013-10-24
  • 打赏
  • 举报
回复
写了一段代码,可以实现在一个区域内点一下然后画一条线,怎么才能点一下画满直线以达到填满这个区域的效果
Dim rgbColor As String
Dim dr As Single
Dim dg As Single
Dim db As Single
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
rgbColor = Hex(Me.Point(x, y))
rgbColor = Change2RGB(rgbColor)
Call printline(x, y)

End Sub



Private Sub Form_paint()
Text1.Text = ""
Text2.Text = ""
Text3.Text = ""
Circle (2000, 2000), 1000, RGB(0, 0, 0)
Circle (2800, 2800), 1000, RGB(0, 0, 0)
End Sub


Private Function printline(x As Single, y As Single)
'左侧查找
Dim lx As Single
Dim ly As Single
Dim rx As Single
Dim ry As Single
Dim loopflag As Boolean
loopflag = True
lx = x - 1
Do While loopflag
If Change2RGB(Me.Point(lx, y)) <> rgbColor Then
loopflag = False
Else
lx = lx - 1
End If
Loop
'右侧查找
loopflag = True
rx = x + 1
Do While loopflag
If Change2RGB(Me.Point(rx, y)) <> rgbColor Then
loopflag = False
Else
rx = rx + 1
End If
Loop
Me.Line (lx, y)-(rx, y), RGB(Val(Text1.Text), Val(Text2.Text), Val(Text3.Text))
End Function

Private Function Change2RGB(c As String)
Select Case Len(c)
Case 1: Change2RGB = "00000" & c
Case 2: Change2RGB = "0000" & c
Case 3: Change2RGB = "000" & c
Case 4: Change2RGB = "00" & c
Case 5: Change2RGB = "0" & c
End Select
End Function
韧恒 2013-10-23
  • 打赏
  • 举报
回复
建个工程,添加如下代码,你什么都明白了。 Private Sub Form_Paint() '这段代码演示了如何使用VB的Circle方法绘制各种各样的圆。 Form1.ScaleMode = vbPixels ' 设置绘图单位为像素 Form1.Circle (60, 60), 40, vbRed '画一个圆心(60,60)半径40的红色的圆(默认空心) Form1.FillStyle = 0 '设定填充模式为实心 Form1.FillColor = vbBlue '设定填充色蓝色 Form1.Circle (190, 60), 40, vbRed '下来画出来的就是填充了实心蓝色的圆了 Form1.DrawWidth = 3 '设定边框宽度为3 Form1.Circle (60, 190), 40, vbRed '这次绘制出来的圆边框粗细为3 Form1.DrawStyle = 5 '设定边框不可见 Form1.FillColor = vbRed '设定填充色红色 Form1.Circle (190, 190), 40 '这次绘制出来一个无边框、填充颜色是红色的圆 End Sub
幻日 2013-10-23
  • 打赏
  • 举报
回复
是要用在圆内画line的的方法
幻日 2013-10-23
  • 打赏
  • 举报
回复
引用 10 楼 Veron_04 的回复:
[quote=引用 6 楼 u012537093 的回复:] [quote=引用 5 楼 Veron_04 的回复:] 填充不是有专门的API函数吗?
就是规定得用在园内用line画线的方法来做[/quote] 不是的,是api函数,参阅: http://download.csdn.net/detail/veron_04/2765084[/quote] 不是要用这个函数的,要的效果是在这个圆内点一下,通过这个点向外发散画线,到与之颜色不一样的圆周为止,以达到填充圆的目的
贝隆 2013-10-23
  • 打赏
  • 举报
回复
引用 6 楼 u012537093 的回复:
[quote=引用 5 楼 Veron_04 的回复:] 填充不是有专门的API函数吗?
就是规定得用在园内用line画线的方法来做[/quote] 不是的,是api函数,参阅: http://download.csdn.net/detail/veron_04/2765084
幻日 2013-10-23
  • 打赏
  • 举报
回复
引用 8 楼 Chen8013 的回复:
有现成的,干吗不用? 你究竟要充成什么样子?
唉,这是人家特意给我出的一道题,我也没办法,要的效果是在这个圆内点一下,通过这个点向外发散画线,到与之颜色不一样的圆周为止,以达到填充圆的目的
舉杯邀明月 2013-10-23
  • 打赏
  • 举报
回复

有现成的,干吗不用?

你究竟要充成什么样子?
幻日 2013-10-23
  • 打赏
  • 举报
回复
引用 3 楼 of123 的回复:
Picdraw.Cls Picdraw.FillColor = RGB(0, 0, 0) Picdraw.FillStyle = vbSolid Picdraw.Circle ((a + X) / 2, (b + Y) / 2), (((a - X) ^ 2 + (b - Y) ^ 2) ^ 0.5) / 2, RGB(0, 0, 0)
不是简单的设置fillstyle和fillcolor属性,是要用line的方法给圆填充颜色
幻日 2013-10-23
  • 打赏
  • 举报
回复
引用 5 楼 Veron_04 的回复:
填充不是有专门的API函数吗?
就是规定得用在园内用line画线的方法来做
贝隆 2013-10-23
  • 打赏
  • 举报
回复
填充不是有专门的API函数吗?
加载更多回复(2)

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧