使⽤C语⾔绘制⼀个笑脸smile
⾸先我们绘制⼀个简单的例⼦
#include <math.h>
#include <stdio.h>
int main() {
double a, b;
for (b = 1; b >= -1; b -= 0.05, putchar('\n'))
for (a = -1; a <= 1; a += 0.025)
putchar(" *"[ a * b + b * b < 1 && fabs(atan2(b, a)) > 0.5 && a * a + pow(b - 0.5, 2) > 0.02]);
}
运⾏后,可以在控制台显⽰出⼀个笑脸~~~
# if you do not have gcc, run `brew install gcc` to install
gcc test1.c && ./a.out
gcc test2.c && ./a.out
然后我们可以循环⽣成多个笑脸(当然可以再加⼀个循环⽣成三重笑脸)
#include <math.h>
#include <stdio.h>
int func(double x, double y, int d) {
return
pow(x - 0.5, 2) + pow(y - 0.5, 2) < 0.25 && fabs(atan2(y - 0.5, x - 0.5)) > 0.5 && pow(x - 0.5, 2) + pow(y - 0.75, 2) > 0.005 && (d == 0 || f(fmod(x * 8, 1), fmod(y }
c语言struct用法例子int main() {
double x, y;
for (y = 1; y >= 0; y -= 1.0 / 160.0, putchar('\n'))
for (x = 0; x <= 1; x += 1.0 / 320.0)
putchar(" *"[func(x, y, 1)]);
}
后⾯是我们的终极3D笑脸
#include <math.h>
#include "svpng.inc"
typedef struct { float x, y, z; } V;
V make(float x, float y, float z) { V r = { x, y, z }; return r; }
V add(V a, V b) { return make(a.x + b.x, a.y + b.y, a.z + b.z); }
V sub(V a, V b) { return make(a.x - b.x, a.y - b.y, a.z - b.z); }
V mul(V v, float s) { return make(v.x * s, v.y * s, v.z * s); }
float dot(V a, V b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
float len(V v) { return sqrtf(dot(v, v)); };
V cross(V a, V b) { return make(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); } V norm(V v) { return mul(v, 1.0f / len(v)); }
float min(float a, float b) { return a < b ? a : b; }
float max(float a, float b) { return a > b ? a : b; }
float map(V p) {
V m1 = { cosf(1), 0, sinf(1) }, m2 = { cosf(1), 0, -sinf(1)};
return min(max(len(p) - 1.0f, min(dot(p, m1), dot(p, m2))), p.z + 1.0f);
}
V normal(V p) {
float e = 1e-6f;
V dx = { e, 0, 0 }, dy = {0, e, 0}, dz = {0, 0, e };
return norm(make(
map(add(p, dx)) - map(sub(p, dx)),
map(add(p, dy)) - map(sub(p, dy)),
map(add(p, dz)) - map(sub(p, dz))));
}
V albedo(V p) {
if (p.z + 1 < 1e-4f)
return make(1, 1, 1); // ground
else if (p.x * p.x + powf(p.z - 0.5, 2) < 0.02f)
return make(0, 0, 0); // eye
else
return make(1, 1, 0); // main
}
#define S 1024
unsigned char img[S * S * 3], *c = img;
int main() {
V eye = { 2, 3, 1 }, at = { 0, 0, 0 }, up = { 0, 0, 1 };
V vz = norm(sub(at, eye)), vx = cross(up, vz), vy = cross(vz, vx);
int x, y, i;
for (y = S - 1; y >= 0; y--)
for (x = 0; x < S; x++, c += 3) {
float sx = ((float)x / S - 0.5f) * 3.0f;
float sy = ((float)y / S - 0.5f) * 3.0f;
float sy = ((float)y / S - 0.5f) * 3.0f;
V o = add(add(eye, mul(vx, sx)), mul(vy, sy));
float t = 0;
do {
V p = add(o, mul(vz, t));
float sd = map(p);
if (sd < 1e-4f) {
V n = normal(p), alb = albedo(p);
float ao = 1, s = 0.5f;
for (i = 1; i < 5; i++) {
float d = i * 0.1f;
ao = max(ao - (d - map(add(p, mul(n, d)))) * s, 0.1f);
s *= 0.95f;
}
V r = mul(alb, (dot(n, norm(make(0, 1, 1))) * 0.5f + 0.5f) * ao * 255); c[0] = (unsigned char)r.x;
c[1] = (unsigned char)r.y;
c[2] = (unsigned char)r.z;
break;
}
t += sd;
} while (t < 100);
}
svpng(fopen("pacman.png", "wb"), S, S, img, 0);
}
是不是很厉害!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论