关于用c语言打印图形的一些问题


#1

一般来说,这种题目都是考察 for 循环来的.但是看到了 这个 ](https://zhihu.com/question/34552247/answer/68637681) ,我就想也许可以新建一个坐标系,将需要打印的图形用不等式表达出来,然后遍历二维平面,符合该不等式的点就输出可见字符,不符合的就输出空格,应该就可以用于各种不同的图形了.

只是还有些疑惑,我该怎么选择坐标系?原点放在哪个位置?x 轴和 y 轴的方向呢?还有什么需要特别考虑的?


#2

坐标系按正常情况建立就行了,公式确定后,决定你要打印的 x 轴和 y 轴的区间范围,从左上角开始向右一行一行的打印。

例如用 ruby 画圆:

#!/usr/bin/env ruby

r = 10 # 半径

# 区间, x = -12, 12], y = -12, 12]
12.downto(-12).each do |y|
  (-12..12).each do |x|
    if r**2 >= x**2 + y**2
      print "*"
    else
      print " "
    end
  end
  puts ""
end

# 区间, x = [0, 12], y = [0, 12]
12.downto(0).each do |y|
  (0..12).each do |x|
    if r**2 >= x**2 + y**2
      print "*"
    else
      print " "
    end
  end
  puts ""
end

#3

不是很理解.感觉边界条件不好确定.


#4

一个图形首先要找到能画出它的公式,例如圆形的公式是 xx + yy = rr ,把这个公式变换成 xx + yy - rr = 0 。

半径 r 是已知的数据,我们把点 (x, y) 代入公式 xx + yy - r*r 计算出一个结果,如果结果等于 0 表示点 (x, y) 刚好落在圆的线上,如果结果小于 0 表示点 (x, y) 落在圆内,如果结果大于 0 表示点 (x, y) 落在圆外。

任何一个图形只要能用公式进行表示,都可以换算成等式一边为 0 的公式,剩下的只要确认打印的点是处于大于 0 还是小于 0 的区域就行了。


#5

举个例子,

#include <stdio.h>
#include <stdlib.h>

void print(int row);
void print_formula(int row);
int f(double x, double y, double row);

int main(int argc, char **argv)
{
	int row;

	scanf("%d", &row);
	print(row);
//	print_formula(row);

	return EXIT_SUCCESS;
}

void print(int row) {
	for(int i = 0; i < row; i++) {
		for(int j = 2*i;j < 2*row - 1; j++) {
			putchar('*');
		}
		putchar('\n');
	}
}

这个用 for 循环输出类似这样的图形

*******
*****
***
*

其中行数由用户输入.若是用另外一种方法写呢?

假设我用图形左上角的点作为原点 (0, 0),x 轴正向向右,y 轴正向向下,则这个图形用不等式表达出来应该就是:0 < x < 2*row - 1, 0 < y < row -x/2,那么我就可以写

int f(double x, double y, double row) {
   return y < row - x/2
}

void print_formula(int row) {
        for(int y = 0; y > -row; y--) {
                for(int x = 0; x < 2*row - 1 ; x++) {
                        putchar(f(x, y, row) ? '*' : ' ');
                }
                putchar('\n');
        }
}

测试一下,好像不对啊.


#6

如果用图形左上角的点作为原点 (0, 0),x 轴正向向右,y 轴正向向下。我们先将 y 轴翻转成正向向上,变成正常的坐标系,你要输出的图形也要翻转,应该是这样的:

*
***
*****
*******

我们求出这个公式为 y = 3 - 1 / 2 * x,变换成 x + 2 * y - 6 = 0,要打印的区域为小于 0。

按照你最终要输出的图形,我们来确定 x 和 y 的范围。最终的图形我们要从左上开始打印,也就是 y 是从 0-3 递增的,x 是从 0-6 递增的。

打印的代码:

#!/usr/bin/env ruby
# -*- coding: utf-8 -*-

# x = [0, 6], y = [0, 3]
(0..3).each do |y|
  (0..6).each do |x|
    if x + 2*y - 6 <= 0
      print "*"
    else
      print " "
    end
  end
  puts ""
end

#7

仔细看看,好像是因为我把公式算错了,毕竟 y 轴向下看着不太习惯.233