c语言 绘制任意斜率的直线,计算机图形学 绘制任意斜率的直线(1)

作者:卿笃军

本文演示,通过自己编写绘制直线函数(像素点填充),绘制任意斜率的直线。

1)创建CP2类

头文件:p2.h

// P2.h: interface for the CP2 class.

//

//

#if !defined(AFX_P2_H__85E77AD6_0704_4E12_8E74_5BE1744B3154__INCLUDED_)

#define AFX_P2_H__85E77AD6_0704_4E12_8E74_5BE1744B3154__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

//二维点类

class CP2

{

public:

CP2();

CP2(double x,double y);

virtual ~CP2();

public: //方便访问,直接定义为共有

double x;

double y;

};

#endif // !defined(AFX_P2_H__85E77AD6_0704_4E12_8E74_5BE1744B3154__INCLUDED_)

实现文件:p2.cpp

// P2.cpp: implementation of the CP2 class.

//

//

#include "stdafx.h"

#include "DrawLine.h"

#include "P2.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

//

// Construction/Destruction

//

CP2::CP2()

{

x=0.0;

y=0.0;

}

CP2::CP2(double x,double y)

{

this->x=x;

this->y=y;

}

CP2::~CP2()

{

}

2)创建CLine类

头文件:Line.h

// Line.h: interface for the CLine class.

//

//

#if !defined(AFX_LINE_H__8A91E283_F40D_4086_8BB8_7A9D9A6DB4D5__INCLUDED_)

#define AFX_LINE_H__8A91E283_F40D_4086_8BB8_7A9D9A6DB4D5__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#include "P2.h"

class CLine

{

public:

CLine();

virtual ~CLine();

void MoveTo(CP2 p0); //移动到指定位置

void MoveTo(double x, double y);

void LineTo(CP2 p1, CDC *pDC); //绘制直线,不含终点

void LineTo(double x, double y, CDC *pDC);

private:

CP2 P0; //起点

CP2 P1; //终点

};

#endif // !defined(AFX_LINE_H__8A91E283_F40D_4086_8BB8_7A9D9A6DB4D5__INCLUDED_)

实现文件:Line.cpp

// Line.cpp: implementation of the CLine class.

//

//

#include "stdafx.h"

#include "DrawLine.h"

#include "Line.h"

#include "math.h"

#define Round(d) int(floor(d+0.5))//四舍五入宏定义

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

//

// Construction/Destruction

//

CLine::CLine()

{

}

CLine::~CLine()

{

}

void CLine::MoveTo(CP2 p0) //记录直线起点函数

{

P0=p0;

}

void CLine::MoveTo(double x, double y)

{

P0.x = x;

P0.y = y;

}

void CLine::LineTo(double x, double y, CDC *pDC) //绘制

{

CP2 p;

p.x = x;

p.y = y;

LineTo(p, pDC);

}

void CLine::LineTo(CP2 p1, CDC *pDC)

{

P1=p1;

CP2 p,t;

COLORREF clr = RGB(0,0,0); //黑色像素点

if(fabs(P0.x-P1.x)<1e-6) //绘制垂线

{

if(P0.y>P1.y) //交换顶点,使得起始点低于终点

{

t=P0;P0=P1;P1=t;

}

for(p=P0;p.y

{

pDC->SetPixelV(Round(p.x),Round(p.y),clr);

}

}

else

{

double k,d;

k=(P1.y-P0.y)/(P1.x-P0.x); //斜率

if(k>1.0) //绘制k>1(y为主方向)

{

if(P0.y>P1.y)

{

t=P0;P0=P1;P1=t;

}

d=1-0.5*k; //中点初始值

for(p=P0;p.y

{

pDC->SetPixelV(Round(p.x),Round(p.y), clr);

if(d>=0) //中点位于将绘制点上方,填充下方点

{

p.x++;

d=d+1-k; //递推公式:当d>=0时,d(i+1)=d(i)+1-k;

}

else

d+=1;

}

}

if(0.0<=k && k<=1.0) //绘制0<=k<=1(x为主方向)

{

if(P0.x>P1.x)

{

t=P0;P0=P1;P1=t;

}

d=0.5-k; //中点初始值

for(p=P0;p.x

{

pDC->SetPixelV(Round(p.x),Round(p.y), clr);

if(d<0) //中点位于将绘制点下方,填充上方点

{

p.y++;

d=d+1-k; //递推公式:当d<0时,d(i+1)=d(i)+1-k;

}

else

d-=k;

}

}

if(k>=-1.0 && k<0.0)//绘制-1<=k<0(x为主方向)

{

if(P0.x>P1.x)

{

t=P0;P0=P1;P1=t;

}

d=-0.5-k; //中点初始化

for(p=P0;p.x

{

pDC->SetPixelV(Round(p.x),Round(p.y), clr);

if(d>0) //中点位于将绘制点上方,填充下方点

{

p.y--;

d=d-1-k; //递推公式:当d>0时,d(i+1)=d(i)-1-k;

}

else

d-=k;

}

}

if(k

{

if(P0.y

{

t=P0;P0=P1;P1=t;

}

d=-1-0.5*k; //中点初始化

for(p=P0;p.y>P1.y;p.y--)

{

pDC->SetPixelV(Round(p.x),Round(p.y), clr);

if(d<0) //中点位于将绘制点下方,填充上方点

{

p.x++;

d=d-1-k;//递推公式:当d>0时,d(i+1)=d(i)-1-k;

}

else

d-=1;

}

}

}

P0=p1; //将终点赋值给起点

}3)OnDraw函数

void CDrawLineView::OnDraw(CDC* pDC)

{

CDrawLineDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

//绘制直线

CLine *line=new CLine;//动态创建直线绘制类对象

line->MoveTo(100,100);

line->LineTo(500,500, pDC);

}

4)绘制效果如下

0818b9ca8b590ca3270a3433284dd417.png

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用C语言绘制抛物线和直线的示例代码。在此示例中,我们将使用二次函数y = ax^2 + bx + c和一次函数y = kx + d来分别表示抛物线和直线。 ```c #include <stdio.h> void draw_parabola(int a, int b, int c); void draw_line(int k, int d); int main() { int a, b, c, k, d; printf("请输入二次函数的参数a、b、c:"); scanf("%d %d %d", &a, &b, &c); printf("请输入直线斜率k和截距d:"); scanf("%d %d", &k, &d); draw_parabola(a, b, c); draw_line(k, d); return 0; } void draw_parabola(int a, int b, int c) { int x, y; for (x = -30; x <= 30; x++) { y = a * x * x + b * x + c; if (y >= -30 && y <= 30) { printf("*"); } else { printf(" "); } } printf("\n"); } void draw_line(int k, int d) { int x, y; for (x = -30; x <= 30; x++) { y = k * x + d; if (y >= -30 && y <= 30) { printf("+"); } else { printf(" "); } } printf("\n"); } ``` 在这个程序中,我们使用了两个函数,`draw_parabola`和`draw_line`,来绘制抛物线和直线。这两个函数都使用了`for`循环来遍历x轴上的所有点,并根据函数的表达式计算出相应的y坐标。如果y坐标在屏幕的可视范围内,我们就在该点上打印一个字符来表示抛物线或直线。如果y坐标不在可视范围内,我们就打印一个空格来留白。 要注意的是,在本例中,我们假设x轴的范围是从-30到30,y轴的范围也是从-30到30。如果需要更大的范围,可以相应地调整循环的起始和结束值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值