GIS算法总结

    xiaoxiao2022-07-06  200

    #include <iostream> #include <graphics.h> #include <math.h> #include <conio.h> using namespace std; // 矩形结构体 typedef struct{ int xmin,xmax,ymin,ymax; }MyRectangle; // 计算a、b的最大公约数 int gcd(int a,int b); // 插入排序 void si_sort(int arr[], int len); // 选择排序 void select_sort(int arr[], int len); // 冒泡排序 void bubble_sort(int arr[], int len); // 快速排序 void fast_sort(int arr[], int start, int end); // 交换 void swap(int *a, int *b); // 绘制DDA直线 void drawDDA(int x1,int y1,int x2,int y2); // Bresenham画线算法 void bresenHamLine(int x1,int y1,int x2,int y2); // 中点画线法 void midPointLine(int x1,int y1,int x2,int y2); // 八对称性 void draw_circle_8(int xc, int yc, int x, int y); // Bresenham画圆算法 void bresenHamCircle(int xc, int yc, int r,int fill); // 中点画圆算法 void midPointCircle(int xc, int yc, int r); // 正负法绘制圆 void posnegCircle(int xc,int yc,int r); // 快速画圆法 void fastCircle(int xc,int yc,int r); // 矩形填充算法 void fiilRectangle(MyRectangle *rect); // 射线法判断点是否在多边形内 bool isPointInPolygon(POINT pts[],POINT pt,int size); // 判断点是否在线上 bool isDotInLineSegment(POINT point,POINT p1,POINT p2); // 判断多边形走向 bool isClockWise(POINT poly[],int size); #include "algorithm.h" // 计算a, b 最大的公约数 int gcd(int a, int b){ if(a < b){ int temp = a; a = b; b = temp; } while(a % b){ int r = a % b; a = b; b = r; } return b; } // 直接插入排序 void si_sort(int arr[], int len){ for (int i = 1; i < len; i++)// 循环从第二个数组元素开始 { int temp = arr[i];//temp标记为未排序的第一个元素 while (i >= 0 && arr[i - 1] > temp) //将temp与已排序元素从大到小比较,寻找temp应插入的元素 { arr[i] = arr[i - 1]; i--; } arr[i] = temp; } } // 选择排序:相邻两个元素进行比较,把大的元素的下标记录下来,一轮完整的比较之后,若最大值的下标不是len-i,则两个元素交换位置 void select_sort(int arr[],int len) { for(int i=0; i<len; i++) // 总共要找len-1次最大值,每次找最大值的区间 [0,len-i] { int index_nmax = 0; for(int j=1; j<len-i; j++) // 因为假设了0下标就是最大值,所以循环可以从1开始 { if(arr[j] > arr[index_nmax]) { index_nmax = j; } } if(index_nmax != len-i-1) // 避免无意义的位置交换 { int tmp = arr[index_nmax]; arr[index_nmax] = arr[len-i-1]; arr[len-i-1] = tmp; } } } // 冒泡排序 void bubble_sort(int arr[], int len){ for (int i = 0; i < len-1; i++) { for (int j = 0; j < len - i - 1; j++) { if (arr[j] > arr[j + 1]) { int max = arr[j]; arr[j] = arr[j + 1]; arr[j+1] = max; } } } } // 交换 void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } // 快速排序 void fast_sort(int arr[], int start, int end){ int arrBase, arrMiddle; int tempStart = start, tempEnd = end; //对于这种递归的函数,内部必须要有一个函数返回的条件 if(tempStart >= tempEnd) return; //拷贝一个基准值作为后面比较的参数 arrBase = arr[start]; while(start < end) { while(start < end && arr[end] > arrBase) end--; if(start < end) { swap(&arr[start], &arr[end]); start++; } while(start < end && arr[start] < arrBase) start++; if(start < end) { swap(&arr[start], &arr[end]); end--; } } arr[start] = arrBase; arrMiddle = start; //分治方法进行递归 fast_sort(arr,tempStart,arrMiddle-1); fast_sort(arr,arrMiddle+1,tempEnd); } // 使用数值微分法绘制直线 void drawDDA(int x1, int y1, int x2, int y2) { // 初始化绘图窗口 initgraph(640,480); float increx,increy,x,y; int steps,i; if(abs(x2-x1)>abs(y2-y1)) steps = abs(x2-x1); else steps = abs(y2-y1); increx = (float)(x2-x1)/steps; increy = (float)(y2-y1)/steps; // 初始值 x = x1; y = y1; for(i = 1;i<=steps;i++){ putpixel(x,y,WHITE); x+=increx; y+=increy; } } // 使用bresenham算法绘制直线 void bresenHamLine(int x1,int y1, int x2, int y2){ // 初始化绘图窗口 initgraph(640,480); int dx = abs(x2 - x1), dy = abs(y2 - y1), yy = 0; if (dx < dy) { yy = 1; swap(&x1, &y1); swap(&x2, &y2); swap(&dx, &dy); } int ix = (x2 - x1) > 0 ? 1 : -1, iy = (y2 - y1) > 0 ? 1 : -1, cx = x1, cy = y1, n2dy = dy * 2, n2dydx = (dy - dx) * 2, d = dy * 2 - dx; if (yy) { // 如果直线与 x 轴的夹角大于 45 度 while (cx != x2) { if (d < 0) { d += n2dy; } else { cy += iy; d += n2dydx; } putpixel(cy, cx, WHITE); cx += ix; } } else { // 如果直线与 x 轴的夹角小于 45 度 while (cx != x2) { if (d < 0) { d += n2dy; } else { cy += iy; d += n2dydx; } putpixel(cx, cy, WHITE); cx += ix; } } } // 使用中点画线法绘制直线 void midPointLine(int x1, int y1,int x2,int y2){ // 初始化绘图窗口 initgraph(640,480); int x = x1, y = y1; int a = y1 - y2; int b = x2 - x1; int cx = (b >= 0 ? 1 : (b = -b, -1)); int cy = (a <= 0 ? 1 : (a = -a, -1)); int d, d1, d2; if (-a <= b) // 斜率绝对值 <= 1 { d = a + a + b; d1 = a + a; d2 = a + a + b + b; while (x != x2) { if (d < 0) { y += cy; d += d2; } else { d += d1; } x += cx; putpixel(x, y,WHITE); } } else // 斜率绝对值 > 1 { d = a + b + b; d1 = b + b; d2 = a + a + b + b; while (x != x2){ if (d < 0) { d += d1; } else { x += cx; d += d2; } y += cy; putpixel(x, y,WHITE); } } } // 八对称性 void draw_circle_8(int xc, int yc, int x, int y){ putpixel(xc + x, yc + y, WHITE); putpixel(xc - x, yc + y, WHITE); putpixel(xc + x, yc - y, WHITE); putpixel(xc - x, yc - y, WHITE); putpixel(xc + y, yc + x, WHITE); putpixel(xc - y, yc + x, WHITE); putpixel(xc + y, yc - x, WHITE); putpixel(xc - y, yc - x, WHITE); } // 使用bresenham算法绘制圆 void bresenHamCircle(int xc, int yc, int r,int fill){ // 初始化绘图窗口 initgraph(640,480); if (xc + r < 0 || xc - r >= 640 || yc + r < 0 || yc - r >= 480) return; int x = 0, y = r, yi, d; d = 3 - 2 * r; if (fill) { // 如果填充(画实心圆) while (x <= y) { for (yi = x; yi <= y; yi ++) draw_circle_8(xc, yc, x, yi); if (d < 0) { d = d + 4 * x + 6; } else { d = d + 4 * (x - y) + 10; y --; } x++; } } else { // 如果不填充(画空心圆) while (x <= y) { draw_circle_8( xc, yc, x, y); if (d < 0) { d = d + 4 * x + 6; } else { d = d + 4 * (x - y) + 10; y --; } x ++; } } } // 使用中点画圆法绘制圆 void midPointCircle(int xc,int yc,int r){ // 初始化绘图窗口 initgraph(640,480); if (xc + r < 0 || xc - r >= 640 || yc + r < 0 || yc - r >= 480) return; int x, y; double d; x = 0; y = r; d = 1.25 - r; draw_circle_8(xc , yc , x , y); while(x < y) { if(d < 0) { d = d + 2 * x + 3; } else { d = d + 2 * ( x - y ) + 5; y--; } x++; draw_circle_8(xc , yc , x , y); } } // 使用正负法绘制圆 void posnegCircle(int xc,int yc,int r){ // 初始化绘图窗口 initgraph(640,480); int x, y, f; x = 0; y = r; f = 0; while(x <= y) { draw_circle_8(xc, yc, x, y); if(f <= 0) { f = f + 2 * x + 1; x++; } else { f = f - 2 * y + 1; y--; } } } // 快速画圆法 void fastCircle(int xc,int yc,int r){ // 初始化绘图窗口 initgraph(640,480); int x, y, d; x = 0; y = r; d = -r / 2; draw_circle_8(xc , yc , x , y); if(r % 2 == 0) { while(x < y) { x++; if(d < 0) d += x; else { y--; d += x - y; } draw_circle_8(xc , yc , x , y); } } else { while(x < y) { x++; if(d < 0) d += x + 1; else { y--; d += x - y + 1; } draw_circle_8(xc , yc , x , y); } } } // 矩形填充算法 void fiilRectangle(MyRectangle *rect){ // 初始化绘图窗口 initgraph(640,480); int x,y; for(y = rect->ymin;y<=rect->ymax;y++){ for(x = rect->xmin;x<=rect->xmax;x++){ putpixel(x,y,WHITE); } } } // 射线法 bool isPointInPolygon(POINT pts[],POINT point,int size){ bool flag = false; POINT p1,p2; for(int i = 0, j = size; i < size; j = i++) { p1 = pts[i]; p2 = pts[j]; // 这里判断是否刚好被测点在多边形的边上 if(isDotInLineSegment(point, p1, p2)) return true; if((p1.y > point.y != p2.y > point.y) && (point.x < (point.y - p1.y) * (p1.x - p2.x) / (p1.y - p2.y) + p1.x)) { flag = !flag; } } return flag; } // 点与线得关系 bool isDotInLineSegment(POINT point,POINT p1,POINT p2){ bool flag = false; double x0 = point.x,y0 = point.y,x1 = p1.x,x2 = p2.x,y1 = p1.y,y2=p2.y; double xmin = x1<x2?x1:x2; double ymin = y1<y2?y1:y2; double xmax = x1>x2?x1:x2; double ymax = y1>y2?y1:y2; if((x1-x0)*(y2-y1)-(x2-x1)*(y1-y0)==0&&(x0>=xmin)&&(x0<=xmax)&&(y0>=ymin)&&(y0<=ymax)){ flag = true; } return flag; } // 判断多边形走向是否是逆时针,逆时针为true bool isClockWise(POINT poly[],int size) { double d = 0; for (int i = 0; i < size-1; i++) { d += -0.5 * (poly[i + 1].y + poly[i].y) * (poly[i + 1].x - poly[i].x); } if (d > 0) { return true; } else { return false; } } int main(){ /*----------------------- 测试最大公约数的计算------------------------ int a = 12,b = 18; cout<<gcd(a,b); */ /*----------------------- 测试直接插入排序算法--------------------------- int arr[] = {99, 2, 3, 1, 22, 88, 7, 77, 54}; si_sort(arr,9); for (int i = 0; i < 9; i++) cout << arr[i] << endl;*/ /*------------------------ 测试选择排序算法------------------------------ int arr[] = {99, 2, 3, 1, 22, 88, 7, 77, 54}; select_sort(arr,9); for (int i = 0; i < 9; i++) cout << arr[i] << endl; */ /*------------------------ 测试冒泡排序算法------------------------------- int arr[] = {99, 2, 3, 1, 22, 88, 7, 77, 54}; bubble_sort(arr,9); for (int i = 0; i < 9; i++) cout << arr[i] << endl; */ /*------------------------ 测试快速排序算法------------------------------- int arr[] = {99, 2, 3, 1, 22, 88, 7, 77, 54}; int arrLength = sizeof(arr)/sizeof(int); fast_sort(arr,0,arrLength-1); for (int i = 0; i < 9; i++) cout << arr[i] << endl; */ /*------------------------ 测试DDA绘制直线方法----------------------------- int x1 = 30,y1 = 30,x2 = 10,y2 = 100; drawDDA(x1,y1,x2,y2); _getch(); // 关闭绘图窗口 closegraph(); */ /*------------------------ 测试bresenham绘制直线方法----------------------------- int x1 = 30,y1 = 30,x2 = 10,y2 = 100; bresenHam(x1,y1,x2,y2); _getch(); // 关闭绘图窗口 closegraph(); */ /*------------------------ 测试中点画线法绘制直线方法----------------------------- int x1 = 30,y1 = 30,x2 = 10,y2 = 100; midPointLine(x1,y1,x2,y2); _getch(); // 关闭绘图窗口 closegraph(); */ /*------------------------ 测试bresenham法绘制圆方法----------------------------- int x1 = 30,y1 = 30,r = 10,fill = 1; bresenHamCircle(x1,y1,r,0); _getch(); // 关闭绘图窗口 closegraph(); */ /*------------------------ 测试中点画线法绘制圆方法----------------------------- int x1 = 30,y1 = 30,r = 10 ; midPointCircle(x1,y1,r); _getch(); // 关闭绘图窗口 closegraph(); */ /*------------------------ 测试正负画线法绘制圆方法----------------------------- int x1 = 30,y1 = 30,r = 10 ; posnegCircle(x1,y1,r); _getch(); // 关闭绘图窗口 closegraph(); */ /*------------------------ 测试快速画圆方法----------------------------- int x1 = 30,y1 = 30,r = 10 ; fastCircle(x1,y1,r); _getch(); // 关闭绘图窗口 closegraph(); */ /*------------------------ 测试矩形填充方法----------------------------- MyRectangle rect = {10,50,10,50} ; fiilRectangle(&rect); _getch(); // 关闭绘图窗口 closegraph(); */ /*------------------------ 测试点与多边形关系判断方法----------------------------- POINT pts[] = { {50, 200}, {200, 200}, {200, 50} ,{50,50}, {50, 200}}; POINT pt = {200,100}; bool isIn = isPointInPolygon(pts,pt,5); cout<<isIn<<endl; */ /*------------------------ 测试多边形走向判断方法----------------------------- POINT pts[] = { {50, 200}, {50, 50}, {200, 50} ,{200,200}, {50, 200}}; POINT pts2[] = { {50, 200}, {200, 200}, {200, 50} ,{50,50}, {50, 200}}; bool isClock = isClockWise(pts2,5); cout<<isClock<<endl; */ system("pause"); }

     

    最新回复(0)