个性化阅读
专注于IT技术分析

计算机图形:扫描转换直线

本文概述

一条直线可以由两个端点和一个方程式定义。在图1中, 两个端点由(x1, y1)和(x2, y2)描述。直线方程式用于确定这两个端点之间所有点的x, y坐标。

扫描转换直线

使用直线方程y = mx + b, 其中m =&b = y中断, 我们可以通过将x从x = x1递增到x = x2来找到y的值。通过对这些计算出的x, y值进行扫描转换, 我们将线条表示为像素序列。

好的线描算法的性质

1.线应显示为直线:我们必须通过选择靠近其的可寻址点来使线合适。如果选择正确, 该线将显示为直线, 否则, 将产生交叉线。

扫描转换直线

直线必须与x轴和y轴平行或成45度角生成。其他线会引起问题:通过它的线段在可寻址点处开始和结束, 可能恰好没有经过它们之间的其他可寻址点。

扫描转换直线

2.线应准确终止:除非精确绘制线, 否则它们可能在错误的位置终止。

扫描转换直线

3.线应具有恒定的密度:线密度与编号成正比。显示的点数除以线的长度。

为了保持恒定的密度, 点应均匀分布。

4.线密度应与线长度和角度无关:可以通过计算近似的线长估算值并使用线生成算法来使线密度恒定在此估算精度范围内。

5.应当快速画线:此计算应由专用硬件执行。

画线算法

  1. 直接使用线方程
  2. DDA(数字差分分析仪)
  3. 布雷森纳姆算法

直接使用线方程

这是最简单的转换形式。首先扫描P1和P2点。 P1具有坐标(x1′, y1’)和(x2’y2’)。

然后m =(y2′, y1’)/(x2′, x1’)和b =

对于x的每个整数值, 如果| m |≤1的值。但是不要考虑

对于每个y整数值, 如果| m |> 1的值。但是不要考虑

示例:给出了一条起点为(0, 0)和终点(6, 18)的线。计算中间点的值和直线的斜率。

解决方案:P1(0, 0)P7(6, 18)

x1 = 0 y1 = 0 x2 = 6 y2 = 18

我们知道线的方程是y = m x + b y = 3x + b …………..等式(1)

将x的值从等式(1)的初始点开始计算, 即(0, 0)x = 0, y = 0 0 = 3 x 0 + b 0 = b⟹b = 0

将b = 0代入等式(1)y = 3x + 0 y = 3x

现在计算中间点令x = 1 y = 3 x 1 y = 3令x = 2 y = 3 x 2 y = 6令x = 3 y = 3 x 3 y = 9令x = 4 y = 3 x 4 y = 12令x = 5 y = 3 x 5 y = 15令x = 6 y = 3 x 6 y = 18

这样的点就是P1(0, 0)P2(1, 3)P3(2, 6)P4(3, 9)P5(4, 12)P6(5, 15)P7(6, 18)

扫描转换直线

用方程画线的算法

步骤1:开始算法

步骤2:声明变量x1, x2, y1, y2, dx, dy, m, b,

步骤3:输入x1, x2, y1, y2的值。 (x1, y1)是直线起点的坐标。 (x2, y2)是直线终点的坐标。

步骤4:计算dx = x2- x1

步骤5:计算dy = y2-y1

步骤6:计算m =

步骤7:计算b = y1-m * x1

步骤8:设置(x, y)等于起点, 即最低点, xend等于x的最大值。

如果dx <0, 则x = x2 y = y2 xend = x1如果dx> 0, 则x = x1 y = y1 xend = x2

步骤9:如果x = xend, 检查是否已画出整条线, 然后停止

步骤10:在当前(x, y)坐标上绘制一个点

步骤11:x的递增值, 即x = x + 1

步骤12:根据方程式y = mx + b计算y的下一个值

步骤13:转到步骤9。

程序使用LineSlope方法画一条线

#include <graphics.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <conio.h>
#include <iostream.h>

class bresen
{
	float x, y, x1, y1, x2, y2, dx, dy, m, c, xend;
	public:
	void get ();
	void cal ();
};
	void main ()
    {
	bresen b;
	b.get ();
	b.cal ();
	getch ();
   }
	Void bresen :: get ()
   {
	print ("Enter start & end points");
	print ("enter x1, y1, x2, y2");
	scanf ("%f%f%f%f", sx1, sx2, sx3, sx4)
}
void bresen ::cal ()
{
	/* request auto detection */
	int gdriver = DETECT, gmode, errorcode;
	/* initialize graphics and local variables */
	initgraph (&gdriver, &gmode, " ");
	/* read result of initialization */
	errorcode = graphresult ();
	if (errorcode ! = grOK)    /*an error occurred */
	{
 		printf("Graphics error: %s \n", grapherrormsg (errorcode);
		printf ("Press any key to halt:");
		getch ();
		exit (1); /* terminate with an error code */
	}
	dx = x2-x1;
	dy=y2-2y1;
	m = dy/dx;
	c = y1 - (m * x1);
	if (dx<0)
	{
		x=x2;
		y=y2;
		xend=x1;
	}
    else
	{
		x=x1;
		y=y1;
		xend=x2;
	}
while (x<=xend)
	{
		putpixel (x, y, RED);
		y++;
		y=(x*x) +c;
	}
}

输出:

Enter Starting and End Points
Enter (X1, Y1, X2, Y2) 200 100 300 200
扫描转换直线

赞(0)
未经允许不得转载:srcmini » 计算机图形:扫描转换直线

评论 抢沙发

评论前必须登录!