
import win.ui;
/*DSG{{*/
var winform = win.form(text="点云球";right=639;bottom=479;bgcolor=0)
winform.add(
plus={cls="plus";left=0;top=0;right=640;bottom=480;db=1;dl=1;dr=1;dt=1;z=1}
);
/*}}*/
import gdip;
import gdip.graphics;
// --- 配置参数 ---
var MAXPOINT = 2888; // 点数过多会导致 GDI+ 绘图频率下降,1200点较平衡
var PI = 3.1415926536;
var viewZ = 3.0; // 视点深度
var p3d = {};
math.randomize();
// 1. 初始化球面随机点
var initPoint = function(){
for(i=1; MAXPOINT; 1){
var z = 2.0 * math.random() - 1;
var rxy = math.sqrt(1 - z * z);
var a = 2 * PI * math.random();
table.push(p3d, {
x = math.cos(a) * rxy;
y = math.sin(a) * rxy;
z = z;
})
}
}
// 2. 旋转逻辑
var rotateAll = function(){
// 绕三个轴小幅度旋转弧度
var ax, ay, az = PI/800, PI/600, PI/400;
var cosX, sinX = math.cos(ax), math.sin(ax);
var cosY, sinY = math.cos(ay), math.sin(ay);
var cosZ, sinZ = math.cos(az), math.sin(az);
for(i=1; #p3d; 1){
var p = p3d[i];
// X轴旋转
var y = p.y;
p.y = y * cosX - p.z * sinX;
p.z = y * sinX + p.z * cosX;
// Y轴旋转
var x = p.x;
p.x = x * cosY + p.z * sinY;
p.z = -x * sinY + p.z * cosY;
// Z轴旋转
x = p.x;
p.x = x * cosZ - p.y * sinZ;
p.y = x * sinZ + p.y * cosZ;
}
// 关键:旋转后立即排序(画家算法),解决遮挡关系
table.sort(p3d, lambda(next) owner.z < next.z);
}
initPoint();
// 3. 绘图回调 (只负责渲染)
// 规范:参数依次为 (graphics, rc, txtColor, rcContent, foreColor)
winform.plus.onDrawContent = function(graphics, rc) {
graphics.smoothingMode = 4/*_GdipSmoothingModeAntiAlias*/;
var centerX = rc.width() / 2;
var centerY = rc.height() / 2;
for(i=1; #p3d; 1){
var p = p3d[i];
// 透视投影计算
var factor = viewZ / (viewZ - p.z);
var screenX = (p.x * factor * 220) + centerX;
var screenY = (p.y * factor * 220) + centerY;
// 颜色深度计算 (z 范围 -1 到 1)
var brightness = math.floor((p.z + 1) * 100) + 55; // 55~255
var r = brightness;
var g = math.floor(brightness * 0.1);
var b = math.floor(brightness * 0.6);
var alpha = math.floor((p.z + 1) * 75) + 100; // 100~250
// 构造 ARGB 颜色
var argb = (alpha << 24) | (r << 16) | (g << 8) | b;
// 创建画刷并绘制
var brush = gdip.solidBrush(argb);
var dotSize = 1.5 * factor;
// 修正:直接调用成员方法,不建议缓存函数
graphics.fillEllipse(brush, screenX - dotSize/2, screenY - dotSize/2, dotSize, dotSize);
// 必须及时删除画刷,防止内存泄漏
brush.delete();
}
}
// 4. 定时刷新逻辑
winform.setInterval(
function(){
rotateAll(); // 在计时器中处理逻辑
winform.plus.redraw(); // 触发绘图回调
}, 15
)
// 设置控件属性
winform.plus.background = 0xFF000000; // 背景黑
winform.plus.foreground = 0x00000000; // 前景透
winform.show();
win.loopMessage();