MiddlePoint算法

MiddlePoint

  MiddlePoint算法:代中点入直线的隐式方程中,然后判定正负

  假定直线的斜率在0到1之间(直线和x轴的夹角小于45°),x=x(i)时已选(x(i), y(i))像素,此时x=x(i)+1与直线最近的像素P1(x(i)+1, y1(i))、P2(x(i)+1), y(i)+1)。

  假定M是表示P1与P2的中点,M=(x(i)+1, y(i)+0.5),Q是直线与垂直线x=x(i)+1的交点,如果M在Q的下方,那么P2离直线更近,应该取为下一个像素点;如果M在Q点上方,则P1离直线更近,应该取为下一个像素点;如果M和Q重合,习惯地取P1为下一个像素点(运算更快)。

在这里插入图片描述
  假设起点和终点分别为(x0, y0)和(x1, y1),隐式方程为F(x, y) = ax + by + c,可以用待定系数法求出:
  a = y0 - y1
  b = x1 - x0
  c = x0y1 - x1y0

在这里插入图片描述

直线上的点,F(x, y) = 0;
直线上方的点,F(x, y) > 0;
直线下方的点,F(x, y) < 0。

  将M=(x(i)+1, y(i)+0.5)代入隐式方程F(x, y),d = F(M) = F(x(i)+1, y(i)+0.5) = a(x(i)+1) + b(y(i)+0.5) + c
  当d<0时,M在直线下方,所以选取右上方的P2点;
  当d>0时,M在直线上方,所以选取右上方的P1点;
  当d=0时,M在直线上,选取P1点。

对每一个像素进行判别式d,根据d的符号确定下一像素:
  若d>=0,取P1,去了之后再判断下一个像素,计算:d1 = F(x(i)+2, y(i)+0.5) = a(x(i)+2) + b(y(i)+0.5) + c = d + a,d的增量为a;
  若d<0,取P2,同理:d2 = d + a + b,d的增量为a + b。

  再看看d的初始值,显然,第一个像素应取为左端点(x0, y0),相应的判别式值为:d0 = F(x0+1, y0 + 0.5) = F(x0, y0) + a + 0.5b = a + 0.5b;
因此,d的初始值为d0 = a + 0.5b,此处为了避免浮点数运算,可以使用2d来替代d。(2d = 2a + b)

手动画点举个例子:
在这里插入图片描述
关键部分代码实现:

void MidPointLine(int x0, int y0, int x1, int y1)
{
	int a, b, d1, d2, d, x, y;
	a = y0 - y1;
	b = x1 - x0;
	d = 2 * a + b;
	d1 = 2 * a;
	d2 = 2 * (a + b);
	x = x0;
	y = y0;
	glPointSize(5.0);
	glBegin(GL_POINTS);
	glVertex2i(x, y);
	glEnd();
	glFlush();
	while (x < x1)
	{
		if (d < 0)
		{
			x++;
			y++;
			d += d2;
		}
		else
		{
			x++;
			d += d1;
		}
		glPointSize(5.0);
		glBegin(GL_POINTS);
		glVertex2i(x, y);
		glEnd();
		glFlush();
	}
}

测试结果:
在这里插入图片描述

完整代码:

#include <GL/glut.h>
#include <math.h>

/*
void DDA_Line(int x1, int y1, int x2, int y2) {
	double dx, dy, e, x, y;
	dx = x2 - x1;
	dy = y2 - y1;
	e = (fabs(dx) > fabs(dy)) ? fabs(dx) : fabs(dy);
	dx /= e;
	dy /= e;
	x = x1;
	y = y1;
	for (int i = 0; i < e; i++) {
		glPointSize(5.0);
		glBegin(GL_POINTS);
		glVertex2i(int(x + 0.5), int(y + 0.5));
		glEnd();
		glFlush();
		x += dx;
		y += dy;
	}
}
*/

void MidPointLine(int x0, int y0, int x1, int y1)
{
	int a, b, d1, d2, d, x, y;
	a = y0 - y1;
	b = x1 - x0;
	d = 2 * a + b;
	d1 = 2 * a;
	d2 = 2 * (a + b);
	x = x0;
	y = y0;
	glPointSize(5.0);
	glBegin(GL_POINTS);
	glVertex2i(x, y);
	glEnd();
	glFlush();
	while (x < x1)
	{
		if (d < 0)
		{
			x++;
			y++;
			d += d2;
		}
		else
		{
			x++;
			d += d1;
		}
		glPointSize(5.0);
		glBegin(GL_POINTS);
		glVertex2i(x, y);
		glEnd();
		glFlush();
	}
}

void display(void) {
	glClearColor(1.0, 1.0, 1.0, 0.0);
	glClear(GL_COLOR_BUFFER_BIT);
	glViewport(0, 0, 500, 500);
	//DDA_Line(0, 500, 500, 0);
	MidPointLine(100, 100, 300, 300);
	glFlush();
}

int main(int argc, char **argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RED);
	glutInitWindowSize(500, 500);
	glutInitWindowPosition(0, 0);
	glutCreateWindow("DDA_line");
	glutDisplayFunc(display);
	glColor3f(1.0, 0.0, 1.0);//颜色
	gluOrtho2D(0.0, 500.0, 0.0, 500.0);
	glutMainLoop();
	return 0;
}
很高兴回答你的问题!我可以提供一个Java示例代码来说明分治法求最大字段和算法: // Java Implementation of Max Sum Subarray using Divide and Conquer public class MaxSubArraySum { // Function to find the maximum possible sum in arr[] // such that arr[m] is part of it static int maxCrossingSum(int arr[], int l, int m, int h) { // Include elements on left of mid. int sum = 0; int left_sum = Integer.MIN_VALUE; for (int i = m; i >= l; i--) { sum = sum + arr[i]; if (sum > left_sum) left_sum = sum; } // Include elements on right of mid sum = 0; int right_sum = Integer.MIN_VALUE; for (int i = m + 1; i <= h; i++) { sum = sum + arr[i]; if (sum > right_sum) right_sum = sum; } // Return sum of elements on left and right of mid return left_sum + right_sum; } // Returns sum of maxium sum subarray in aa[l..h] static int maxSubArraySum(int arr[], int l, int h) { // Base Case: Only one element if (l == h) return arr[l]; // Find middle point int m = (l + h)/2; /* Return maximum of following three possible cases a) Maximum subarray sum in left half b) Maximum subarray sum in right half c) Maximum subarray sum such that the subarray crosses the midpoint */ return Math.max(Math.max(maxSubArraySum(arr, l, m), maxSubArraySum(arr, m+1, h)), maxCrossingSum(arr, l, m, h)); } /*Driver program to test maxSubArraySum*/ public static void main(String[] args) { int arr[] = {2, 3, 4, 5, 7}; int n = arr.length; int max_sum = maxSubArraySum(arr, 0, n-1); System.out.println("Maximum contiguous sum is "+ max_sum); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值