涉及到图形学,有比较复杂的数学计算,所以绘制过程可能会比较耗时,效果图就不上了,看代码执行结果吧。。。
/*Bitmap{{*/
createBitmap = function(w=0, h=0, c=32){
c = c<32 ? 24 : 32
var len = (c>>3) * w * h
return {
struct bmfHeader = {
WORD bfType = 0x4D42;
int bfSize = 54 + len;
WORD bfReserved1;
WORD bfReserved2;
int bfOffBits = 54;
_struct_aligned = 2;
};
struct bmiHeader = {
INT biSize = 40;
int biWidth = w;
int biHeight = h;
WORD biPlanes = 1;
WORD biBitCount = c;
INT biCompression;
INT biSizeImage = len;
int biXPelsPerMeter;
int biYPelsPerMeter;
INT biClrUsed;
INT biClrImportant;
_struct_aligned = 2;
};
byte pixs[] = ..raw.buffer(len)
}
}
/*}}*/
var code = /**
#include <math.h>
float f(float x, float y, float z)
{
float a = x * x + 9.0f / 4.0f * y * y + z * z - 1;
return a * a * a - x * x * z * z * z - 9.0f / 80.0f * y * y * z * z * z;
}
float h(float x, float z)
{
for (float y = 1.0f; y >= 0.0f; y -= 0.001f)
if (f(x, y, z) <= 0.0f)
return y;
return 0.0f;
}
int mDraw(char* img, int sw, int sh)
{
int lw = sw*3;
int i = lw*sh - lw + 2, nextLineOffset = lw * 2;
for (int sy = 0; sy < sh; sy++)
{
float z = 1.5f - sy * 3.0f / sh;
for (int sx = 0; sx < sw; sx++)
{
float x = sx * 3.0f / sw - 1.5f;
float v = f(x, 0.0f, z);
int r = 0;
if (v <= 0.0f)
{
float y0 = h(x, z);
float ny = 0.001f;
float nx = h(x + ny, z) - y0;
float nz = h(x, z + ny) - y0;
float nd = 1.0f / sqrt(nx * nx + ny * ny + nz * nz);
float d = (nx + ny - nz) / sqrt(3) * nd * 0.5f + 0.5f;
r = (int)(d * 255.0f);
}
img[ i ] = r;
i += 3;
}
i -= nextLineOffset;
}
return 0;
}
**/
import win.ui;
/*DSG{{*/
var winform = win.form(text="自绘3D心形图";right=530;bottom=530)
winform.add(
plus={cls="plus";left=6;top=6;right=518;bottom=518;z=1}
)
/*}}*/
var w, h = 512, 512
var bmpObj = createBitmap(w, h, 24)
var p = bmpObj.pixs
/**填充随机颜色
..math.randomize()
var rnd = ..math.random
var len = bmpObj.bmiHeader.biSizeImage
for(i=1;len;3){
p[ i ] = rnd(0, 255) //b
p[i+1] = rnd(0, 255) //g
p[i+2] = rnd(0, 255) //r
//p[i+3] = rnd(0, 255) //a
}
//**/
import tcc;
var vm = tcc();
vm.compile(code);
vm.mDraw(p, w, h)
var bmp = ..raw.tostring(bmpObj)
winform.plus.foreground = bmp
//..string.save("\Heart.bmp", bmp)
winform.show();
win.loopMessage();
|