精华内容
下载资源
问答
  • 区域填充

    千次阅读 2017-03-24 12:22:06
     区域填充方法分为两:区域由多边形围成,区域由多边形的顶点序列来定义;另一方法是通过像素的值来定义区域的内部,相应的技术称为是以像素为基础的。  内定义区域,定义方法是指出区域内部所有的像素值,...

    一、种子填充算法

      区域是指光栅网络上的一组像素,区域填充是把某确定的像素值送入到区域内部的所有像素中。

      区域填充方法分为两大类:区域由多边形围成,区域由多边形的顶点序列来定义;另一类方法是通过像素的值来定义区域的内部,相应的技术称为是以像素为基础的。

      内定义区域,定义方法是指出区域内部所有的像素值,此时区域内部所有像素有某个原值oldvalue。

      边界定义区域,定义方法是指出区域边界所具有的像素值。此时区域边界上的所有像素具有某个边界boundaryvalue。区域的边界应该是封闭的,并且应该指明区域的内部。

     1. 以像素为基础的区域填充主要是依据区域的连通性进行。

      四连通:从区域中的一个像素出发,经连续地上下左右四个相邻的像素的移动,就可以到达区域内的任意一个像素。

      八连通:如果出了要经上下左右的移动,还要经左上、右上、左下、右下的移动,才能由一个像素走到区域中的另外一个任意像素。

      利用区域的连通性进行区域填充,除了需要区域应该明确定义外,还需要事先给定一个区域内部像素,这个像素称为种子。

      做区域填充时,要进行对光栅网络的遍历,找出由种子出发能达到而又不穿过边界的所有像素。这种利用连通性的填充,其主要优点是不受区域不规则性的影响,主要缺点是需要事先知道一个内部像素。

      2.扫描线种子填充算法

      将区域由内边界点限定的同一行内相连接的不具有新值newvalue的一组像素称为一个像素段,像素段用它最右边的像素来标识。

      算法的步骤如下:

      2.1 对种子所在像素段进行区域填充。

      2.2 从右至左检查种子所在的行的上一横行,将查得的像素段一次编号存入堆栈。接着对种子所在的行的下一横行同样处理。

      2.3若堆栈为空,则算法结束,否则从堆栈顶部取一个像素段,就以这个像素为新的种子,返回步骤2.1。



    二、多边形的扫描转换算法。

      多边形扫描转换产生面填充的图形。多边形扫描转换可以依据区域的一种“奇偶”性质,即一条直线与任意封闭区域的曲线相交时,总是从第一个交点进入内部,再从第二个交点推出,一下交替的进入退出,即基数次进入,偶数次退出。当然,可能有些“相切”的点应做特殊处理。

      可以分如下三个步骤来做:

      1.找出扫描线与多边形边界线的所有交点。

      2.按x坐标增加顺序对交点排序。

      3.交点对之间进行区域填充。

      正确解决“相切”的办法是,当顶点表现为局部极大或者局部极小时,就看做是两个,否则看做是一个。在这里,称一个顶点局部极大,如果这个顶点的前面和后面各有一些相邻的顶点的y坐标,都小于该顶点的y坐标。局部极小的定义类似地可确定。

      实际处理这个问题可以有一个简便的办法,那就是对应看做是一个的顶点,将其上面的边缩短两条相邻的扫描线对应的一个单位。

      计算扫描线与多边形边界线的交点:注意到若扫描线yi与多边形边界线交点x的坐标是xi,则对下一条扫描线yi+1,它与那条边界线得交点的x坐标xi+1可如下求出:

        xi+1=xi+1/m; (其中m为斜率)

      活跃边表AET(Active-Edge-Table),用这个表存贮与当前扫描线相交的各边。每次离开一条扫描线进入下一条扫描线之前,将表中有但与下一条扫描线不相交的边清除出表,将与下一条扫描线相交而表中没有的边加入表中。

      边表ET(Edge Table),TE中各登记项按y坐标递增排序,每一登记项下的“吊桶”按所计x坐标递增排序,“吊桶”中各项内容依次是:

      1.遍的另一端点的较大的y坐标ymax。

      2.与较小的y坐标对应的边的端点的x坐标xmin。

      3.斜率的倒数,即1/m。

      算法:

      y=置y为边表ET中各登记项对应的y坐标中最小值。

      活跃边表AET初始化为空表;

      while(ET表中仍有扫描线未被处理)

    {

      将ET中登记项y对应的各“吊桶”合并到表AET中,将AET中各吊桶按x坐标递增排序;

      在扫描线y上,按照AET表提供的x坐标对,用color填充。

      将AET表中有y=yma各项清除出表;

      对AET中留下的各项,分别将x换为x+1/m,这是求出AET中各边与下一条扫描线交点的x坐标。

      由于前一步可能破坏了AET表中各项x坐标的递增次序,故按x坐标重新排序。

      y=y+1,去处理下一条扫描线。

    }




     


    展开全文
  • 图形学-区域填充

    2020-07-24 09:21:49
    区域填充指的是从区域内的一点(种子点)开始由内向外将填充色扩展到整个区域的过程,这里的区域都是指已经表示成点阵形式的填充图形,它是一个像素集合,区域通常有内点表示和边界表示种形式。 把位于给定区域...

    定义

    区域填充指的是从区域内的一点(种子点)开始由内向外将填充色扩展到整个区域的过程,这里的区域都是指已经表示成点阵形式的填充图形,它是一个像素集合,区域通常有内点表示和边界表示两种形式。
    把位于给定区域边界上的像素一一例举出来的方法称为边界表示法。它要求区域边界上的像素都着同一颜色(边界色),而区域内和区域外的像素可以着同样的颜色,单不能着边界色。这样,边界表示法的区域具有显式的边界,填充算法可逐个像素地向外处理,直到遇到边界色为止,这种方法称为边界填充算法
    在这里插入图片描述
    枚举给定区域内所有像素的表示方法称为内点表示法。它要求区域内的所有像素着同一颜色,而区域外的像素着不同的颜色。内点表示法表示的区域没有显式的边界,以内点表示法为基础的区域填充算法称为范填充算法。
    无论哪种形式表示,区域均可分为4-连通区域和8-连通区域两类。
    在这里插入图片描述
    在这里插入图片描述

    边界填充算法

    在这里插入图片描述

    泛填充算法

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 多边形的区域填充 首先,我们了解一下多边形。 多边形可以简单地分为凸多边形和凹多边形,除此之外,我们还要讨论内含环的多边形,如下图。 多边形的表示方法 顶点表示:用多边形顶点的序列来刻画多边形。直观、...

    相关资料来源于网络,侵删歉。
    如果文章中存在错误,请下方评论告知我,谢谢!


    多边形的区域填充

    首先,我们了解一下多边形。
    多边形可以简单地分为凸多边形和凹多边形,除此之外,我们还要讨论内含环的多边形,如下图。

    多边形的表示方法
    顶点表示:用多边形顶点的序列来刻画多边形。直观、几何意义强、占内存少;不能直接用于显示。
    点阵表示:用位于多边形内的像素的集合来刻画多边形。失去了许多重要的几何信息;但它是光栅显示系统显示时所需的表示形式,易于面着色。

    多边形的扫描转换(多边形的区域填充)
    把多边形的顶点表示转换为点阵表示,也就是从多边形的给定边界出发,求出位于其内部的各个像素,并给各个像素设置相应的灰度和颜色,通常称这种转换为多边形的扫描转换。
    方法:逐点判断法,扫描线算法,边缘填充法等。


    前提
    多边形的顶点坐标均为整数。

    逐点判断法

    逐个判断绘图窗口内的像素,确定是否在多边形区域内,从而求出位于多边形区域内的像素集合。

    #define MAXN 100
    typedef struct{
    	int PolygonNum;//多边形顶点个数
    	Point vertexces[MAXN];//多边形顶点数组
    }Polygon;
    
    void FillPolygonPbyP(Polygon *P, int color){
    	int x, y;
    	for(y=ymin;y<=ymax;y++)
    	for(x=xmin;x<=xmax;x++)
    		if(isInside(P,x,y))
    			WritePixel(x,y,color);
    }

    如何判断点在多边形内外呢?
    1.射线法
    从点v发出射线,求与多边形的交点个数n。若n为奇数,则点v在多边形内部;若n为偶数,则点v在多边形外部。
    2.累计角度法
    从点v向多边形的每个顶点发出射线,形成有向角,计算所有有向角的角度和S。若S=0,则点v在多边形外部;若S=±2π,则点v在多边形内部。

    逐点判断的算法虽然程序简单,但不可取。原因是速度太慢,主要是由于该算法割断了各象素之间的联系,孤立地考察各象素与多边形的内外关系,使得几十万甚至几百万个象素都要一一判别,每次判别又要多次求交点,需要做大量的乘除运算,花费很多时间。

    扫描线算法

    前提:处理对象为非自交多边形,即边与边之间除了顶点外无其它交点,如下图是自交多边形。

    将多边形填充分解为一条条的扫描线填充(扫描线是纵坐标为整数的横线)。对任一条扫描线,自左向右确定该扫描线与多边形的交点位置,并对每对交点间的像素进行填充。那么关键是如何求扫描线与多边形各边的交点,并进行取舍,如下图。

    我们作如下规定
    1.如果交点非整数
    交点位于左边之上,向右取整;交点位于右边之上,向左取整。(要使交点位于多边形内)
    2.落在右上边界的像素不记录。
    3.如果交点是与扫描线相交的那条边的上端点,单独对这条边不记录。(结合上图中2、4、5、6-7间的点加以理解)

    步骤
    求交:求扫描线与多边形各边交点
    排序:按x递增顺序对交点排序
    交点匹配:依次每两个交点配对,在上图中(1,2),(3,4),(5,6),(7,8)配对。
    填充:填充每对交点间在多边形区域内部的象素。

    几点说明
    1.交点个数为偶数。
    2.若交点个数为n,则配对的点为(k,k+1),k=1,3,5...,n-1。
    3.配对的区间是位于多边形内的,其余不是。

    接下来我们具体了解一下如何求扫描线与多边形的交点

    假定已经求解出扫描线y=e和多边形边的所有交点,那么递推出扫描线y=d=e+1与多边形边的交点,求解可分为两类:
    1.边既和y=e相交,又和y=d相交。
    若x为其中某条边与y=e的交点横坐标,k为该边的斜率,则此边与y=d的交点横坐标x'=x+1/k;
    2.边只与y=d相交,不与y=e相交,即新出现的边。
    此时,这些边的下端点就是交点,不用计算。    

    几种特殊情况
    1.不对水平边计算,在预处理阶段将水平边删除。
    2.对尖角的处理(即填充区域非常狭窄),扫描线原则上一个元素都不会填充,这时我们需要进行反走样。

    好了,我们来看实现
    扫描线算法中采用了灵活的数据结构。
    1.边结构

    typedef struct   
    {
        int ymax; // 边的上端点的y值
        float x; // ET表中为边的下端点的x值;AET中为当前扫描线与边的交点的x值
        float dx; // 单位高度x方向偏移量(即边的斜率的倒数)
        E * nextEdge ;  // 指向下一条边的指针
    }E;
    

    2.边表ET
    边表ET的基本元素是边结构,它是按多边形每条边的下端点的y坐标对非水平边进行分类的。边的下端点y坐标值等于i,那么该边就属于第i类。同一类中的边按其下端点的x值(x值相等的,按dx值)增序排列。如下图。

    3.活动边表AET
    活动边表AET的基本元素也是边结构,它由当前与扫描线相交的边组成,记录多边形的边和当前扫描线的所有交点的x坐标,并且随着扫描线的递增而不断变化。

    (边表ET用来排除不必要的求交测试。如求扫描线y=4的AET时,e3,e4所属的类序号5大于4,所以它们和y=4没有交点,不用进行求交测试。)
     

    伪代码:

    void polyfill (polygon, color)
    {  
    	//建立全局边表ET;
    	for (各条扫描线i )  { 把ymin == i 的边结构->边表ET [i]  }
    	将扫描线i的初值置为ET中非空元素的最小序号;
    	初始化活动边表AET为空;
    	for (各条扫描线i )
    	{
    		(1) 把边表ET[i]中的边结点插入AET表;
    		(2) 遍历AET表,把y max== i 的结点从AET中删除,并按x坐标值增序排列各边;
    		(3) 把配对交点区间(左闭右开)上的象素(x, i),用WritePixel (x, i, color)改写颜色值;
    		(4) 把AET中每条边结点的x值递增△x;
    	}
    }
    

     

    展开全文
  • 分为两: 1、种子填色算法(Seed Filling) 这算法建立在多边形边边界的图象形式数据之上,并还需提供多边形界内一点的坐标。所以,它一般只能用于人机交互填色,而难以用于程序填色。 GIS中用于栅格填色 2、...

    个人网站https://lishiyu.vip

    一、区域填充算法

    分为两大类:

    1、种子填色算法(Seed Filling)

    这类算法建立在多边形边边界的图象形式数据之上,并还需提供多边形界内一点的坐标。所以,它一般只能用于人机交互填色,而难以用于程序填色。

    GIS中用于栅格填色

    2、扫描线填色算法(Scan-Line Filling)

    这类算法建立在多边形边边界的矢量形式数据之上,可用于程序填色,也可用交互填色。


    二、种子填色算法(Seed Filling)

    种子填色又称边界填色(Boundary Filling)。

    它的功能是:给出多边形光栅化后的边界位置及边界色代码boundary,以及多边形之内的一点x, y位置,要求将颜色color填满多边形。

    算法分类

    分为四邻法(4-connected)和八邻法。

    C#实现

    种子填充更适合用于栅格像元填色,知识有限。暂且用GDL+的矢量像元代替。

    算法流程思路

    😆自认为很棒的思路哈哈哈~😆

    代码实现(很巧(qi)妙(pa)的思路 😌 )

    重要参数
    1. 需要填充颜色的图形的边界颜色🌈

    2. 需要填充的颜色是什么🌈

    3. 种子点,即填充图形内部中尚未填充颜色的任意一点,也是填充的起始点。✴️

      (星星之火🔥可以燎原呐~ )

    具体思路

    利用中点画圆算法(中点画圆算法文章中已详细阐述),画两个圆。

    • 第一个圆为目标填充圆,即,需要填充颜色的圆。
    • 第二个圆为取色圆,取其边界颜色,将其作为第一个圆填充的颜色。

    其实要定义第一个圆的填充颜色,亦可用交互方式来定义,即用户自定义颜色。有点麻烦,不想搞那么花里胡哨的了。

    代码

    硬核算法部分

    using System.Drawing;
    
    namespace scan
    {
        partial class Form1
        {
            public static void seedfill(Color boundcolor,Point pointseed,Color fillcolor,Bitmap bitmap)
            {
                //取出种子点(需要填充的图形边界内一点)的颜色
                Color c = bitmap.GetPixel(pointseed.X, pointseed.Y);
    
                //四邻法,对种子点的颜色进行判断。
                if (c!=fillcolor && c!=boundcolor)
                {
                    bitmap.SetPixel(pointseed.X, pointseed.Y, fillcolor);
                    seedfill(boundcolor, new Point(pointseed.X, pointseed.Y + 1), fillcolor, bitmap);
                    seedfill(boundcolor, new Point(pointseed.X, pointseed.Y - 1), fillcolor, bitmap);
                    seedfill(boundcolor, new Point(pointseed.X + 1, pointseed.Y), fillcolor, bitmap);
                    seedfill(boundcolor, new Point(pointseed.X - 1, pointseed.Y), fillcolor, bitmap);
                }
            }
        }
    }
    

    使用部分

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace scan
    {
        public partial class Form1 : Form
        {
            Graphics graphics;
            Bitmap bitmap;
            public Form1()
            {
                InitializeComponent();
                graphics = panel1.CreateGraphics();
                bitmap = new Bitmap(panel1.Width, panel1.Height);
            }
            private void ButtonDraw_Click(object sender, EventArgs e)
            {
                //第一个圆为填充图形
                circle(100, 100, 30, Color.Red);
    
                //第二个圆为取色图形
                circle(290, 200, 10, Color.Blue);
    
                graphics.DrawImage(bitmap, 0, 0, bitmap.Width, bitmap.Height);
            }
            private void ButtonFill_Click(object sender, EventArgs e)
            {
                //填充开始的点(种子点),为第一个圆的圆心。
                Point point = new Point(100, 100);
    
                //参数1图形边界颜色:取点(100,90)。
                //参数2开始填充的种子点:point(100,100).其为圆心。
                //参数3想要填充的颜色:取自第二个圆的边界颜色,即点(200,190)。
                //参数4在bitmap上进行操作。
                seedfill(bitmap.GetPixel(100, 70), point, bitmap.GetPixel(290, 190), bitmap);
                graphics.DrawImage(bitmap, 0, 0, bitmap.Width, bitmap.Height);
            }
        }
    }
    
    

    hhhhhh……

    运行结果

    😎

    展开全文
  • 平面区域填充算法是计算机图形学领域的一个很重要的算法,区域填充即给出一个区域的边界(也可以是没有边界,只是给出指定颜色),要求将边界范围内的所有象素单元都修改成指定的颜色(也可能是图案填充)。区域填充...
  • 计算机图形学——区域填充算法 橡皮筋效果 本次实验的环境是使用vs提供的MFC框架,在鼠标交互输入中使用橡皮筋算法来实现多边形的输入。首先定义相应变量来保存输入的数据。 int m_pNumbers; //输入点的个数 CPoint ...
  • 对于HotSpot虚拟机来说,Java的实例对象在内存中存储分为三块区域,分别是对象头、实例数据、对齐填充。 对象头 对象头包含部分,第一部分用于存储对象自身运行时的数据,包括GC分代年龄、哈希码、锁状态、...
  • 摘要:提出了一种基于扫描线转换的等值线快速填充算法。与现有的逐点扫描法和区域填充算法相比,该算法既不需要进行逐点...近年来关于等值线填充算法的研究也很多,大致可分为扫描填充和区域填充两类。其中扫描填充法
  • 区域填充算法

    万次阅读 2006-02-24 17:58:00
    区域填充即给出一个区域的边界,要求对边界范围内的所有象素单元赋予指定的颜色代码。区域填充中最常用的是多边形填色,本节中我们就以此为例讨论区域填充算法。多边形填色即给出一个多边形的边界,要求对多边形边界...
  •  平面区域填充算法是计算机图形学领域的一个很重要的算法,区域填充即给出一个区域的边界(也可以是没有边界,只是给出指定颜色),要求将边界范围内的所有象素单元都修改成指定的颜色(也可能是图案填充)。区域...
  • OpenGL研究3.0 多边形区域填充

    千次阅读 2014-06-23 00:32:21
    所谓多边形区域填充,就是将多边形内部区域,全部已同样色块填充。注意:这里讨论的多边形是简单多边形(即不考虑诸如五角星这种相交多边形)。简单多边形,分为凹多边形和凸多边形。 多边形区域填充有以下几种方法...
  • Android 不规则图像填充 小玩着色游戏

    万次阅读 多人点赞 2015-05-18 08:57:47
    转载请标明出处: ... 本文出自:【张鸿洋的博客】 一、概述 近期群里偶然看到一哥们在群里聊不规则图像填充...对于这着色的资料,最好的就是去搜索些相关app,根据我的观察呢,不规则图像填充在着色游戏里面应用
  • 1.1.有效边表填充算法分为如下几个步骤: 1.1.1.将多边形所有的边分别与扫描线1计算交点,得到交点集,与扫描线计算的边没有顺序要求。 1.1.2.将点集按标x的大小递增排序,得到有序点集。 1.1.3.将有序点集两两配对...
  • 【Algorithm】种子填充算法

    万次阅读 多人点赞 2019-06-13 19:32:33
    【平面区域填充算法】是计算机图形学领域的一个很重要的算法,区域填充即给出一个区域的边界 (也可以是没有边界,只是给出指定颜色),要求将边界范围内的所有象素单元都修改成指定的颜色(也可能是图案填充)。...
  • 深入理解Java虚拟机-Java内存区域与内存溢出异常

    万次阅读 多人点赞 2020-01-03 21:42:24
    文章目录概述运行时数据区域程序计数器(线程私有)Java虚拟机栈(线程私有)局部变量表操作数栈动态链接方法返回地址小结本地方法栈(线程私有)Java堆(全局共享)方法区(全局共享)运行时常量池直接内存HotSpot...
  • 图像填充方法概述

    千次阅读 2017-12-16 20:32:09
    总说这里主要讲解Inpainting的主要发展历程。从2001年到2014年的图像填充方法概述。
  • 【Qt】数据类型和有用的数据操作

    千次阅读 2018-11-22 14:38:29
    Qt提供的数据类型分为基本数据类型和形态的数据类型。   基本数据类型 Qt支持多个平台,创建的应用程序需要在多种平台上都具有相同大小的数据类型。为了能精确指定数据类型的大小,Qt提供了一下的基本数据类型...
  • 深入JVM内存区域

    千次阅读 2015-11-12 12:22:56
    JVM内存区域的划分和C/C++开发不同,在从事JAVA的开发过程中,我们对内存区域的关注相对较轻,但是了解和掌握JAVA的内存结构会帮助我们做出合理的优化决策。
  • 思维导图 对象的创建 对象的内存布局 对象头( Header ) ...在 JVM-01自动内存管理机制之Java内存区域与内存溢出异常(上)中我们介绍了 运行时数据区域,这里我们来继续探讨下hotspot虚拟机对象 ...
  • 这里处理类别属性的通用方法有,这按照数据的维度划分。因此可以分为低维类别数据及高维类别数据。 低维类别数据预处理方法 对于低维度的类别数据最普遍的做法就是二值化。我们简单举个例子: ...
  • Java加载及对象创建过程详解

    千次阅读 多人点赞 2019-06-27 08:00:00
    加载过程 加载的五个过程:加载、验证、准备、解析、初始化。 ... 在Java堆中生成一个代表这个的java.lang.Class对象,作为方法区域数据的访问入口。 验证 验证阶段作用是保证Class...
  • 根据交点每个点分为一组,并画出这点之间的点,进行填充。(扫描线与每条线段会出现一个交点,条线段的交点处按照个点进行计算,实际上并没有画) 直到扫描到最上面的部分结束。 主要代码: // ScanLine....
  • 焊接方法的分类

    千次阅读 2020-12-20 10:26:37
    焊接方法分类一般都根据热源的性质、形成接头的状态及是否采用加压来划分。1、熔化焊熔化焊是将焊件接头加热至熔化状态,不加压力完成焊接的方法。它包括气焊、电弧焊、电渣焊、激光焊、电子束焊、等离子弧焊、堆焊...
  • 我们已经把无效像素分为了遮挡区和误匹配区,填充的有效视差来源也要区别分析。 首先,两者的共同点是,有效视差都来自于周围有效像素的视差值,区别在于如何从周围的有效视差中选出最合适的一个。 对于遮挡区像素...
  • 【干货】CASS自定义图斑填充技巧

    千次阅读 2020-12-19 16:39:30
    原标题:【干货】CASS自定义图斑填充技巧 经常有... 注意:CASS版本不同填充符号的设置方法也有出入主要分为9.2以下版本和10.0以上版本种 本次就以“水浇地”为例教大家 如何设置图斑填充符号,大家可结合自己的CA...
  • 计算机图形学复习3

    千次阅读 2020-08-21 00:00:47
    区域填充,反走样,以及字符的表示。
  • 工作三年了,整不明白架构图都画啥?

    千次阅读 多人点赞 2021-03-01 08:46:26
    这个过程有点像搭积木一样,把每一个区域用适合此位置的积木填充进去。如果是团队初建或者是技术升级,那么这个过程还是比较复杂的,需要大量的验证。不过其实互联网的技术分层和使用已经相对稳定,搭建一个这样的...
  • 金属焊接方法有40种以上,主要分为熔焊、压焊和钎焊三大。1、熔焊是在焊接过程中将工件接口加热至熔化状态,不加压力完成焊接的方法。熔焊时,热源将待焊工件接口处迅速加热熔化,形成熔池。熔池随热源向前移动...
  • 近几年微软笔试题汇总分类解析

    千次阅读 2013-10-11 16:52:26
    作者:寒小阳 时间:2013年10月。... 这里对2010年至今的微软笔试题做了一个汇总和分类,然后进行了解答和分析,每一题中涉及到的知识点和方法在很多别家公司的笔试面试中也有用,希望下面的内容能在大家找
  • 还有一个问题就是,对象的创建在虚拟机中是非常频繁的行为,比如,可能出现正在给对象A分配内存,指针还没来得及修改,对象B又同时使用了原来的指针来分配内存的情况,解决这种并发问题,一般种方案: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 42,689
精华内容 17,075
关键字:

区域填充一般分为哪两类

友情链接: OS1.zip