精华内容
下载资源
问答
  • 怎么把不规则图形等分
    千次阅读
    2018-12-16 18:46:09

    CSS绘制不规则图形

    在实际开发中,经常会遇到绘制图形(图标)的需求,比如:箭头图表、不规则图形、规则图形;


    常见方法

    • 对于图形的实现,可以大体上分为几种做法

    (1) 背景图片,请UI小姐姐帮你吧……此处略过;

    (2) CSS3的属性:圆角、透明度、变形、边框、伪类等属性实现;

    (3) 渐变属性:通常使用线性渐变实现切角;

    (4) 裁剪属性:

    (5) Canvas实现:

    • 比较
    方法描述适用性优点缺点
    背景图
    CSS3属性
    渐变属性
    图像裁剪
    Canvas

    一、背景图实现

    背景图存在的问题:

    • 占用资源较大,修改维护不方便,灵活性不足;

    二、CSS3属性:图形实现

    大体可以划分为:

    • 三角形系列:三角形、倒三角、左三角、右三角、左上三角、右上三角、左下三角、右下三角;
    • 圆形系列:圆形、椭圆、扇形、圆环、月牙、蛋形
    • 四边形系列:正方形、长方形、菱形、平行四边形、梯形、直角梯形
    • 多边形系列:五边形、钻石、六边形、八边形、
    • 特殊形状:心形、无穷大符号、食人豆、太极图
    • 星形系列:五角星、六角星、八角星、十二角星
    • 实际需求:对话框

    示例代码:

    width="100%" height="300" src="//jsfiddle.net/Bumphy/t6L3b9as/embedded/result,html,css/dark/" allowfullscreen="allowfullscreen">

    三、渐变属性

    渐变分为:径向渐变、线性渐变;

    关键是掌握三个要素:

    • 渐变线(gradient line)
    • 渐变线上的起始点(starting point)和结束点(ending point)
    • 在起始点和结束点上的颜色值

    推荐阅读:深入理解 CSS linear-gradient

    width="100%" height="300" src="//jsfiddle.net/Bumphy/nm8chkfj/5/embedded/result,html,css/dark/" allowfullscreen="allowfullscreen">

    四、图像裁剪

    谈到,图片裁剪,有两个属性,clipclip-path 。其实clip-pathclip的替代属性。

    由于clip属性已经被从web标准中移除了,所以这里就不介绍它了,无情地抛弃它了。

    如果对clip感兴趣,具体可以看这里

    这里,我们主要来了解一下clip-path属性。

    clip-path属性可以用于通过裁剪图片,来显示期望中的图片形状。

    先让我们来看几个例子:

    width="100%" height="300" src="//jsfiddle.net/Bumphy/pyd4suo2/embedded/result,html,css/dark/" allowfullscreen="allowfullscreen">
    • 适用性:所有元素;在SVG中,它适用于除defs元素和所有图形元素之外的容器元素;

    • 取值:

    /* Keyword values */
    clip-path: none;
    
    /* Image values */ 
    clip-path: url(resources.svg#c1);
    
    /* Box values */
    clip-path: fill-box;
    clip-path: stroke-box;
    clip-path: view-box;
    clip-path: margin-box
    clip-path: border-box
    clip-path: padding-box
    clip-path: content-box
    
    /* Geometry values */
    clip-path: inset(100px 50px);
    clip-path: circle(50px at 0 100px);
    clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
    
    /* Box and geometry values combined */
    clip-path: padding-box circle(50px at 0 100px);
    
    /* Global values */
    clip-path: inherit;
    clip-path: initial;
    clip-path: unset;
    

    这么多取值,完全分不清呀喂!!!没关系,来个示例肿么样?

    一个有意思的网站

    变形之css shapes

    CSS Shapes 标准定义了可以被 CSS 属性值使用的图形描述方法。

    标准目前主要有两个版本。当前标准为第一版,第二版还在迭代过程之中。

    该标准的第一个版本主要包含 3 个属性:shape-outsideshape-image-threshold以及shape-margin

    shape-outside可以实现内容能绕着不规则几何图形排列。

    取值:

    circle函数:定义一个正圆。可以指定半径和圆心位置。 对于半径,只能接受非负数,负数不允许。默认地,使用短边作为直径。 如果使用百分数,百分数的定义是 sqrt(width2+height2)/sqrt(2)。几何定义为:“对角线长度与单位面积对角线长度的比值”。 有两个快捷值可以设置:closest-side和farthest-side 圆心位置默认为中心,如果需要指定须以at引导的数据。此数据可以是百分数或这 center/left/right 的组合。 完整的参数形如:circle(100px at center 25%)

    ellipse函数:定义一个椭圆。和circle函数的参数大致一样。指定半径时候可以指定两个参数。椭圆函数的长轴和短轴只能在宽度方向和高度方向产生。如果指定的话,就是依次指定水平和垂直的半径。 完整的参数形如:ellipse(100px 200px at center 25%)

    inset函数:定义一个内部矩形。这个矩形可以把周围的内容放进去。参数有两个,一个是矩形的上右下左的百分比坐标,类似与margin的指定原则,但必须是百分数。第二个参数为这个矩形的 border 半径,以round引导。 完整的参数形如:ellipse(0% 66% 1% 1% round 50%)

    polygon函数:表示一个封闭的多边形区域。语法为:polygon(X1 X1, … , Xn Yn)。意思是由 N 个点构成的多边形。Xi 和 Yi 代表每个顶点所示的坐标,坐标可为像素值或者百分比。Xi,Yi与Xi+1,Yi+1即为相邻顶点的边。Xn,Yn与X1,Y1也是连接的。

    对于多边形,存在有多种填充逻辑,用于判定一个点在多边形的“内部”还是“外部”。目前标准支持两种,这与 SVG 标准一致。

    nonzero:按该规则,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点情况。从 0 开始计数,路径从左向右穿过射线则计数加 1,从右向左穿过射线则计数减 1。得出计数结果后,如果结果是 0,则认为点在图形外部,否则认为在内部。

    evenodd:按该规则,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点的数量。如果结果是奇数则认为点在内部,是偶数则认为点在外部。

    默认地,标准指定为nonzero。如果是evenodd可以在polygon函数中传第一个参数。

    在线工具

    shape-image-threshold
    这个属性一般和shape-outside联合使用,此时,shape-outside的属性应设置为一张图片。此时,shape-image-threshold 用于从图像中提取形状的阈值。形状由 alpha 值大于此阈值的像素定义。

    .el{
    	shape-outside: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/css-shapes-9.jpg);
      	shape-image-threshold: 0.0;
    }
    

    此处需要注意:

    不能使用file:协议进行测试。
    注意同源策略。
    未来的协议可能会倾向使用图片数据的亮度来取代目前的 alpha 通道。为此会提供一个开关选项。未来同时兼容这两种值的时候,究竟是亮度还是 alpha 通道,取决于这个开关选项值的状态。

    shape-margin
    shape-margin表示在 CSS 形状的浮动区域周围添加空白区域来避免周围内容和形状区域重叠。下面的代码是一个使用的例子。

    .float {
        shape-outside: polygon(10px 10px, 90px 50px, 40px 50px, 90px 90px, 10px 90px);
        shape-margin: 10px;
    }
    

    shape-margin可以为:px、em、rem、百分比或者 calc()函数值。但必须为非负数。下面展示了几个可能的取值:

    shape-margin: 10px;
    shape-margin: 1em;
    shape-margin: 5%;
    shape-margin: calc(2em - 1px);
    

    引用
    形神兼备——谈谈CSS Shapes

    更多相关内容
  • 图片中不规则区域的点击

    千次阅读 2020-06-29 16:23:20
    接着上一条,对于找茬里面更高的要求就是一张大图中不规则图形的点击处理,需要获取点击区域,然后点击对这个不规则区域进行处理,如变色操作,还能知到点击的是哪个不规则区域。 先看效果图: 这个先要一个...

    接着上一条,对于找茬里面更高的要求就是一张大图中不规则图形的点击处理,需要获取点击区域,然后点击对这个不规则区域进行处理,如变色等操作,还能知到点击的是哪个不规则区域。

    先看效果图:

    这个先要一个xml,这个xml里面就是各个不同区域的描点数据。先看看这个数据怎么获取吧,需要工具:Adobe Dreamweaver 。下面的演示操作使用的是Adobe Dreamweaver CC 2018.

    第一步:

     

    第二步点击插入一个Image,

     

    第三步:

    这里要选择设计,然后再回到拆分那里

    第四步骤,在图片上右键,然后点击属性,选择不规则选择区域:

     

    这里就是不规则选框,选择你要点击事件响应的不规则区域,选择完成在下面的html里面就有一个area便签,里面的一串数字代表了你的不规则区域。也就是后面安卓代码里面的pts字段里的数据了。

     

    下面就是读取这个area区域,然后将这个区域存放在自己的一个实体中,这个实体作为后面返回给点击事件也是有必要的。然后就是监听onTouchEvent,将这个事件瓜分出来点击事件,将这个点击的位置在之前添加的area里查找,看是否包含这个点击的x,y值,如果有就说明点击到了某个区域,然后将这个区域返回出来。

      @Override
        public boolean onTouchEvent(MotionEvent event) {
            boolean resStat = super.onTouchEvent(event);
            if (mSourceBitmap != null && !isAnimation) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    mDownTime = System.currentTimeMillis();
                    mPointF.set(event.getX(), event.getY());
                }
                if (event.getPointerCount() == 1) {
                    if (isCanMove) {
                        moveEvent(event);
                        resStat = true;
                    }
                    if (isCanClick) {
                        clickEvent(event);
                        resStat = true;
                    }
                } else if (event.getPointerCount() == 2) {
                    if (isCanScale) {
                        scaleEvent(event);
                        resStat = true;
                    }
                }
                if (isNeedToCheckOutOfSide) {
                    outOfSideEvent(event);
                    resStat = true;
                }
            }
            return resStat;
        }
    
       /**
         * 是否点击在热点区检测
         *
         * @param event
         */
        protected void checkAreas(MotionEvent event) {
            mHotKeys.clear();
            float[] curMove = getCurrentMoveXY();
            float scale = getCurrentScale();
            for (String key : mCheckAreas.keySet()) {
                if (mCheckAreas.get(key).isInArea(mEmptyRectF, (event.getX() - curMove[0]) / scale, (event.getY() - curMove[1]) / scale)) {
                    mHotKeys.add(key);
                    lastClick = event;
                    break;
                }
            }
        }
    
        /**
         * 缩放事件
         *
         * @param event
         */
        protected void scaleEvent(MotionEvent event) {
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_POINTER_DOWN:
                    mIsTwoFinger = true;
                    mBeforeDistance = spacing(event);
                    if (mBeforeDistance > 10f) {
                        mSaveMatrix.set(mMatrix);
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
                    float afterDistance = spacing(event);
                    if (afterDistance > 10f) {
                        float tempScale = afterDistance / mBeforeDistance;
                        mMatrix.set(mSaveMatrix);
                        float newScale = getCheckRangeScale(tempScale);
    //				imageCenterLocation(event);
                        mMatrix.postScale(newScale, newScale, VIEW_WIDTH / 2, VIEW_HEIGHT / 2);
                        invalidate();
                    }
                    break;
                case MotionEvent.ACTION_POINTER_UP:
                    if (event.getPointerCount() == 0) {
                        upToCheckOutOfSide(event);
                    }
                    break;
                default:
                    break;
            }
        }

    基本上就这么弄完了,下面就来粘贴处demo链接,欢迎下载:https://download.csdn.net/download/greatdaocaoren/12561318

     

    展开全文
  • 类似的FeatureLayer同样具备definitionExpression,这些方法都可以根据用户权限控制数据的展示,今天我们要讨论的并不是这两种类型,而是切片类型的服务如何根据不规则形状显示,为什么要进行不规则的显示呢,打个...

    由于项目的要求,地图需要按照用户权限显示对应的区域,这里我们所使用的地图服务是指切片类型的服务,根据Arcgis api我们知道MapImageLayer可以控制子图层的显隐,子图层的定义查询:

    var layer = new MapImageLayer({
    url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer",
      sublayers: [
       {
         id: 3,
         visible: false
       },
       {
         id: 0,
         visible: true,
         definitionExpression: "pop2000 > 100000"
       }
     ]
    });
    

    类似的FeatureLayer同样具备definitionExpression,这些方法都可以根据用户权限控制数据的展示,今天我们要讨论的并不是这两种类型,而是切片类型的服务如何根据不规则形状显示,为什么要进行不规则的显示呢,打个比方,我们的切片服务为完整的全市域的切片,而在实际应用中需要针对城市某个区域进行显示,这时就要依据区划范围面进行不规则显示了,便于用户权限的控制。

    那么切片类型的服务如何控制?

    方式一:控制范围坐标Extent,当地图范围变化时,判断与显示范围的关系,强制用户拖拽超出范围,这个方法的弊端是Extent是矩形。

    方式二:地图遮罩,发布遮挡范围面,这个效果较为直观,但是毕竟是又添加了一层服务,在地图拖拽的空隙会漏出遮挡面下的区域内容,而且还会出现卡顿等问题。

    方式三:CSS遮罩,这也是本文较为推荐的方式

    脱离api的思考方式,选择在地图控件的上方,叠加一层不透明的div,根据显示范围将div裁切出空洞进而显示出地图部分,优点在于CSS3可以按照不规则点进行裁切,缺点是通过样式的控制过于简单,数据仍然能够被获取。

    给出CSS3的代码示例,API采用的为4.6(3.X的效果可能更佳,api提供的接口更丰富,这里主要是监控地图Extent的变化)

    ClipPath:function(geo_hn){//输入为geometry的范围图形
          var _self = this;
          var centergeo = geo_hn.extent.clone();//clone后不会对原图形更改
          gConfig.initExtent = centergeo.expand(1.2);
          _self.mapView.goTo({target:gConfig.initExtent}).then(function () {
              var scale = _self.mapView.scale;
             _self.mapView.constraints.minScale = scale*1.5;//限定地图的缩放
    
             watchUtils.init(_self.mapView,'extent',function(extent,oldextent){//动态监测地图范围变化
    
                var polygonscreen = "polygon(100% 0,0 0,0 50%,";
                for(var i=0;i<geo_hn.rings[0].length;i++){//将坐标点位转换为屏幕坐标
                  var xymap = geo_hn.rings[0][i];
                  var screenxt =_self.mapView.toScreen({x:xymap[0],y:xymap[1],spatialReference:_self.mapView.spatialReference});
    
                  polygonscreen+=screenxt.x+"px "+screenxt.y+"px,";
                }
                polygonscreen += "0 50%,0 100%,100% 100%)";
                $("#regiondivl").css("-webkit-clip-path",polygonscreen);//css3输入一串坐标就可以裁切div了,这里为了挖洞,从右上角开始到右下角结束,只要图形点顺时针排列就可以挖洞了
            })
          });
        }
    

    相应的html:

    <div id="mapDiv" style="position:relative;background:url(plug-in/mapviews/assets/gw2.png);">
    </div>
    <div id="regiondivl" class ='shadediv'></div>
    
    .shadediv{
        position: absolute; 
        top:0px; 
        left:0px; 
        width:100%; 
        height:100%; 
        z-index:990;
        background:url(../assets/gw2.png);//这个背景图片也可以换成纯色,只要和地图底色一致就可以
    }
    

    效果图:

    总结:在最终呈现的效果上,css的效果最佳,同时也存在一个问题,当范围面点位过多时,地图拖拽缩放会有一些延迟,我们的做法是将范围面做简化处理,40~50个点位还是可以保障图形的基本特别,同时减轻css裁切的负担。

    展开全文
  • 本文借助easyx库函数(提供下载链接),很方便地用C语言实现了鼠标、按钮、进度条、坐标尺操作,为普通C程序的友好人机交互界面提供了一种简单便捷的方案。

    0.引言

    \qquad 看了CSDN上很多关于C程序图形化界面的介绍,有的代码繁琐难解,不方便调试修改;有的不够详细。本文提供的代码简单、易于移植、容易理解,望急需使用C语言制作图形化界面的朋友采纳。
    \qquad 对easyx尚不熟悉的朋友不需要担心,我敢打包票它只需10分钟就可以上手,而它为你节省的时间可能是3个小时甚至更多。关于easyx的简单应用请参考一篇我以前写的关于C程序可视化的博文。
    →【C语言实现动画控制】←
    \qquad 本文的讲解是循序渐进的,读者应该重点关注每个步骤的理解,两步之间代码的变化,即可完全理解本文。

    1.素材准备

    1. easyx的下载链接如下:(本文使用的版本是2014冬至版)
      https://www.easyx.cn/downloads/
      注:使用easyx需要注意它兼容的编译器(下载的帮助文件会写),不同的easyx兼容的编译器不同,但总是和visual C++6兼容(和字符编码有关),本文以visual C++6编译器为例书写代码。
    2. easyx的最新英文帮助文档链接(下载2014冬至版会自带中文帮助文档):
      https://docs.easyx.cn/en-us/intro
    3. 如果你成功下载了easyx2014冬至版,那么解压后把头文件(easyx.h和graphic.h)和lib文件(amd64)分别放在VC文件夹默认的include文件夹和lib文件夹中。右键你的VC程序,选择打开文件所在位置,然后找到MFC文件夹,友情提供两个文件夹的位置截图。
      include
      lib
    4. 建议编译的C文件以cpp后缀保存。

    2.编程

    2.1.创建你的界面

    \qquad 创建一个480×360的窗口,我们需要使用initgraph()函数,闲言少叙,让我们直接看一段代码:

    #include <graphics.h>              // 引用图形库头文件
    #include <conio.h>
    #include <stdio.h>
    #include <windows.h>				//用到了定时函数sleep()
    #include <math.h>
    
    int main()
    {
    	int i;
    	short win_width,win_height;//定义窗口的宽度和高度
    	win_width = 480;win_height = 360;
    	initgraph(win_width,win_height);//初始化窗口(黑屏)
    	for(i=0;i<256;i+=5)
    	{
    		setbkcolor(RGB(i,i,i));//设置背景色,原来默认黑色
    		cleardevice();//清屏(取决于背景色)
    		Sleep(15);//延时15ms
    	}
    	closegraph();//关闭绘图界面
    }
    
    

    \qquad 这段代码很容易理解,运行这段程序,就会出现逐渐明亮的屏幕。因为不断刷新背景色为 R G B ( i , i , i ) RGB(i,i,i) RGB(i,i,i)。C语言中的颜色使用十六进制表示的,RGB函数可以将0~255范围内的三个整数三原色转换成这个十六进制。
    \qquad cleardevice()函数用于清屏,是界面内所有元素都被清空,一般只会在初始化出现。
    \qquad Sleep()是毫秒级延迟,当然界面变亮时间不一定是准确的15ms×255/5=0.765s,因为其他语句还需要执行时间。
    \qquad closegraph():关闭绘图界面。注意,如果初始化了绘图界面但没有在主函数结束前关闭它,可能会引发一些莫名其妙的错误!所以这个函数一定要有!

    2.2.创建按钮

    \qquad 我们尝试在界面创建几个按钮,按钮需要的操作是绘制矩形和打印文字。虽然看着简单,但是里面还是有点学问,为了方便大家理解,还是先放上代码和注释。

    #include <graphics.h>              // 引用图形库头文件
    #include <conio.h>
    #include <stdio.h>
    #include <windows.h>				//用到了定时函数sleep()
    #include <math.h>
    int r1[]={30,20,130,60};//输入按钮的矩形参数
    int r2[]={170,20,220,60};//运行按钮的矩形参数
    int r3[]={260,20,310,60};//退出按钮的矩形参数
    int main()
    {
    	int i;
    	short win_width,win_height;//定义窗口的宽度和高度
    	win_width = 480;win_height = 360;
    	initgraph(win_width,win_height);//初始化窗口(黑屏)
    	for(i=0;i<256;i+=5)
    	{
    		setbkcolor(RGB(i,i,i));//设置背景色,原来默认黑色
    		cleardevice();//清屏(取决于背景色)
    		Sleep(15);//延时15ms
    	}
    	RECT R1={r1[0],r1[1],r1[2],r1[3]};//矩形指针R1
    	RECT R2={r2[0],r2[1],r2[2],r2[3]};//矩形指针R2
    	RECT R3={r3[0],r3[1],r3[2],r3[3]};//矩形指针R3
    	LOGFONT f;//字体样式指针
    	gettextstyle(&f);					//获取字体样式
    	_tcscpy(f.lfFaceName,_T("宋体"));	//设置字体为宋体
    	f.lfQuality = ANTIALIASED_QUALITY;    // 设置输出效果为抗锯齿  
    	settextstyle(&f);                     // 设置字体样式
    	settextcolor(BLACK);				//BLACK在graphic.h头文件里面被定义为黑色的颜色常量
    	drawtext("输入参数",&R1,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R1内输入文字,水平居中,垂直居中,单行显示
    	drawtext("运行",&R2,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R2内输入文字,水平居中,垂直居中,单行显示
    	drawtext("退出",&R3,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R3内输入文字,水平居中,垂直居中,单行显示
    	setlinecolor(BLACK);
    	rectangle(r1[0],r1[1],r1[2],r1[3]);
    	rectangle(r2[0],r2[1],r2[2],r2[3]);
    	rectangle(r3[0],r3[1],r3[2],r3[3]);
    	system("pause");//暂停,为了显示
    	closegraph();
    	return 0;
    }
    

    在这里插入图片描述
    \qquad 这里需要特别介绍的是矩形指针 p R e c t pRect pRect,它使用句柄RECT定义,并且不可以中途再次赋值。之所以要设置矩形指针了为了打印字体的时候以矩形为边界自动填充。它的格式是RECT r={X1,Y1,X2,Y2},X1和X2是矩形的左边和右边的横坐标,Y1和Y2是矩形的上边和下边的纵坐标,这一点和rectangle()绘制空心矩形函数参数排列一致。后面的DT_CENTER | DT_VCENTER | DT_SINGLELINE就是描述填充格式的常量。使用drawtext书写文字不需要再计算文字的坐标和设置大小,会方便很多。
    \qquad LOGFONT是字体样式指针,通过gettextstyle()函数来获取当前的字体类型,再通过settextstyle()函数加以设置。这里只修改了字体的名称和显示质量,还可以修改斜体、下划线等属性,更详细的部分请参考帮助文档。

    2.3.鼠标操作

    2.3.1.单击特效

    \qquad 作为一个图形化界面的C程序,鼠标操作总不能少吧。在讲解程序前先别着急,简单为大家科普一下鼠标事件:
    \qquad 鼠标是输入设备,只要发生以下的事件,就会暂存在鼠标消息列表中,我们的操作系统就会依次响应列表中的鼠标消息事件,常用的鼠标事件如下:

    • WM_MOUSEMOVE——鼠标移动
    • WM_MOUSEWHEEL——鼠标滚轮滚动
    • WM_LBUTTONDOWN——鼠标左键按下
    • WM_LBUTTONUP——鼠标左键弹起
    • WM_LBUTTONDBLCLK——鼠标左键双击
    • WM_RBUTTONDOWN——鼠标右键按下
    • WM_RBUTTONUP——鼠标右键弹起
    • WM_RBUTTONDBLCLK——鼠标左键双击
    • WM_MBUTTONDOWN——鼠标中键按下
    • WM_MBUTTONUP——鼠标中键弹起
    • WM_MBUTTONDBLCLK——鼠标中键双击
      \qquad 我们只需要根据不断获取鼠标消息队列的消息并根据消息依次进行响应即可。

    \qquad 相信大家已经迫不及待了,那么请看下面一个简单的程序。

    #include <graphics.h>              // 引用图形库头文件
    #include <conio.h>
    #include <stdio.h>
    #include <windows.h>				//用到了定时函数sleep()
    #include <math.h>
    int r1[]={30,20,130,60};//输入按钮的矩形参数
    int r2[]={170,20,220,60};//运行按钮的矩形参数
    int r3[]={260,20,310,60};//退出按钮的矩形参数
    int main()
    {
    	int i;
    	short win_width,win_height;//定义窗口的宽度和高度
    	win_width = 480;win_height = 360;
    	initgraph(win_width,win_height);//初始化窗口(黑屏)
    	for(i=0;i<256;i+=5)
    	{
    		setbkcolor(RGB(i,i,i));//设置背景色,原来默认黑色
    		cleardevice();//清屏(取决于背景色)
    		Sleep(15);//延时15ms
    	}
    	RECT R1={r1[0],r1[1],r1[2],r1[3]};//按钮1的矩形区域
    	RECT R2={r2[0],r2[1],r2[2],r2[3]};//按钮2的矩形区域
    	RECT R3={r3[0],r3[1],r3[2],r3[3]};//按钮2的矩形区域
    	LOGFONT f;
    	gettextstyle(&f);					//获取字体样式
    	_tcscpy(f.lfFaceName,_T("宋体"));	//设置字体为宋体
    	f.lfQuality = ANTIALIASED_QUALITY;    // 设置输出效果为抗锯齿  
    	settextstyle(&f);                     // 设置字体样式
    	settextcolor(BLACK);				//BLACK在graphic.h头文件里面被定义为黑色的颜色常量
    	drawtext("输入参数",&R1,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R1内输入文字,水平居中,垂直居中,单行显示
    	drawtext("运行",&R2,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R2内输入文字,水平居中,垂直居中,单行显示
    	drawtext("退出",&R3,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R3内输入文字,水平居中,垂直居中,单行显示
    	setlinecolor(BLACK);
    	rectangle(r1[0],r1[1],r1[2],r1[3]);
    	rectangle(r2[0],r2[1],r2[2],r2[3]);
    	rectangle(r3[0],r3[1],r3[2],r3[3]);
    	MOUSEMSG m;//鼠标指针
    	setrop2(R2_NOTXORPEN);//二元光栅——NOT(屏幕颜色 XOR 当前颜色)
    	while(true)
    	{
    		m = GetMouseMsg();//获取一条鼠标消息
    		if(m.uMsg==WM_LBUTTONDOWN)
    		{
    			for(i=0;i<=10;i++)
    			{
    				setlinecolor(RGB(25*i,25*i,25*i));//设置圆颜色
    				circle(m.x,m.y,2*i);
    				Sleep(25);//停顿2ms
    				circle(m.x,m.y,2*i);//抹去刚刚画的圆
    			}
    			FlushMouseMsgBuff();//清空鼠标消息缓存区
    		}
    	}
    	system("pause");//暂停,为了显示
    	closegraph();
    	return 0;
    }
    
    
    

    在这里插入图片描述
    \qquad 每点击鼠标以下,应该可以看到鼠标点击处有一个逐渐扩大并淡出的圆(截图无法清晰,在画面的中右侧),当循环体内Sleep的视觉大于20ms后视觉效果很强。
    \qquad 每响应一次鼠标左键单击事件,都会调用一次清空鼠标消息缓存区的函数FlushMouseMsgBuff(),如果没有这个函数会怎么样呢?如果我们快速连续地单击鼠标左键N次,那么特效就会播放N次,如果特效播放速度比单击的速度慢,那么即使你停下来了,程序仍然会接着播放单击特效,因为你的左键单击仍然在鼠标的消息队列m.uMsg中的鼠标消息没有响应完。
    \qquad 这里需要解释的是一个二元光栅设置函数setrop2(),二元光栅是混合背景色和当前颜色的模式。我们这里采用的方式是同或(NOT XOR)的方式,若底色为白色(1),则当前颜色不变;若底色是黑色(0),则当前颜色反色。为什么需要采用这种方式呢?因为我们在第二次抹去原来的圆的时候不能采用白色,否则如果背景色原来就为黑(比如按钮和文字),就也会被抹成白色。而背景色与任意一个颜色同或两次都为其本身,即可起到还原背景色的效果。这里的背景色与cleardevice()前面那个背景色不同,这里的是指执行这一条绘画指令之前屏幕上的颜色。

    2.3.2.光标感应

    \qquad 我们希望鼠标移到按钮上时按钮会有所变化,移开按钮时又会回到原样。这里我们采用一种简单的填充颜色的方法,就是按钮变色。我们需要解决一个问题就是按钮变色了但是按钮的文字不能被覆盖,那么我们还是需要使用到二元光栅。只是我们这次的模式改成了同或。
    \qquad 为了方便起见,存放三个按钮的数组我们合并为了一个二维数组,在鼠标事件中更容易使用和分配任务。

    #include <graphics.h>              // 引用图形库头文件
    #include <conio.h>
    #include <stdio.h>
    #include <windows.h>				//用到了定时函数sleep()
    #include <math.h>
    int r[3][4]={{30,20,130,60},{170,20,220,60},{260,20,310,60}};//三个按钮的二维数组
    
    int button_judge(int x,int y)
    {
    	if(x>r[0][0] && x<r[0][2] && y>r[0][1] && y<r[0][3])return 1;
    	if(x>r[1][0] && x<r[1][2] && y>r[1][1] && y<r[1][3])return 2;
    	if(x>r[2][0] && x<r[2][2] && y>r[2][1] && y<r[2][3])return 3;
    	return 0;
    }
    int main()
    {
    	int i,event=0;
    	short win_width,win_height;//定义窗口的宽度和高度
    	win_width = 480;win_height = 360;
    	initgraph(win_width,win_height);//初始化窗口(黑屏)
    	for(i=0;i<256;i+=5)
    	{
    		setbkcolor(RGB(i,i,i));//设置背景色,原来默认黑色
    		cleardevice();//清屏(取决于背景色)
    		Sleep(15);//延时15ms
    	}
    	RECT R1={r[0][0],r[0][1],r[0][2],r[0][3]};
    	RECT R2={r[1][0],r[1][1],r[1][2],r[1][3]};
    	RECT R3={r[2][0],r[2][1],r[2][2],r[2][3]};
    	LOGFONT f;
    	gettextstyle(&f);					//获取字体样式
    	_tcscpy(f.lfFaceName,_T("宋体"));	//设置字体为宋体
    	f.lfQuality = ANTIALIASED_QUALITY;    // 设置输出效果为抗锯齿  
    	settextstyle(&f);                     // 设置字体样式
    	settextcolor(BLACK);				//BLACK在graphic.h头文件里面被定义为黑色的颜色常量
    	drawtext("输入参数",&R1,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R1内输入文字,水平居中,垂直居中,单行显示
    	drawtext("运行",&R2,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R2内输入文字,水平居中,垂直居中,单行显示
    	drawtext("退出",&R3,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R3内输入文字,水平居中,垂直居中,单行显示
    	setlinecolor(BLACK);
    	rectangle(r[0][0],r[0][1],r[0][2],r[0][3]);
    	rectangle(r[1][0],r[1][1],r[1][2],r[1][3]);
    	rectangle(r[2][0],r[2][1],r[2][2],r[2][3]);
    	MOUSEMSG m;//鼠标指针
    	
    	while(true)
    	{
    		m = GetMouseMsg();//获取一条鼠标消息
    
    		switch(m.uMsg)
    		{
    			case WM_MOUSEMOVE:
    				setrop2(R2_XORPEN);
    				setlinecolor(LIGHTCYAN);//线条颜色为亮青色
    				setlinestyle(PS_SOLID, 3);//设置画线样式为实现,10磅
    				setfillcolor(WHITE);//填充颜色为白色
    				if(button_judge(m.x,m.y)!=0)
    				{
    					if(event != button_judge(m.x,m.y))
    					{
    						event = button_judge(m.x,m.y);//记录这一次触发的按钮
    						fillrectangle(r[event-1][0],r[event-1][1],r[event-1][2],r[event-1][3]);//有框填充矩形(X1,Y1,X2,Y2)
    					}
    				}
    				else
    				{
    					if(event != 0)//上次触发的按钮未被修正为原来的颜色
    					{
    						fillrectangle(r[event-1][0],r[event-1][1],r[event-1][2],r[event-1][3]);//两次同或为原来颜色
    						event = 0;
    					}
    				}
    				break;
    			case WM_LBUTTONDOWN:
    				setrop2(R2_NOTXORPEN);//二元光栅——NOT(屏幕颜色 XOR 当前颜色)
    				for(i=0;i<=10;i++)
    				{
    					setlinecolor(RGB(25*i,25*i,25*i));//设置圆颜色
    					circle(m.x,m.y,2*i);
    					Sleep(30);//停顿30ms
    					circle(m.x,m.y,2*i);//抹去刚刚画的圆
    				}
    				break;
    				FlushMouseMsgBuff();//清空鼠标消息缓存区
    		}
    	}
    	system("pause");//暂停,为了显示
    	return 0;
    }
    
    

    在这里插入图片描述
    \qquad 这里我们运用了两次设置二元光栅的函数setrop2,在鼠标的移动条件内(case MOUSEMOVE),我们使用的是屏幕颜色和当前颜色异或,这是为什么呢?因为fillrectangle()函数是画一个有框填充矩形,我们让这个有框填充矩形和原按钮的一样大。由于线条的颜色为亮青色,填充颜色为白色(1),白色的填充颜色和屏幕颜色异或,取的是屏幕颜色的反色。按钮的边框是黑色(0),它与亮青色异或,则会保留原来的亮青色。
    \qquad 与同或一样,异或两次等于没有执行操作,所以可以还原到原屏幕画布的颜色。

    2.3.3.进度条

    \qquad 既然涉及到进度条了,那么就应该涉及到正式程序了,这里我不想涉及太多的专业知识影响大家理解,但又不能让程序运行得太快以至于看不出进度条的变化,所以我设计了一个简单的弹性球轨迹作图程序。
    \qquad 假设球半径为R,初始高度为 h 0 h_0 h0,初速度为0(自由落体),非弹性碰撞时能量损失率为 α \alpha α。计算部分子函数如下:

    int simulation()
    {
    	float dt = 0.01;//仿真间隔10ms
    	long int N = (long int)(sim_t/dt);//迭代次数
    	float *h=(float*)calloc(N,sizeof(float));//高度
    	float *v=(float*)calloc(N,sizeof(float));//速度(竖直方向)
    	long int i;//迭代变量
    	for(i=1;i<N;i++)
    	{
    		if(h[i-1]>R)//未发生碰撞
    		{
    			v[i]=v[i-1]-9.8*dt;//速度计算
    		}
    		else//发生碰撞,动能损失alpha,速度损失alpha的开方
    		{
    			v[i]=-sqrt(alpha)*v[i-1];	
    		}
    	}
    	free(h);
    	free(v);//释放内存
    	return 0;
    }
    

    \qquad 当然,我们还需要绘图网格,定义绘图网格的函数如下:

    void init_figure()
    {
    	int i;
    	setrop2(R2_COPYPEN);//当前颜色
    	setlinecolor(BLACK);
    	setlinestyle(PS_SOLID);//实线
    	rectangle(30,100,420,330);//外框线
    	setlinestyle(PS_DOT);//点线
    	for(i=30+39;i<420;i+=39)
    	{
    		line(i,100,i,330);//竖直辅助线
    	}
    	for(i=100+23;i<330;i+=23)
    	{
    		line(30,i,420,i);//水平辅助线
    	}
    }
    

    \qquad 注意,我们使用了rectangle()空心矩形函数绘制网格外框架,使用了line函数依次画出了辅助线。

    \qquad 我们现在的目标就是将h的坐标转换到网格上去,绘制出球心的轨迹,这样似乎并不复杂,只需要对simulation()函数稍加修改即可。

    int simulation()
    {
    	float dt = 0.01;//仿真间隔10ms
    	float dy = 230/h0;//单位纵坐标
    	long int N = (long int)(sim_t/dt);//迭代次数
    	float *h=(float*)calloc(N,sizeof(float));//高度
    	float *v=(float*)calloc(N,sizeof(float));//速度(竖直方向)
    	long int i;//迭代变量
    	float process_duty;//进度
    	init_figure();//初始化图像网格
    	setrop2(R2_COPYPEN);//当前颜色
    	//计算步骤
    	h[0]=h0;v[0]=0;
    	for(i=1;i<N;i++)
    	{
    		if(h[i-1]>R)//未发生碰撞
    		{
    			v[i]=v[i-1]-9.8*dt;//速度计算
    		}
    		else//发生碰撞,动能损失alpha,速度损失alpha的开方
    		{
    			v[i]=-sqrt(alpha)*v[i-1];	
    		}
    		h[i]=h[i-1]+v[i]*dt;//高度计算
    		process_duty = (i+1)/(float)(N);
    		putpixel(30+(int)(process_duty*390),330-(int)(h[i]*dy),RED);//画点putpixel(X,Y,color*)
    		Sleep(dt*1000);//延时
    	}
    	free(h);
    	free(v);
    	return 0;
    }
    

    \qquad 这里的新函数putpixel(X,Y,color*)是画像素点的函数,适合刻画不连续或不规则的移动轨迹。
    \qquad 现在我们只剩下了刻画进度条的函数了,进度条的刷新很明显是应该放在for循环里面的,那么我们采用什么进度条的格式呢?进度条可以有圆形、扇形、长条连续型、长条不连续型等多种,我们这里采用的是环形进度条,将进度数字显示在环中心。请看以下的对simulation()函数改进的代码:

    //仿真运行
    int simulation()
    {
    	char t[3];//百分值的字符
    	char *out_text;//带百分号的百分字符
    	float dt = 0.01;//仿真间隔10ms
    	float dy = 230/h0;//单位纵坐标
    	long int N = (long int)(sim_t/dt);//迭代次数
    	float *h=(float*)calloc(N,sizeof(float));//高度
    	float *v=(float*)calloc(N,sizeof(float));//速度(竖直方向)
    	long int i;//迭代变量
    	float process_duty;//进度
    	RECT r={370,35,400,65};//百分值显示区域的矩形指针
    	init_figure();//初始化图像网格
    	setrop2(R2_COPYPEN);//当前颜色
    	setfillcolor(WHITE);
    	setlinecolor(WHITE);
    	fillrectangle(354,19,411,81);//覆盖原进度条区域
    	setlinestyle(PS_NULL);//无线条
    	setbkmode(TRANSPARENT);//设置文字填充背景为透明
    	//计算步骤
    	h[0]=h0;v[0]=0;
    	BeginBatchDraw();//开始缓存区
    	for(i=1;i<N;i++)
    	{
    		if(h[i-1]>R)//未发生碰撞
    		{
    			v[i]=v[i-1]-9.8*dt;//速度计算
    		}
    		else//发生碰撞,动能损失alpha,速度损失alpha的开方
    		{
    			v[i]=-sqrt(alpha)*v[i-1];	
    		}
    		setfillcolor(WHITE);
    		setlinecolor(WHITE);
    		fillrectangle(354,19,416,81);//覆盖原进度条区域
    		h[i]=h[i-1]+v[i]*dt;//高度计算
    		process_duty = (i+1)/(float)(N);
    		setlinestyle(PS_SOLID);
    		putpixel(30+(int)(process_duty*390),330-(int)(h[i]*dy),RED);
    		setfillcolor(BLUE);
    		setlinestyle(PS_NULL);
    		fillpie(355,20,415,80,0,process_duty*2*PI);
    		setfillcolor(WHITE);
    		fillcircle(385,50,20);
    		sprintf(t,"%d",(int)(process_duty*100.0));//整型转换为字符串
    		out_text = strcat(t,"%");//添加一个百分号
    		drawtext(out_text,&r,DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    		Sleep(dt*1000);
    		FlushBatchDraw();//刷新缓存区
    	}
    	EndBatchDraw();//结束缓存区
    	free(h);
    	free(v);
    	return 0;
    }
    

    \qquad 这里我们需要多加载一个头文件<string.h>。
    \qquad 首先需要计算进度条的坐标,把环形进度条区域用白色矩形刷新掉,环形进度条需要一个扇形和圆形的组合,扇形的角度是0~360°。这里我们用到了fillpie(X1,Y1,X2,Y2,start_angle,end_angle),前四个参数为椭圆扇形的外接矩形坐标,后两个参数分别为起始角和终止角(弧度制)。每过一次迭代都重新计算终止角(起始角始终为0),即可起到扇形角度逐渐增长的效果,再用一个白色填充圆覆盖中心部分即可变成环形进度条。
    \qquad FlushBatchDraw()函数是刷新缓存区的函数,与BeginBatchDraw()EndBatchDraw()一起使用,如果我们绘图之后不想立即显示,而想批量绘图最后一起刷新画板,用缓存区的方法再合适不过了。

    3.完整代码及效果

    #include <graphics.h>              // 引用图形库头文件
    #include <conio.h>
    #include <stdio.h>
    #include <windows.h>				//用到了定时函数sleep()
    #include <math.h>
    #include <string.h>
    #define PI 3.1416
    int r[3][4]={{30,20,130,60},{170,20,220,60},{260,20,310,60}};//三个按钮的二维数组
    float alpha,R,h0,sim_t;//碰撞时的能量损失率,球的半径、初始高度、仿真时间
    //按钮判断函数
    int button_judge(int x,int y)
    {
    	if(x>r[0][0] && x<r[0][2] && y>r[0][1] && y<r[0][3])return 1;
    	if(x>r[1][0] && x<r[1][2] && y>r[1][1] && y<r[1][3])return 2;
    	if(x>r[2][0] && x<r[2][2] && y>r[2][1] && y<r[2][3])return 3;
    	return 0;
    }
    //初始化图像
    void init_figure()
    {
    	int i;
    	setrop2(R2_COPYPEN);//当前颜色
    	setlinecolor(BLACK);
    	setlinestyle(PS_SOLID);//实线
    	rectangle(30,100,420,330);//外框线
    	setlinestyle(PS_DOT);//点线
    	for(i=30+39;i<420;i+=39)
    	{
    		line(i,100,i,330);//竖直辅助线
    	}
    	for(i=100+23;i<330;i+=23)
    	{
    		line(30,i,420,i);//水平辅助线
    	}
    }
    //仿真运行
    int simulation()
    {
    	char t[3];//百分值的字符
    	char *out_text;
    	float dt = 0.01;//仿真间隔10ms
    	float dy = 230/h0;//单位纵坐标
    	long int N = (long int)(sim_t/dt);//迭代次数
    	float *h=(float*)calloc(N,sizeof(float));//高度
    	float *v=(float*)calloc(N,sizeof(float));//速度(竖直方向)
    	long int i;//迭代变量
    	float process_duty;//进度
    	RECT r={370,35,400,65};//百分值显示区域的矩形指针
    	init_figure();//初始化图像网格
    	setrop2(R2_COPYPEN);//当前颜色
    	setfillcolor(WHITE);
    	setlinecolor(WHITE);
    	fillrectangle(354,19,411,81);//覆盖原进度条区域
    	setlinestyle(PS_NULL);//无线条
    	setbkmode(TRANSPARENT);//设置文字填充背景为透明
    	//计算步骤
    	h[0]=h0;v[0]=0;
    	BeginBatchDraw();//开始缓存区
    	for(i=1;i<N;i++)
    	{
    		if(h[i-1]>R)//未发生碰撞
    		{
    			v[i]=v[i-1]-9.8*dt;//速度计算
    		}
    		else//发生碰撞,动能损失alpha,速度损失alpha的开方
    		{
    			v[i]=-sqrt(alpha)*v[i-1];	
    		}
    		setfillcolor(WHITE);
    		setlinecolor(WHITE);
    		fillrectangle(354,19,416,81);//覆盖原进度条区域
    		h[i]=h[i-1]+v[i]*dt;//高度计算
    		process_duty = (i+1)/(float)(N);
    		setlinestyle(PS_SOLID);
    		putpixel(30+(int)(process_duty*390),330-(int)(h[i]*dy),RED);
    		setfillcolor(BLUE);
    		setlinestyle(PS_NULL);
    		fillpie(355,20,415,80,0,process_duty*2*PI);
    		setfillcolor(WHITE);
    		fillcircle(385,50,20);
    		sprintf(t,"%d",(int)(process_duty*100.0));//整型转换为字符串
    		out_text = strcat(t,"%");//添加一个百分号
    		drawtext(out_text,&r,DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    		Sleep(dt*1000);
    		FlushBatchDraw();//刷新缓存区
    	}
    	EndBatchDraw();//结束缓存区
    	free(h);
    	free(v);
    	return 0;
    }
    
    int main()
    {
    	int i,event=0;
    	char s[30];//输入字符串变量
    	short win_width,win_height;//定义窗口的宽度和高度
    	win_width = 480;win_height = 360;
    	initgraph(win_width,win_height);//初始化窗口(黑屏)
    	for(i=0;i<256;i+=5)
    	{
    		setbkcolor(RGB(i,i,i));//设置背景色,原来默认黑色
    		cleardevice();//清屏(取决于背景色)
    		Sleep(30);//延时30ms
    	}
    	RECT R1={r[0][0],r[0][1],r[0][2],r[0][3]};
    	RECT R2={r[1][0],r[1][1],r[1][2],r[1][3]};
    	RECT R3={r[2][0],r[2][1],r[2][2],r[2][3]};
    	LOGFONT f;//字体样式指针
    	gettextstyle(&f);					//获取字体样式
    	_tcscpy(f.lfFaceName,_T("宋体"));	//设置字体为宋体
    	f.lfQuality = ANTIALIASED_QUALITY;    // 设置输出效果为抗锯齿  
    	settextstyle(&f);                     // 设置字体样式
    	settextcolor(BLACK);				//BLACK在graphic.h头文件里面被定义为黑色的颜色常量
    	drawtext("输入参数",&R1,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R1内输入文字,水平居中,垂直居中,单行显示
    	drawtext("运行",&R2,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R2内输入文字,水平居中,垂直居中,单行显示
    	drawtext("退出",&R3,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R3内输入文字,水平居中,垂直居中,单行显示
    	setlinecolor(BLACK);
    	rectangle(r[0][0],r[0][1],r[0][2],r[0][3]);
    	rectangle(r[1][0],r[1][1],r[1][2],r[1][3]);
    	rectangle(r[2][0],r[2][1],r[2][2],r[2][3]);
    	MOUSEMSG m;//鼠标指针
    	
    	while(true)
    	{
    		m = GetMouseMsg();//获取一条鼠标消息
    
    		switch(m.uMsg)
    		{
    			case WM_MOUSEMOVE:
    				setrop2(R2_XORPEN);
    				setlinecolor(LIGHTCYAN);//线条颜色为亮青色
    				setlinestyle(PS_SOLID, 3);//设置画线样式为实现,10磅
    				setfillcolor(WHITE);//填充颜色为白色
    				if(button_judge(m.x,m.y)!=0)
    				{
    					if(event != button_judge(m.x,m.y))
    					{
    						event = button_judge(m.x,m.y);//记录这一次触发的按钮
    						fillrectangle(r[event-1][0],r[event-1][1],r[event-1][2],r[event-1][3]);//有框填充矩形(X1,Y1,X2,Y2)
    					}
    				}
    				else
    				{
    					if(event!=0)//上次触发的按钮未被修正为原来的颜色
    					{
    						fillrectangle(r[event-1][0],r[event-1][1],r[event-1][2],r[event-1][3]);//两次同或为原来颜色
    						event = 0;
    					}
    				}
    				break;
    			case WM_LBUTTONDOWN:
    				setrop2(R2_NOTXORPEN);//二元光栅——NOT(屏幕颜色 XOR 当前颜色)
    				for(i=0;i<=10;i++)
    				{
    					setlinecolor(RGB(25*i,25*i,25*i));//设置圆颜色
    					circle(m.x,m.y,2*i);
    					Sleep(20);//停顿30ms
    					circle(m.x,m.y,2*i);//抹去刚刚画的圆
    				}
    				//按照按钮判断左键单击后的操作
    				switch(button_judge(m.x,m.y))
    				{
    					//复原按钮原型
    					case 1:
    						InputBox(s,30,"请输入碰撞时的能量损失率、球的半径、初始高度、仿真时间");
    						sscanf(s,"%f%f%f%f",&alpha,&R,&h0,&sim_t);//将输入字符串依次扫描到全局变量里面
    						FlushMouseMsgBuffer();//单击事件后清空鼠标消息
    						break;
    					case 2:
    						simulation();//仿真运行
    						FlushMouseMsgBuffer();//单击事件后清空鼠标消息
    						break;
    					case 3:
    						closegraph();//关闭绘图环境
    						exit(0);//正常退出
    					default:
    						FlushMouseMsgBuffer();//单击事件后清空鼠标消息
    						//printf("\r\n(%d,%d)",m.x,m.y);//打印鼠标坐标,方便调试时确定区域
    						break;
    				}
    				break;
    		}
    	}
    	return 0;
    }
    
    

    在这里插入图片描述
    在这里插入图片描述
    希望本文对您有帮助,谢谢阅读。

    展开全文
  • 【学习ing】二维不规则多边形排样问题

    千次阅读 多人点赞 2019-10-18 10:14:12
    的方式将问题转化为矩形排样,但是对于大尺寸不规则图形,边角空间有很大的浪费,利用率不高。 网格划分:将object和shapes划分成网格,并使用0-1矩阵来描述空间被占用的情况,再进行优化。划分粒度对结果影响较大...
  • opencv11-计算不规则图像的质心

    万次阅读 2017-08-11 16:31:00
    不规则区域的矩,表示一个归一化的灰度级图像函数理解为一个二维随机变量的概率密度。 这个随机变量的属性可以用统计特征-矩(moments)来描述。通过假设非零的像素值表示区域,矩可以用于二值或灰度级的区域...
  • visio绘制自定义图形(完全零基础)

    千次阅读 2022-04-30 22:57:25
    版本使用的是2016,操作方法同样适用于2007/...有一点挺重要的是,我们需要开发工具打开(默认是没有的) 文件-选项-自定义功能区-将开发工具打勾勾-确定 然后上面就有这个东西 然后对要做的图形进行分析(这
  • 一、二维图形变化之基本知识 本章涉及向量、世界坐标系、用户坐标系、窗口与视区、齐次坐标、二维变换 。需要掌握的知识点有: 向量、矩阵以及它们的运算 坐标系的概念和坐标系之间的变换齐次坐标的概念二维...
  • 一、三维物体基本几何变换 主要讨论如下几个问题 :如何对三维图形进行方向、尺寸和形状方面的变换 ?三维物体如何在二维输出设备上输出 ?通过三维图形变换,可由简单图形得到复杂图形,三维图形变换则分为三维...
  • 【例题】下面的六个图形分为两类,使每一类图形都有各目的共同特征或规律,分类正确的一项∶() A.①②④,③⑤⑥ B.①②⑤,③④⑥ D.①③⑥,②④⑤ C.①③④,②⑤⑥ 解析:观察图形可知①③⑥中直线与曲线的...
  • 真实图形学(光照模型)

    万次阅读 多人点赞 2018-04-30 11:54:14
    真实感图形学,简单地说,就是希望用计算机生成像照相机拍的照片一样逼真的图形图像 。要实现这个目标,需要三部曲: 第一步:建立三维场景(建模); 第二步:消隐解决物体深度的显示及确定物体之内的相互关系;...
  • 接上文 计算机图形学 学习笔记(六):消隐算法:Z-buffer,区间扫描线,Warnock,光栅图形学小结在图形学中,有两大基本工具:向量分析,图形变换。本文将重点讲解向量和二维图形的变换。5.1 向量基础知识我们所...
  • 不规则物体形状匹配综述

    千次阅读 2013-05-13 19:27:07
    物体识别是计算机视觉应用的一项基本任务。识别通常基于目标物体的灰度信息、颜色信息或形状信息。物体识别的目的就是要...根据匹配对象的不同,可以将不规则物体的形状匹配分为基于区域的匹配方法和基于轮廓的匹配方
  • 计算机图形学概述

    千次阅读 多人点赞 2020-06-02 10:24:26
    文章目录一、 图形学基本概念1.1 基本概念1.2 图形及构成要素1.3 计算机中表示图形的方法1.4 计算机图形学的定义1.5 学科间关系1.6 图形学、图像处理、模式识别的异同二、计算机图形学的发展2.1 图形技术发展2.2 ...
  • 谁能告诉我这科的理论在哪可以实用呀?搞懂,只能收藏一下包挂科
  • 计算机图形学复习1

    千次阅读 2020-08-17 20:32:32
    由于需要准备计算机图形学的考试,开始复习计算机图形学,这里将持续为大家带来图形学的基础内容更新和一些例题讲解。希望能够更新完成吧。喜欢的小伙伴可以先关注博主,以免找到。 计算机图形学复习0 距离上篇...
  • esri-leaflet入门教程(5)-...但如果要做一列的地图交互操作或者动态渲染等,那就必须使用地图区域跳转、查询结果渲染、动态添加图形等多种交互手段。而这些交互手段基本上离开一些非服务类型的数据加载,我们可以将
  • 计算机图形学入门OpenGL

    千次阅读 2019-07-30 19:49:05
    计算机图形学openGL 计算机图形学:(Computer Graphics, 简称CG) 简单得说:计算机图形学是一种使用数学算法将二维或者三维图形转化为计算机显示器所能显示的二维栅格形式的科学。 Modeling(建模):构造场景的三维...
  • 这是三栏布局的正中间部分 </div> <div class="right"></div> </article> </section> </body> </html> 展示效果 知识拓展 上述5中解决方式是比较常见的,但是我们能只局限于为了问答而问答,我们应该从此基础上...
  • 超硬核!数据结构学霸笔记,考试面试吹牛就靠它

    万次阅读 多人点赞 2021-03-26 11:11:21
    主要内容: 1、函数传数组就是传了个指针,这个大家都知道,所以传的时候你写arr[],里面写多少,或者写,都是没关系的,那你后面一定要放一个变量来数组长度传进来。 2、还有就是,定义:int arr[5],你访问...
  •   2019-01-22 15:32:10 ...由于高度复杂但信息丰富的图形结构,图形上的机器学习一直以来都是一项艰巨的任务。本文是关于如何使用图形卷积网络(GCN)进行图形深度学习的系列文章中的第二篇。...
  • CAD考试规则评分标准

    千次阅读 2021-07-25 06:54:40
    《CAD考试规则评分标准》由会员分享,可在线阅读,更多相关《CAD考试规则评分标准(3页珍藏版)》请在人人文库网上搜索。1、考试注意事项试卷中的所有题目均由考生在计算机上通过绘图软件完成,并保存在指定的位置。...
  • 每日在实验室学(hua)习(shui),不知不觉图形学作业要交了。虽然不会做,但是要交作业,还是得逼一自己,在实验室博士师姐热心的帮我要了博士师兄的作业后,我满怀期待的打开,一脸失望的退出。okkkkkkk ! ...
  • 光栅图形学算法——裁剪算法

    千次阅读 2017-07-15 00:05:24
    使用计算机处理图形信息时,计算机内部存储的图形往往比较大,而屏幕...最简单的裁剪方法是各种图形扫描转换为点之后,再判断点是否在窗口内。 点的裁剪        对于任意一点P(x,y),若满足下列两队不等式:
  • 方格是数学教学中经常运用...但在具体实施过程中,很多时候老师都只是它单独地作为一种计量面积的方法,对数方格这一环节的教学也只是轻描淡写、一带而过。其实数方格的作用远不止于此,笔者认为它可以统领整个小...
  • 牛逼!Java 从入门到精通,超全汇总版

    万次阅读 多人点赞 2021-05-06 19:40:33
    Java 核心技术卷一 有人 Java 核心技术卷一作为入门书籍推荐,其实我觉得并友好,虽然这也是一门基础书籍,但是对不同的人来说,这本书的接收程度不同,我推荐看完上面的 Head First Java 再看这本。...
  • 3.2 多边形网格(Polygon Mesh) 对于多边形网格来说相信读者并陌生,该方法广泛应用在计算机图形当中,简单来说通过定义各个多边形面的顶点以及顶点之间的连接关系就可以得到许许多多的三角形面或是四边形面,再...
  • 接上文 计算机图形学 学习笔记(七):二维图形变换:平移,比例,旋转,坐标变换通过三维图形变换,可由简单图形得到复杂图形,三维图形变化则分为三维几何变换和投影变换。6.1 三维图形几何变换三维物体的几何...
  • GuiPing图形化网络测试

    千次阅读 2016-05-15 13:18:25
    (1)进行连续ping时无法查看最大值、最小值、平均值参数; (2)具有图表功能,无法分析某段较长时间内的网络稳定性; 所以作者根据一些特定的需求,以易用性为主,设计了此免费的图形化软件,其特点如下: (1...
  • 计算机图形

    千次阅读 2018-10-16 19:06:24
    本文转载自:http://blog.csdn.net/hcbbt/article/details/42779341 计算机图形学 复习笔记 ...第一章 计算机图形学综述 研究内容 图形的概念:计算机图形学的研究对象 能在人的视觉系统中产生视觉印象...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 98,794
精华内容 39,517
关键字:

怎么把不规则图形等分