心形图案生成

先看一张效果图: 


其实这个东西很简单的,不过我们首先要知道,爱心的曲线方程,图中的这种爱心曲线方程的标准形式是:

(x2+y21)3x2y3=0
而图中就是两条曲线中间填上阴影就好了,那么在这个方程的标准形式上加上一些缩放比例就得到了公式:
(Ax2+By21)3Bx2y3=0
然后选择合适的 A,B 。最后就是判断一个点是不是在两条曲线之间就好了,高中的知识。

不过爱心的里面我还写了点字,这就要我们手动使用二位字符数组来缓存下这个爱心图形,然后在缓存区中加字,大家可以看源码中我注释的地方就明白了。

#include <stdio.h>
#include <malloc.h>
#include <string.h>

#define CHAR_STAR '*'
#define CHAR_SPACE ' '

#define EPS 1e-1

#define OUT_A 0.3
#define IN_A 0.6
#define IN_B 1.8
#define OUT_B 1.0

#define HEIGH 1.5
#define WIDTH 4.0

#define OFFSET_HEIGH 0.5
#define OFFSET_WIDTH 1.0

#define STRING_ONE "Dear YXR"
#define STRING_TWO "I love you"

double pown(double x, int n)
{
    int i;
    double ret = 1.0;
    for (i = 0; i < n; i++)
        ret *= x;
    return ret;
}

double f(double ratioA, double ratioB, double x, double y)
{
    return pown(ratioA * pown(x, 2) + ratioB * pown(y, 2) - 1, 3) - ratioB * pown(x, 2) * pown(y, 3);
}

int main()
{
    int i, j;
    double x, y;

    int cnt_x = 2 * WIDTH * 10- OFFSET_WIDTH * 10 + 1;
    int cnt_y = 2 * HEIGH * 10- OFFSET_HEIGH * 10 + 1;

    int len = strlen(STRING_ONE);

    int pos_x = (cnt_x + 1 - 2 * len) / 2;
    int posA_y = cnt_y / 3;
    int posB_y = cnt_y * 2 / 3;

    char **buf;

    buf = (char **)malloc(cnt_y * sizeof(char *));
    for (i = 0; i < cnt_y; i++)
        buf[i] = (char *)malloc(cnt_x * sizeof(char) + 1);

    for (i = 0; i < cnt_y; i++)
        for (j = 0; j < cnt_x + 1; j++)
            buf[i][j] = 0;

    for (i = 0, y = HEIGH; y >= -(HEIGH - OFFSET_HEIGH); ++i, y -= EPS) {
        for (j = 0, x = -(WIDTH - OFFSET_WIDTH); x <= WIDTH; ++j, x += EPS)
            if (f(IN_A, IN_B, x, y) >= 0 && f(OUT_A, OUT_B, x, y) < 0)
                buf[i][j] = CHAR_STAR;
            //  putchar(CHAR_STAR);
            else
                buf[i][j] = CHAR_SPACE;
            //  putchar(CHAR_SPACE);
        //puts("");
    }

    for (i = 0; i < len; i++)
        buf[posA_y][pos_x + i] = STRING_ONE[i],
        buf[posB_y][pos_x + i] = STRING_TWO[i];

    for (i = 0; i < cnt_y; i++)
        puts(buf[i]);

    for (i = 0; i < cnt_y; i++)
        free(buf[i]);
    free(buf);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值