精华内容
下载资源
问答
  • *//** * @fileoverview GeoUtils类提供若干几何算法,用来帮助用户判断点与矩形、 * 圆形、多边形线、多边形面的关系,并提供计算折线长度和多边形的面积的公式。 * 主入口类是<a href="symbols/BMapLib.GeoUtils...
    /**
    * Created by LEGION on 2018/10/11.
    */
    /**
    * @fileoverview GeoUtils类提供若干几何算法,用来帮助用户判断点与矩形、
    * 圆形、多边形线、多边形面的关系,并提供计算折线长度和多边形的面积的公式。
    * 主入口类是<a href="symbols/BMapLib.GeoUtils.html">GeoUtils</a>,
    * 基于Baidu Map API 1.2。
    *
    * @author Baidu Map Api Group
    * @version 1.2
    */
    /**
    * @namespace BMap的所有library类均放在BMapLib命名空间下
    */
    var BMapLib = window.BMapLib = BMapLib || {};
    (function() {

    /**
    * 地球半径
    */
    var EARTHRADIUS = 6370996.81;

    /**
    * @exports GeoUtils as BMapLib.GeoUtils
    */
    var GeoUtils =
    /**
    * GeoUtils类,静态类,勿需实例化即可使用
    * @class GeoUtils类的<b>入口</b>。
    * 该类提供的都是静态方法,勿需实例化即可使用。
    */
    BMapLib.GeoUtils = function(){

    }

    /**
    * 判断点是否在矩形内
    * @param {Point} point 点对象
    * @param {Bounds} bounds 矩形边界对象
    * @returns {Boolean} 点在矩形内返回true,否则返回false
    */
    GeoUtils.isPointInRect = function(point, bounds){
    //检查类型是否正确
    if (!(point instanceof BMap.Point) ||
    !(bounds instanceof BMap.Bounds)) {
    return false;
    }
    var sw = bounds.getSouthWest(); //西南脚点
    var ne = bounds.getNorthEast(); //东北脚点
    return (point.lng >= sw.lng && point.lng <= ne.lng && point.lat >= sw.lat && point.lat <= ne.lat);
    }

    /**
    * 判断点是否在圆形内
    * @param {Point} point 点对象
    * @param {Circle} circle 圆形对象
    * @returns {Boolean} 点在圆形内返回true,否则返回false
    */
    GeoUtils.isPointInCircle = function(point, circle){

    //检查类型是否正确
    if (!(point instanceof BMap.Point) ||
    !(circle instanceof BMap.Circle)) {
    return false;
    }
    //point与圆心距离小于圆形半径,则点在圆内,否则在圆外
    var c = circle.getCenter();
    var r = circle.getRadius();

    var dis = GeoUtils.getDistance(point, c);
    if(dis <= r){
    return true;
    } else {
    return false;
    }
    }

    /**
    * 判断点是否在折线上
    * @param {Point} point 点对象
    * @param {Polyline} polyline 折线对象
    * @returns {Boolean} 点在折线上返回true,否则返回false
    */
    GeoUtils.isPointOnPolyline = function(point, polyline){
    //检查类型
    if(!(point instanceof BMap.Point) ||
    !(polyline instanceof BMap.Polyline)){
    return false;
    }

    //首先判断点是否在线的外包矩形内,如果在,则进一步判断,否则返回false
    var lineBounds = polyline.getBounds();
    if(!this.isPointInRect(point, lineBounds)){
    return false;
    }

    //判断点是否在线段上,设点为Q,线段为P1P2 ,
    //判断点Q在该线段上的依据是:( Q - P1 ) × ( P2 - P1 ) = 0,且 Q 在以 P1,P2为对角顶点的矩形内
    var pts = polyline.getPath();
    for(var i = 0; i < pts.length - 1; i++){
    var curPt = pts[i];
    var nextPt = pts[i + 1];
    //首先判断point是否在curPt和nextPt之间,即:此判断该点是否在该线段的外包矩形内
    if (point.lng >= Math.min(curPt.lng, nextPt.lng) && point.lng <= Math.max(curPt.lng, nextPt.lng) &&
    point.lat >= Math.min(curPt.lat, nextPt.lat) && point.lat <= Math.max(curPt.lat, nextPt.lat)){
    //判断点是否在直线上公式
    var precision = (curPt.lng - point.lng) * (nextPt.lat - point.lat) -
    (nextPt.lng - point.lng) * (curPt.lat - point.lat);
    if(precision < 2e-10 && precision > -2e-10){//实质判断是否接近0
    return true;
    }
    }
    }

    return false;
    }

    /**
    * 判断点是否多边形内
    * @param {Point} point 点对象
    * @param {Polyline} polygon 多边形对象
    * @returns {Boolean} 点在多边形内返回true,否则返回false
    */
    GeoUtils.isPointInPolygon = function(point, polygon){


    //检查类型
    if(!(point instanceof BMap.Point) ||
    !(polygon instanceof BMap.Polygon)){

    return false;
    }

    //首先判断点是否在多边形的外包矩形内,如果在,则进一步判断,否则返回false

    var polygonBounds = polygon.getBounds();
    if(!this.isPointInRect(point, polygonBounds)){
    return false;
    }
    var pts = polygon.getPath();//获取多边形点


    //下述代码来源:http://paulbourke.net/geometry/insidepoly/,进行了部分修改
    //基本思想是利用射线法,计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则
    //在多边形内。还会考虑一些特殊情况,如点在多边形顶点上,点在多边形边上等特殊情况。

    var N = pts.length;
    var boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
    var intersectCount = 0;//cross points count of x
    var precision = 2e-10; //浮点类型计算时候与0比较时候的容差
    var p1, p2;//neighbour bound vertices
    var p = point; //测试点


    p1 = pts[0];//left vertex
    for(var i = 1; i <= N; ++i){//check all rays
    if(p.equals(p1)){
    return boundOrVertex;//p is an vertex
    }

    p2 = pts[i % N];//right vertex
    if(p.lat < Math.min(p1.lat, p2.lat) || p.lat > Math.max(p1.lat, p2.lat)){//ray is outside of our interests
    p1 = p2;
    continue;//next ray left point
    }

    if(p.lat > Math.min(p1.lat, p2.lat) && p.lat < Math.max(p1.lat, p2.lat)){//ray is crossing over by the algorithm (common part of)
    if(p.lng <= Math.max(p1.lng, p2.lng)){//x is before of ray
    if(p1.lat == p2.lat && p.lng >= Math.min(p1.lng, p2.lng)){//overlies on a horizontal ray
    return boundOrVertex;
    }

    if(p1.lng == p2.lng){//ray is vertical
    if(p1.lng == p.lng){//overlies on a vertical ray
    return boundOrVertex;
    }else{//before ray
    ++intersectCount;
    }
    }else{//cross point on the left side
    var xinters = (p.lat - p1.lat) * (p2.lng - p1.lng) / (p2.lat - p1.lat) + p1.lng;//cross point of lng
    if(Math.abs(p.lng - xinters) < precision){//overlies on a ray
    return boundOrVertex;
    }

    if(p.lng < xinters){//before ray
    ++intersectCount;
    }
    }
    }
    }else{//special case when ray is crossing through the vertex
    if(p.lat == p2.lat && p.lng <= p2.lng){//p crossing over p2
    var p3 = pts[(i+1) % N]; //next vertex
    if(p.lat >= Math.min(p1.lat, p3.lat) && p.lat <= Math.max(p1.lat, p3.lat)){//p.lat lies between p1.lat & p3.lat
    ++intersectCount;
    }else{
    intersectCount += 2;
    }
    }
    }
    p1 = p2;//next ray left point
    }
    if(intersectCount % 2 == 0){//偶数在多边形外
    return false;
    } else { //奇数在多边形内
    return true;
    }
    }

    /**
    * 将度转化为弧度
    * @param {degree} Number 度
    * @returns {Number} 弧度
    */
    GeoUtils.degreeToRad = function(degree){
    return Math.PI * degree/180;
    }

    /**
    * 将弧度转化为度
    * @param {radian} Number 弧度
    * @returns {Number} 度
    */
    GeoUtils.radToDegree = function(rad){
    return (180 * rad) / Math.PI;
    }

    /**
    * 将v值限定在a,b之间,纬度使用
    */
    function _getRange(v, a, b){
    if(a != null){
    v = Math.max(v, a);
    }
    if(b != null){
    v = Math.min(v, b);
    }
    return v;
    }

    /**
    * 将v值限定在a,b之间,经度使用
    */
    function _getLoop(v, a, b){
    while( v > b){
    v -= b - a
    }
    while(v < a){
    v += b - a
    }
    return v;
    }

    /**
    * 计算两点之间的距离,两点坐标必须为经纬度
    * @param {point1} Point 点对象
    * @param {point2} Point 点对象
    * @returns {Number} 两点之间距离,单位为米
    */
    GeoUtils.getDistance = function(point1, point2){
    //判断类型
    if(!(point1 instanceof BMap.Point) ||
    !(point2 instanceof BMap.Point)){
    return 0;
    }

    point1.lng = _getLoop(point1.lng, -180, 180);
    point1.lat = _getRange(point1.lat, -74, 74);
    point2.lng = _getLoop(point2.lng, -180, 180);
    point2.lat = _getRange(point2.lat, -74, 74);

    var x1, x2, y1, y2;
    x1 = GeoUtils.degreeToRad(point1.lng);
    y1 = GeoUtils.degreeToRad(point1.lat);
    x2 = GeoUtils.degreeToRad(point2.lng);
    y2 = GeoUtils.degreeToRad(point2.lat);

    return EARTHRADIUS * Math.acos((Math.sin(y1) * Math.sin(y2) + Math.cos(y1) * Math.cos(y2) * Math.cos(x2 - x1)));
    }

    /**
    * 计算折线或者点数组的长度
    * @param {Polyline|Array<Point>} polyline 折线对象或者点数组
    * @returns {Number} 折线或点数组对应的长度
    */
    GeoUtils.getPolylineDistance = function(polyline){
    //检查类型
    if(polyline instanceof BMap.Polyline ||
    polyline instanceof Array){
    //将polyline统一为数组
    var pts;
    if(polyline instanceof BMap.Polyline){
    pts = polyline.getPath();
    } else {
    pts = polyline;
    }

    if(pts.length < 2){//小于2个点,返回0
    return 0;
    }

    //遍历所有线段将其相加,计算整条线段的长度
    var totalDis = 0;
    for(var i =0; i < pts.length - 1; i++){
    var curPt = pts[i];
    var nextPt = pts[i + 1]
    var dis = GeoUtils.getDistance(curPt, nextPt);
    totalDis += dis;
    }

    return totalDis;

    } else {
    return 0;
    }
    }

    /**
    * 计算多边形面或点数组构建图形的面积,注意:坐标类型只能是经纬度,且不适合计算自相交多边形的面积
    * @param {Polygon|Array<Point>} polygon 多边形面对象或者点数组
    * @returns {Number} 多边形面或点数组构成图形的面积
    */
    GeoUtils.getPolygonArea = function(polygon){
    //检查类型
    if(!(polygon instanceof BMap.Polygon) &&
    !(polygon instanceof Array)){
    return 0;
    }
    var pts;
    if(polygon instanceof BMap.Polygon){
    pts = polygon.getPath();
    }else{
    pts = polygon;
    }

    if(pts.length < 3){//小于3个顶点,不能构建面
    return 0;
    }

    var totalArea = 0;//初始化总面积
    var LowX = 0.0;
    var LowY = 0.0;
    var MiddleX = 0.0;
    var MiddleY = 0.0;
    var HighX = 0.0;
    var HighY = 0.0;
    var AM = 0.0;
    var BM = 0.0;
    var CM = 0.0;
    var AL = 0.0;
    var BL = 0.0;
    var CL = 0.0;
    var AH = 0.0;
    var BH = 0.0;
    var CH = 0.0;
    var CoefficientL = 0.0;
    var CoefficientH = 0.0;
    var ALtangent = 0.0;
    var BLtangent = 0.0;
    var CLtangent = 0.0;
    var AHtangent = 0.0;
    var BHtangent = 0.0;
    var CHtangent = 0.0;
    var ANormalLine = 0.0;
    var BNormalLine = 0.0;
    var CNormalLine = 0.0;
    var OrientationValue = 0.0;
    var AngleCos = 0.0;
    var Sum1 = 0.0;
    var Sum2 = 0.0;
    var Count2 = 0;
    var Count1 = 0;
    var Sum = 0.0;
    var Radius = EARTHRADIUS; //6378137.0,WGS84椭球半径
    var Count = pts.length;
    for (var i = 0; i < Count; i++) {
    if (i == 0) {
    LowX = pts[Count - 1].lng * Math.PI / 180;
    LowY = pts[Count - 1].lat * Math.PI / 180;
    MiddleX = pts[0].lng * Math.PI / 180;
    MiddleY = pts[0].lat * Math.PI / 180;
    HighX = pts[1].lng * Math.PI / 180;
    HighY = pts[1].lat * Math.PI / 180;
    }
    else if (i == Count - 1) {
    LowX = pts[Count - 2].lng * Math.PI / 180;
    LowY = pts[Count - 2].lat * Math.PI / 180;
    MiddleX = pts[Count - 1].lng * Math.PI / 180;
    MiddleY = pts[Count - 1].lat * Math.PI / 180;
    HighX = pts[0].lng * Math.PI / 180;
    HighY = pts[0].lat * Math.PI / 180;
    }
    else {
    LowX = pts[i - 1].lng * Math.PI / 180;
    LowY = pts[i - 1].lat * Math.PI / 180;
    MiddleX = pts[i].lng * Math.PI / 180;
    MiddleY = pts[i].lat * Math.PI / 180;
    HighX = pts[i + 1].lng * Math.PI / 180;
    HighY = pts[i + 1].lat * Math.PI / 180;
    }
    AM = Math.cos(MiddleY) * Math.cos(MiddleX);
    BM = Math.cos(MiddleY) * Math.sin(MiddleX);
    CM = Math.sin(MiddleY);
    AL = Math.cos(LowY) * Math.cos(LowX);
    BL = Math.cos(LowY) * Math.sin(LowX);
    CL = Math.sin(LowY);
    AH = Math.cos(HighY) * Math.cos(HighX);
    BH = Math.cos(HighY) * Math.sin(HighX);
    CH = Math.sin(HighY);
    CoefficientL = (AM * AM + BM * BM + CM * CM) / (AM * AL + BM * BL + CM * CL);
    CoefficientH = (AM * AM + BM * BM + CM * CM) / (AM * AH + BM * BH + CM * CH);
    ALtangent = CoefficientL * AL - AM;
    BLtangent = CoefficientL * BL - BM;
    CLtangent = CoefficientL * CL - CM;
    AHtangent = CoefficientH * AH - AM;
    BHtangent = CoefficientH * BH - BM;
    CHtangent = CoefficientH * CH - CM;
    AngleCos = (AHtangent * ALtangent + BHtangent * BLtangent + CHtangent * CLtangent) / (Math.sqrt(AHtangent * AHtangent + BHtangent * BHtangent + CHtangent * CHtangent) * Math.sqrt(ALtangent * ALtangent + BLtangent * BLtangent + CLtangent * CLtangent));
    AngleCos = Math.acos(AngleCos);
    ANormalLine = BHtangent * CLtangent - CHtangent * BLtangent;
    BNormalLine = 0 - (AHtangent * CLtangent - CHtangent * ALtangent);
    CNormalLine = AHtangent * BLtangent - BHtangent * ALtangent;
    if (AM != 0)
    OrientationValue = ANormalLine / AM;
    else if (BM != 0)
    OrientationValue = BNormalLine / BM;
    else
    OrientationValue = CNormalLine / CM;
    if (OrientationValue > 0) {
    Sum1 += AngleCos;
    Count1++;
    }
    else {
    Sum2 += AngleCos;
    Count2++;
    }
    }
    var tempSum1, tempSum2;
    tempSum1 = Sum1 + (2 * Math.PI * Count2 - Sum2);
    tempSum2 = (2 * Math.PI * Count1 - Sum1) + Sum2;
    if (Sum1 > Sum2) {
    if ((tempSum1 - (Count - 2) * Math.PI) < 1)
    Sum = tempSum1;
    else
    Sum = tempSum2;
    }
    else {
    if ((tempSum2 - (Count - 2) * Math.PI) < 1)
    Sum = tempSum2;
    else
    Sum = tempSum1;
    }
    totalArea = (Sum - (Count - 2) * Math.PI) * Radius * Radius;

    return totalArea; //返回总面积
    }

    })();//闭包结束
    //=======================================================
    <!DOCTYPE html>
    <html>
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=Ys4Yh5eKiRbTuTtavay0gVithqviqBf7"></script>
    <script type="text/javascript" src="a.js"></script>
    <head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script>
    //创建一个圆(坐标自己填)
    var circle = new BMap.Circle(new BMap.Point(112.595384,26.904631),1000,{fillColor:"blue", strokeWeight: 1 ,fillOpacity: 0.3, strokeOpacity: 0.3});
    //创建一个点(坐标自己填)
    var point = new BMap.Point(112.695384,26.904631); // 创建点坐标
    //判断点是否在圆形区域内
    if(BMapLib.GeoUtils.isPointInCircle(point,circle)){
    alert("该point 在 circle内");
    }else
    {
    alert("该point 不在 circle内");
    }
    </script>
    </head>
    <body>

    </body>
    </html>

    转载于:https://www.cnblogs.com/zhangzhiqin/p/9773980.html

    展开全文
  • 该机器人作为搭载传感器的罐底在线检测平台,需要遍历罐底所有区域,以检测罐底是否有安全隐患。 2.研究必要性 工业生产以及石油天然气的储存运输中,大型储罐作为最主要的储运工具得到了广泛的应用。金属油罐是...

    圆形罐底在线检测机器人路径规划和避障研究
    1.研究目标
    本项目拟开发一套基于多传感器在线检测数据的路径规划和避障算法,以支持检测储油罐内部罐底状态的移动机器人。该机器人作为搭载传感器的罐底在线检测平台,需要遍历罐底所有区域,以检测罐底是否有安全隐患。
    2.研究必要性
    在工业生产以及石油天然气的储存运输中,大型储罐作为最主要的储运工具得到了广泛的应用。金属油罐是采用钢板材料焊成的容器。对于超过10000m3的大容积油罐采用的是高强度的低合金钢。常见的金属油罐形状,一般是立式圆柱形、卧式圆柱形、球形等几种。本文研究涉及的检测机器人主要针对最常见的立式圆柱形油罐,罐底水平,圆形,有小部分面积覆盖管、阀、沉积油渣等障碍物。
    这些大型油罐随着时间的延长以及周围介质的环境变化,储罐材料不可避免的会出现老化、腐蚀等缺陷,造成储罐的安全度和抗突发性荷载能力的下降,加上罐内介质的不断倒运,内部压力或液位的不断变化,其罐底缺陷最容易引起介质泄露,导致严重的经济损失和环境生态污染,甚至会危及人身安全。因此定期对储罐罐底进行安全性检测具有重要的意义。
    目前国内有大量储罐罐底进入了检修期,急需进行健康状况监测。由于缺少自动化检测设备,储罐底板检测劳动强度大,检测时间长,而且储罐的密封空间不允许工作人员长时间工作,检测效率极低。另外,现代企业要求不停产在线检测以提高生产效率。所以,针对储罐罐底的表面情况和结构特以及储罐的环境特征,设计一种储罐罐底自动化在线检测机器人,对于提高检测效率,降低劳动强度具有广阔的前景和重要的意义。
    3. 圆形罐底在线检测运动机器人
    随着科学技术的飞速发展以及人类在运动机器人领域不断取得的进步,移动机器人在国防科学、宇宙探险、工业生产、家庭服务等方面的应用前景也愈发广泛。以智能小车为载体的运动机器人是一个集环境感知、规划决策、自动行驶等功能为一体的综合系统。它集中地运用了计算机、传感、信息、通信、人工智能以及自动控制等技术,是典型的高新技术综合体。在应用领域里,机器人会更加广泛地代替人类从事各种各样的生产作业,使人类能够从繁重的、单调的、有害的和危险的生产作业中解放出来。
    本文研究涉及的在线罐底检测机器人是一种运动机器人,机械结构类似于小车,携带传感器可以对车体正下方一定面积的罐底地面进行检测,已确定是否有裂缝的安全缺陷。小车在自身携带的超声传感器实时数据的支持下,沿预先设定的路径遍历整个圆形罐底,在遇到罐底管道、阀、沉淀堆积物等障碍时可以绕过,并继续沿原来的路径运动。
    4.路径规划和避障技术路线
    路径规划及避障算法的研究是罐底检测机器人研究中的重要部分,是两个相互关联的问题。本文算法的输入数据来自两个超声模块(分别安装在小车侧面和车头)和里程轮。
    (1)路径规划
    连接起点位置和终点位置的序列点或曲线称之为路径,构成路径的策略称之为路径规划。罐底在线检测机器人必须通过路径规划,使机器人尽可能遍历圆形罐底的所有面积,完成检测过程。
    路径规划所涉及到的是检测小车整体行驶路径优劣性的问题,其能力决定了机器人对圆形罐底所有面积进行检测的可能性,时间效率和能耗。在罐底检测中,对于检测小车的整个路径规划基于几何法。路径规划的目标是使小车运动轨迹绘制一个螺旋线圈,由于罐底几何参数R2已知,该路径可以预先计算得到,如图1:
    在这里插入图片描述
    图1 罐底路径规划得到螺旋线
    实现上述路径规划的基本思路是:使用小车侧面的超声测距模块采集小车侧面和灌壁的距离S,由于S=R2 ̶ R1。则可求得R1,根据R1值,判断当前检测面积的状态。理想状态下,当R1为0,算法结束。
    具体来说,当小车侧面的超声波测距模块感应到罐壁时,将罐壁的位置信息S反馈给单片机,通过S判断是否偏离预设路径,单片机控制左右两个车轮差速,使小车转动一定角度,然后直行。经过短暂时间的行驶,继续检测小车侧面与罐壁之间的距离,控制小车的行驶方向,从而完成整个路径。
    (2)避障
    障碍物是指妨碍机器人通行的静止状态和运动状态的物体,如罐底沉积堆积物等。避障是指移动机器人根据传感器感知到的障碍物的状态信息,包括障碍物的尺寸、形状和位置等,按照一定方法进行有效地避障,最后达到目标点。
    避障是针对小车遇到障碍物如何处理的问题,其能力决定了小车探测障碍、处理障碍信息以及避障运动的能力和合理性,直接影响到小车的路径规划效果。
    避障的实现使用小车车头的超声测距模块实现,车头的超声探头发现障碍,偏转角度前进,直至障碍被车身侧面探头捕获,然后开始避障控制。避障的控制可以使用Bug2算法。
    用Bug2算法时,机器人开始跟踪物体的轮廓,检测到当前的状态S(q1L点)和遇到障碍前(q1H点)相同,同时判断小车和qgoal目标之间暂时没有障碍时,就立即分离,沿预定路径运动(目标q2H点)。这个改进的Bug2算法,具有非常短的机器人行走总路径。
    在这里插入图片描述
    图2 Bug2避障算法示意图
    路径规划和避障两个问题相辅相成。路径规划多数情况下都涉及到避障,而避障的作用是给检测小车沿着规划好的路径行走时提供各种信息。两个问题的处理过程实质上构成一个自适应反馈控制系统。
    此时,算法的实现可以使用势场法(PFM)。把圆形罐底看作一个同心圆的超声势场,使用S作为对当前势场的一个感知。势场法不仅仅可以用来避障,还可以用来进行路径的规划。势场法把机器人处理为在势场下的一个点,随着势场而移动,目标表现为低谷值,即对机器人的吸引力,而障碍物扮演势场中的一个高峰,即斥力,所有这些矢量的力迭加于机器人身上,平滑地引导机器人走向目标,同时避免碰撞已知的障碍物。当机器人移动过程中检测新的障碍物,则需要更新势场并重新和预先规划的路径进行匹配。
    5.研究的工程实现
    (1)系统硬件平台的设计和实现。
    (2) 设计小车系统各模块的底层驱动程序及用户的调试接口,用51单片机控制各模块。主要包括:能够判断并控制小车离罐壁距离和离障碍物距离的超声测距模块以及控制小车前进方向的后轮差动驱动模块。
    (3) 研究路径规划和避障算法,在小车运动时能够在罐底按照预定轨迹行驶,与罐壁保持一定距离,当遇到障碍物时,能够自动绕过,绕过之后还需要保证小车回到原来的行驶轨迹之上。
    6.关键问题
    (1)控制问题,在整个运动过程中,在反馈信息(超声势场)不完整的情况下,使机器人能够按照所设定的路径,从初始点运动到设定的目标点。
    (2)实时数据采集问题,罐内不同介质条件下保证超声模块和里程数据的有效性。
    (3)实际运动轨迹的还原问题,罐内运动状态不可见,只有在罐外根据记录数据还原之前的运动轨迹,以保证之前的运动状态可观察。
    7. 项目特色
    (1)无人操作,完全的自主运动。
    (2)可避障,在预定计算的路径下具有一定的容错能力。
    (3)根据记录数据可离线复原实际运动轨迹。
    8.创新点
    (1)由小车侧壁超声探头的检测数据虚拟得到一个被动的超声势场,以此作为研究的主要背景,可以较方便的实现螺旋线的路径规划。事实上,超声势场的构造可以更加复杂和高效,通过主动发出超声信号在更大的空间里实现主动的信息标记。
    (2)Bug2算法对小规模障碍的绕行控制有较高的精度。
    参考文献
    [1] 赵星圆.大型储罐罐底缺陷检测分析与维修工艺研究[D].西安石油大学,2016.
    [2] 刘彦戎.基于STC89C51RC单片机的智能遥感避障小车的系统设计[D].电子设计工程,2017
    [3] 邓宝林,清洁机器人避障控制系统的研究[D].哈尔滨工程大学,2005
    [4] Li Caihong, Zhang Zi. Path planning of robot based on two point method [N]. Journal of Shandong University of Technology (NATURAL SCIENCE EDITION), 2005
    [5] 段群杰.水下机器人实时路径规划方法研究[D].哈尔滨工程大学,2007
    [6] 蔚伟.基于行为的移动机器人目标跟踪控制[D].东北电力大学,2007
    [7] 魏崇竹.移动机器人视觉信息提取与路径规划研究[D].大连海事大学,2007
    [8] 张广林,胡小梅,柴剑飞,赵磊,俞涛.路径规划算法及其应用综述[M].现代机械出版社,2011
    [9] Song Hui, Gao Xiaoming. Application Research on path planning of embedded intelligent robot [M]. machine tool and hydraulic, 2007
    [0] 常继科,赵建辉.基于环境模型的路径规划算法研究[N].科技创新导报,2008
    [1] 邬再新,李艳宏,刘涛.多移动机器人路径规划技术的研究现状与展望[M].机械出版社,2008
    [2] Fang Yaqun, the present situation and development of mobile robot path planning [M].2009
    [3] 罗骋,家用清洁机器人路径探测和路径规划的研究[D].武汉理工大学,2008
    [4] Liu Tianzhao, design of intelligent robot based on single chip microcomputer, [D]. technology information, 2012
    [5] 汪鑫,基于单片机的智能超声波避障小车系统设计[D].2016
    [6] 邓伟.服务机器人的同步定位与地图构建(SLAM)问题研究[D].新疆大学,2014
    [7] 吴国伟,姚金杰,齐睿.基于AVR的智能教学无人车控制系统设计.电子设计工程,2013
    [8] Gao Yu, Jin Chao, Cui Guang Zhao. An improved multi robot path planning adaptive artificial potential field method [N]. Journal of Zhengzhou University of Light Industry (NATURAL SCIENCE EDITION), 2013
    [9] 苏丽颖,余跃庆,王丽英.基于障碍物影响系数的机器人路径规划方法[M].北京工业大学学报,2008
    [20] 程岩.自主车辆的路径规划[D],河北工业大学.2012

    展开全文
  • 区域地址搜索是指某一地址或某些地址是否在指定的区域范围区域范围一般有圆形、矩形和多边形,利用百度地图API提供的数据接口,可以提取中国,各省、市、区,甚至是小区或商圈的边界经纬度坐标(多边形)。这样...
    copyright.gif(2017-07-23 银河统计)

    区域地址搜索是指某一地址或某些地址是否在指定的区域范围内。区域范围一般有圆形、矩形和多边形,利用百度地图API提供的数据接口,可以提取中国,各省、市、区,甚至是小区或商圈的边界经纬度坐标(多边形)。这样,就可以根据判断任意经纬度所在区域,在地址分类以及和地址相关指标的分类和插值算法中有广泛用途。

    本文判别计算需要引入百度地图API类库:

    <script type="text/javascript" src="http://api.map.baidu.com/library/GeoUtils/1.2/src/GeoUtils_min.js"></script>

    类BMapLib.GeoUtils提供的都是静态方法,勿需实例化即可使用。方法列表如下:

    方法返回值描述
    BMapLib.GeoUtils.degreeToRad(Number)Number将度转化为弧度
    BMapLib.GeoUtils.radToDegree(Number)Number将弧度转化为度
    BMapLib.GeoUtils.getDistance(Point, Point)Number计算经纬度之间的距离
    BMapLib.GeoUtils.getPolygonArea(polygon)Number计算多边形面或点数组构建图形的面积
    BMapLib.GeoUtils.getPolylineDistance(polyline)Number计算折线或者点数组的长度
    BMapLib.GeoUtils.isPointInCircle(point, circle)Boolean判断点是否在圆形内
    BMapLib.GeoUtils.isPointInPolygon(point, polygon)Boolean判断点是否多边形内
    BMapLib.GeoUtils.isPointInRect(point, bounds)Boolean判断点是否在矩形内
    BMapLib.GeoUtils.isPointOnPolyline(point, polyline)Boolean判断点是否在折线上

    一、点与区域之间的关系

    这里,“点”指某一地址或经纬度坐标,区域指园形、矩形、多边形或当前地图可视区域。点与区域之间的关系是指点在区域内或区域外。

    1、判断一些点是否在给定圆形区域内

    待判别经纬度坐标
    [[116.307852,40.057031],[116.313082,40.047674],[116.328749,40.026922],[116.347571,39.988698],[116.345867,39.998333],[116.403472,39.999411],[116.307901,40.05901]]

    圆心经度  圆心纬度  圆半径 (米) 判别计算

    2、判断一些点是否在给定矩形区域内

    待判别经纬度坐标
    [[116.407852,39.857031],[116.413082,39.947674],[116.398749,39.926922],[116.407571,39.928698],[116.405867,39.898333],[116.403472,39.889411],[116.407901,39.95901],[116.404,39.915],[116.398,39.915]]

    矩形左下角经度  矩形左下角纬度 
    矩形右上角经度  矩形右上角纬度 

    判别计算

    3、判断一些点是否在给定多边形区域内

    待判别经纬度坐标
    [[116.407852,39.857031],[116.413082,39.947674],[116.398749,39.926922],[116.407571,39.928698],[116.405867,39.898333],[116.403472,39.889411],[116.407901,39.95901],[116.404,39.915],[116.398,39.915],[116.400,39.914]]
    多边形边界坐标
    [[116.395,39.910],[116.394,39.914],[116.403,39.920],[116.402,39.914],[116.410,39.913]]

    判别计算

    二、区域边界经纬度坐标提取

    一般情况下行政区域边界为多边形,判断一些点是否在给定多边形区域内这种技巧应用比较广泛。

    1、按省(或直辖市)、市、区(或县)和商圈名称提取边界经纬度

    商圈是指以店铺座落点为核心向外延伸一定距离而形成的一个方圆范围,是店铺吸引顾客的地理区域。百度地图只提供了部分发达城市的商圈区域边界经纬度。

    输入省(直辖市)、市、区(县)和商圈名称

    经纬度坐标列表

    经纬度坐标数组

    注:可在省(直辖市)、市、区(县)和商圈名称列表中选择区域(可以只选省份名称或城市名称),点击“获取轮廓线”按钮获得区域边界经纬度

    代码样例

    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>获取地区轮廓线</title>
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=1.3"></script>
    <style type="text/css">
        body{font-size:13px;margin:10px}
        #container{width:800px;height:500px;border:1px solid gray}
    </style>
    </head>
    <body>
    <div id="container"></div>
    <br />
    输入省、直辖市或县名称:<input type="text" id="districtName" style="width:80px" value="重庆市">
    <input type="button" onclick="getBoundary()" value="获取轮廓线">
    
    <script type="text/javascript">
    var map = new BMap.Map("container");
    map.centerAndZoom(new BMap.Point(116.403765, 39.914850), 5);
    map.addControl(new BMap.NavigationControl({type: BMAP_NAVIGATION_CONTROL_SMALL}));
    map.enableScrollWheelZoom();
    
    function getBoundary(){       
    var bdary = new BMap.Boundary();
    var name = document.getElementById("districtName").value;
    bdary.get(name, function(rs){       //获取行政区域
        map.clearOverlays();        //清除地图覆盖物       
        var count = rs.boundaries.length; //行政区域的点有多少个
        for(var i = 0; i < count; i++){
            var ply = new BMap.Polygon(rs.boundaries[i], {strokeWeight: 2, strokeColor: "#ff0000"}); //建立多边形覆盖物
            map.addOverlay(ply);  //添加覆盖物
            map.setViewport(ply.getPath());    //调整视野         
            }                
        });   
    }
    
    </script>
    </body>
    </html>

    2、提取小区边界经纬度

    百度和高德等地图API提供的区域边界经纬度坐标一般只到区(县)一级,农村的乡、村和城市的小区区域边界经纬度坐标则需要项目开发者自己根据项目需求自己标注。另外还有城市绿地、农村耕地、自然湖泊等区域边界经纬度坐标等也需要自行标注。标注方法及工具参见后续文章。

    在住宅房地产价格批量评估技术中,由于同一小区同类房地产价格相近,通常需要根据小区内出售的房地产平均价格做为小区的基准价格。因此,首先根据自然小区或价格类似的区域把一座城市划分为几百或几千个基准价格分区(大部分是自然小区、小部分为人工合并的小区),然后以小区房地产平均价格小区基准价格(没有销售数据或销售量很少的小区需要评估师估价或用近邻小区自动估价)。这样,

    以哈尔滨市为例,为了进行住宅房地产价格批量评估,首先划分出2000多个基准价格分区(标注出小区边界经纬度坐标,本文只列出约100个小区),这样对任一地址(哈尔滨市道里区通达街单元室)的房地产,估价步骤如下:

    I、将地址转换为经纬度;
    II、运用点与区域之间的关系判断改地址所属基准价格分区,从而得到基准价;
    III、根据楼层、朝向和面积等个别特性调整基准价,最后得到估价。

    在批量估价过程中,地址批量解析、小区边界经纬度坐标标注、小区销售价格采集等工作在规模较大城市将耗费大量人力、物力和财力。

    哈尔滨市&nbsp道里区道外区南岗区香坊区松北区呼兰区平房区&nbsp小区 

    经纬度坐标列表

    经纬度坐标数组

    本文提供的各种区域经纬度边界工具仅用于个人学习或教学研究用途,不支持大批量商业用途的区域边界经纬度坐标提取(由于百度地图key的限制)。

    转载于:https://www.cnblogs.com/cloudtj/p/7223712.html

    展开全文
  • 今天分享的是判断一个目标点是否在扇形的计算,用到的是比较简单的运算,高效率的算法我很尽快更新。 数学知识  在这里需要大家回顾一下初中以及高中的代数和平面几何的知识,想必大部分的朋友在这方...

    距离上次发布已经有了很长一段时间,期间由于各种原因没有更新这方面的技术分享,在这里深表遗憾。在MMO或其他的游戏中,会有针对各种形状的计算,通常在攻击区域里不会很复杂,常见的为矩形、圆形、扇形。今天分享的是判断一个目标点是否在扇形内的计算,用到的是比较简单的运算,高效率的算法我很尽快更新。

    数学知识

       在这里需要大家回顾一下初中以及高中的代数和平面几何的知识,想必大部分的朋友在这方面和我一样几乎忘记了或是对这些数学知识感觉有些头痛。不过大家没有必要担心,在实际运用中,我们都不会涉及太复杂的计算,因为我们不需要追求的十分精确。

      但是在以下内容中,大家需要知道一些基本的定理和公式:勾股定理、余弦定理。

      需要了解弧度和角度的一些转换:角度 = 弧度 * 180.0 / ∏

      一些数学函数:atan2、acos等。

      中心线:以中心线顺、逆时针展开半角,形成一个完整的目标扇形区域。

      极坐标概念:

      如上图坐标点A的平面坐标为(7.96, 5.43),对应的极坐标为(ρ, θ)

      相对坐标的概念:

      在扇形的计算中,我们的X轴与Y轴的方向与原点的的X轴和Y轴平行,在上图中,如果以A点作为中心点,那么B的相对坐标为(xb - xa, yb - ya)。

     扇形与点的关系

      示例图1:

      必要的数据: 原点A(攻击者坐标)、方向点B(direction)、目标点C(point)、扇形角度(β)、扇形的半径(r)。

      扇形的有效区域:

      如上图中的扇形的角度为180°,其有效面积为:以X轴为中心分布的可攻击区域1(area1紫色区域)和可攻击区域2(area2绿色区域)。

      如果目标点的极坐标为(ρ,Θ),那么上述的目标点判断为:目标点到原点A的距离小于扇形的半径(ρ <= r)、在区域1(0 <= Θ <= α + β / 2)或区域2((a - β / 2) + 360 <= Θ <= 360)。

      因为我们的极坐标的范围为(0-360),所以如果算出来的扇形最小的角度为负,需要转换为正来比较。

      从上述的判断中,并没有将所有的情况考虑到,如果需要的扇形角度超过180或者方向点落在不同的象限内,计算的方式是不同的,接下来再看一张示意图。

      示例图2:

      如上图所示,这样的面积计算就不能使用第一种方式,方向的极坐标的角度为315°,而扇形的角度的不过270°,那么α、β、γ到底变成了怎样的关系,我们求出了方向的极坐标是否能把这样两个面积的角度分别计算出来?

      区域1(0 <= Θ <= α + β / 2),如果是上图的数据则为0 <= Θ <= 315 + 270 / 2,范围就是[0,450],如果用词判断则象限2中的空白部分的本不符合的点就符合条件了,其实我们可以看出区域1的实际范围为[0,90],同理区域2的范围为[180,360]。而超过了360°的角度只要减去360,这里的450转换为正常角度则为90刚刚是我们的正确角度。而第一种方式中的区域二的区域为[a - β / 2,360],在上图中刚刚为[180,360]是符合的。

      如何判断一个扇形是否跨域了X轴正方向?

      因为我们的扇形是以中心线分成两个部分,那么只需要判断这两个部分是否超过了就可以,当前如果中心线在X轴正方向时绝对是跨域了两个方向。

      三种跨域的方式:示例图1中(a - β / 2)的值小于零、示例图2中的(α + β / 2)大于360、方向点在X轴正方向上(极坐标的角度Θ为0或绝对坐标X大于0和Y等于0)。

      同时两个扇形的角度需要转换:小于0的角度需要转换为正(示例图1中a - β / 2,加上360)、大于360的角度需要转换为360以内的角度(示例图中的α + β / 2,减去360)。

      那么两个区域就为[0, a + β / 2]、[a - β / 2, 360],需要注意这里的角度都需要进行上述的转换。

      示例图3:

      如果扇形的范围没有跨域X轴正方向,那么角度的范围是[a - β / 2, a + β / 2]。

    代码实现

      我们知道了点和面的关系后,就能够对目标点进行判定了,编码实现才有了依据。(上面三种情况是否会有遗漏,暂时没有考虑过,欢迎大家指正)

      基础结构定义:

    struct point_struct {
      double x;
      double y;
      point_struct() : x{.0}, y{.0} {}
    };
    using point_t = point_struct;

      相对坐标转换(没有方向):

    /**
     * 没有方向的相对坐标转换,x、y轴的方向与原点相同
     * @param origin 坐标系原点
     * @param point 需要转换的点
     */
    /**
     *    Y
     *    |
     *    |      CY
     *    |      |
     *    |      |    .point
     *    |      |
     *    |      |
     *    |  origin----------------- CX
     *    |
     *    |
     *    O--------------------------------------------------- X
     *
     */
    point_t absolute_to_relative(const point_t &origin, const point_t &point) {
      point_t result;
      result.x = point.x - origin.x;
      result.y = point.y - origin.y;
      return result;
    }

      极坐标转换:

    /**
     * 简单极坐标转换(转换后的x为斜边,y为角度),
     * 减少数学函数调用(可以忽略,因为通常情况下这几种情况命中概率极低)
     * @param point 需要转换的点
     */
    point_t to_spolar_coordinate(const point_t &point) {
      point_t result;
      result.x = 0;
      result.y = -1;
      if (0 == point.x == point.y) {
        result.y = 0;
        return result;
      }
      if (0 == point.y) {
        result.x = abs(point.x);
        result.y = point.x > 0 ? 0 : 180;
        return result; 
      }
      if (0 == point.x) {
        result.x = abs(point.y);
        result.y = point.y > 0 ? 90 : 270;
        return result;
      }
      if (abs(point.x) == abs(point.y)) {
        result.x = 1.41421 * abs(point.x);
        if (point.x > 0 && point.y > 0) {
          result.y = 45;
        } else if (point.x < 0 && point.y > 0) {
          result.y = 135;
        } else if (point.x < 0 && point.y < 0) {
          result.y = 225;
        } else if (point.x > 0 && point.y < 0) {
          result.y = 315;
        }
      }
      return result;
    }
    /**
     * 转换为极坐标(转换后的x为斜边,y为角度)
     * @param point 需要转换的点
     */
    inline point_t to_polar_coordinate(const point_t &point) {
      point_t result;
      result.x = sqrt(point.x * point.x + point.y * point.y);
      result.y = (180.0 / PI) * atan2(point.y , point.x); //弧度转角度
      result.y = result.y < .0 ? result.y + 360.0 : result.y;
      return result;
    }

      判断是否在扇形内:

    /**
     * 判断一个点是否在扇形内(相对中心点)
     * @param center 扇形的中心点
     * @param direction 中心线的方向坐标
     * @param r 半径
     * @param angle 角度(0 < angle < 360)
     * @param point 需要检查的点
     */
    bool in_circular_sector(const point_t &center, 
                            const point_t &direction, 
                            double r, 
                            int angle,
                            const point_t &point) {
      //实际使用中,我们会把方向点的极坐标放到外部进行计算
      point_t d_rpoint = absolute_to_relative(center, direction); //方向相对坐标
      point_t d_pc_point = to_spolar_coordinate(d_rpoint); //方向极坐标
      if (-1 == d_pc_point.y) { //简单的如果转换不出,则需要调用角度函数计算
        d_pc_point = to_polar_coordinate(d_rpoint);
      }
      point_t rpoint = absolute_to_relative(center, point); //目标相对坐标
      point_t pc_point = to_polar_coordinate(rpoint); //目标极坐标
      if (pc_point.x > r) return false;
      bool result = false;
      auto half_angle = angle / 2;
      auto angle_counter = d_pc_point.y - half_angle; //中心线顺时针方向的范围
      auto angle_clockwise = d_pc_point.y + half_angle; //中心线逆时针方向的范围
      /*
      std::cout << "angle_counter: " << angle_counter << " angle_clockwise: " 
                << angle_clockwise << " d_pc_point.y" << d_pc_point.y << std::endl;
      */
      if (0 == d_pc_point.y || angle_counter < 0 || angle_clockwise > 360) {
        angle_counter = angle_counter < 0 ? angle_counter + 360 : angle_counter;
        angle_clockwise = angle_clockwise > 360 ? angle_counter - 360 : angle_counter;
        if (pc_point.y >= 0 && pc_point.y <= angle_counter) {
          result = true;
        } else if (pc_point.y >= angle_clockwise && pc_point.y <= 360) {
          result = true;
        }
      } else {
        result = angle_counter <= pc_point.y && angle_clockwise >= pc_point.y;
      }
      return result;
    }

      实际使用的优化:

      可以先求出圆范围内的所有玩家对象,这样可以减少atan2调用,其次方向点的极坐标放到循环之外,减少循环次数。

    PF人员招募

    开篇语
      我们没有大神,只有解决问题的人。
      我们没有强悍的技术,只有一颗向往简单的心。
      我们没有惊人的理论,只有一堆不可思议的妄想。
      我们不需要复杂,只需要够简洁。
      我们不需要固定的思维,只需要你能想得到。

    PF托管地址

      https://github.com/viticm/plainframework1

    PF安装教程

      http://www.cnblogs.com/lianyue/p/3974342.html

    PF交流QQ群

      348477824(同时欢迎技术人员加入进行交流)

    转载于:https://www.cnblogs.com/lianyue/p/6217824.html

    展开全文
  • 1、解决了:处理大量出现的卡顿设置未知的异常(经测试3万小区扇区制作图层 60秒完成) 2、微站图层全向天线生产圆形图层(方位角填写360) 3、如选择文件提示出现BUG,请将文件另存为97-2003.xls(兼容性问题:...
  • delphi 开发经验技巧宝典源码

    热门讨论 2010-08-12 16:47:23
    0160 判断某一字符是否在字符串中 105 0161 判断字符串是由数字、大写字母或小写字母组成 105 0162 判断字符串中的某一字符是否大写 106 0163 判断字符串中是否有小写字母 107 0164 判断字符串中是否有指定...
  • 实例134 判断某一字符是否在字符串中 5.3 字符串处理 实例135 在字符串中用一子串替换另一子串 实例136 如何将一行字符串分成一列字符 实例137 根据标点符号分行 实例138 去掉字符串中所有空格 实例139 去除...
  • 实例194 按树结构输出区域信息 实例195 分解路径和名称 实例196 数值与字符串类型的转换 实例197 使用递归过程实现阶乘运算 实例198 随机获取姓名 实例199 判断指定月份属于哪个季节 实例200 判断闰年 实例...
  • 实例194 按树结构输出区域信息 实例195 分解路径和名称 实例196 数值与字符串类型的转换 实例197 使用递归过程实现阶乘运算 实例198 随机获取姓名 实例199 判断指定月份属于哪个季节 实例200 判断闰年 实例...
  • 实例068 高级算法应用——判断IP地址是否合法 105 实例069 高级算法应用——实现裴波纳契数列求和 106 实例070 高级算法应用——求水仙花数的算法 107 实例071 如何将字节单位B转换成GB、MB 和KB 108 实例072 身份证...
  • 实例068 高级算法应用——判断IP地址是否合法 105 实例069 高级算法应用——实现裴波纳契数列求和 106 实例070 高级算法应用——求水仙花数的算法 107 实例071 如何将字节单位B转换成GB、MB 和KB 108 实例072 身份证...
  • 实例068 高级算法应用——判断IP地址是否合法 105 实例069 高级算法应用——实现裴波纳契数列求和 106 实例070 高级算法应用——求水仙花数的算法 107 实例071 如何将字节单位B转换成GB、MB 和KB 108 实例072 身份证...
  • pro文件中可以自由开启是否加载地图。 视频播放可选2种内核自由切换,vlc+ffmpeg,均可pro中设置。 可设置1+4+9+16画面轮询,可设置轮询间隔以及轮询码流类型等,直接主界面底部工具栏右侧单击启动轮询按钮...
  • 然后,自己的Application中调用Utils.init(this);进行初始化 添加混淆: -keep class com.easytools.tools.DialogUtils {*;} -dontwarn com.easytools.tools.** -keep class com.easytools.constant.**{*;} 所需...
  • 范例10-6-1判断某点是否在凸边形的轮廓 356 范例10-7-1计算轮廓的面积与周长 357 范例10-8-1使用匹配模板找出某物 359 范例10-8-2使用非匹配模板找出某物 363 范例10-8-3 修正使用匹配与非匹配模板找出某物 364 ...
  • 实例082 利用IFS算法绘制自然景物 3.2 图像预览 实例083 图片自动预览程序 实例084 图片批量浏览 实例085 浏览大幅BMP图片 实例086 放大和缩小图片 实例087 可随鼠标移动的图形 实例088 随图像大小变换的...
  • 实例082 利用IFS算法绘制自然景物 3.2 图像预览 实例083 图片自动预览程序 实例084 图片批量浏览 实例085 浏览大幅BMP图片 实例086 放大和缩小图片 实例087 可随鼠标移动的图形 实例088 随图像大小变换的...
  • 实例082 利用IFS算法绘制自然景物 3.2 图像预览 实例083 图片自动预览程序 实例084 图片批量浏览 实例085 浏览大幅BMP图片 实例086 放大和缩小图片 实例087 可随鼠标移动的图形 实例088 随图像大小变换的...
  • 实例082 利用IFS算法绘制自然景物 3.2 图像预览 实例083 图片自动预览程序 实例084 图片批量浏览 实例085 浏览大幅BMP图片 实例086 放大和缩小图片 实例087 可随鼠标移动的图形 实例088 随图像大小变换的...
  • 实例082 利用IFS算法绘制自然景物 3.2 图像预览 实例083 图片自动预览程序 实例084 图片批量浏览 实例085 浏览大幅BMP图片 实例086 放大和缩小图片 实例087 可随鼠标移动的图形 实例088 随图像大小变换的...
  • 实例082 利用IFS算法绘制自然景物 3.2 图像预览 实例083 图片自动预览程序 实例084 图片批量浏览 实例085 浏览大幅BMP图片 实例086 放大和缩小图片 实例087 可随鼠标移动的图形 实例088 随图像大小变换的...
  • 实例082 利用IFS算法绘制自然景物 3.2 图像预览 实例083 图片自动预览程序 实例084 图片批量浏览 实例085 浏览大幅BMP图片 实例086 放大和缩小图片 实例087 可随鼠标移动的图形 实例088 随图像大小变换的...
  • 实例082 利用IFS算法绘制自然景物 3.2 图像预览 实例083 图片自动预览程序 实例084 图片批量浏览 实例085 浏览大幅BMP图片 实例086 放大和缩小图片 实例087 可随鼠标移动的图形 实例088 随图像大小变换的...
  •  cc实例082 利用IFS算法绘制自然景物   3.2 图像预览   cc实例083 图片自动预览程序   cc实例084 图片批量浏览   cc实例085 浏览大幅BMP图片   cc实例086 放大和缩小图片   cc实例087 可随鼠标...
  •  cc实例082 利用IFS算法绘制自然景物   3.2 图像预览   cc实例083 图片自动预览程序   cc实例084 图片批量浏览   cc实例085 浏览大幅BMP图片   cc实例086 放大和缩小图片   cc实例087 可随鼠标...
  • C#编程经验技巧宝典

    热门讨论 2008-06-01 08:59:33
    的值 52 <br>0069 求最大公约数 52 <br>0070 求最小公倍数 53 <br>0071 判断素数的算法 53 <br>0072 如何判断一个数是否是完数 54 <br>0073 歌德巴赫猜想的算法 54 <br>0074 八皇后...
  • cc实例082 利用IFS算法绘制自然景物 3.2 图像预览 cc实例083 图片自动预览程序 cc实例084 图片批量浏览 cc实例085 浏览大幅BMP图片 cc实例086 放大和缩小图片 cc实例087 可随鼠标移动的图形 cc实例088...
  • cc实例082 利用IFS算法绘制自然景物 3.2 图像预览 cc实例083 图片自动预览程序 cc实例084 图片批量浏览 cc实例085 浏览大幅BMP图片 cc实例086 放大和缩小图片 cc实例087 可随鼠标移动的图形 cc实例088...

空空如也

空空如也

1 2
收藏数 29
精华内容 11
关键字:

是否在圆形区域内算法