
import win.ui;
import gdip;
/*DSG{{*/
var winform = win.form(text="绘制3D正方体[线条版]演示 - (By Mr_MAO) ";right=759;bottom=469)
winform.add(
plus={cls="plus";left=0;top=0;right=760;bottom=470;db=1;dl=1;dr=1;dt=1;notify=1;z=1}
);
/*}}*/
// 定义 3D 顶点 (x, y, z)
var vertices = {
{-1, -1, -1}; {1, -1, -1}; {1, 1, -1}; {-1, 1, -1};
{-1, -1, 1}; {1, -1, 1}; {1, 1, 1}; {-1, 1, 1}
};
// 定义 12 条边
var edges = {
{1, 2}; {2, 3}; {3, 4}; {4, 1}; // 底面
{5, 6}; {6, 7}; {7, 8}; {8, 5}; // 顶面
{1, 5}; {2, 6}; {3, 7}; {4, 8} // 侧边
};
// 定义 6 个面
var faces = {
{1,2,3,4},{5,6,7,8},{1,2,6,5},{2,3,7,6},{3,4,8,7},{4,1,5,8}
};
// 定义 6 个面的颜色
var facecolors = {
0xFFF0E68C,0xFF90EE90,0xFF9370DB,0xFFFF6347,0xFF4169E1,0xFFD3D3D3
};
// 状态变量
var cubeState = {
angleX = 0.5;
angleY =0.5;
scale = 100;
offsetX = 380;
offsetY = 235;
}
// 旋转计算
var rotate = function(v, ax, ay) {
var x, y, z = v[1], v[2], v[3];
// 绕 X 轴旋转
var y1 = y * ..math.cos(ax) - z * ..math.sin(ax);
var z1 = y * ..math.sin(ax) + z * ..math.cos(ax);
// 绕 Y 轴旋转
var x2 = x * ..math.cos(ay) + z1 * ..math.sin(ay);
var z2 = -x * ..math.sin(ay) + z1 * ..math.cos(ay);
return x2, y1, z2;
}
// 绘图回调
winform.plus.onDrawForegroundEnd = function(graphics, rc){
var rgbForm = ::GetSysColor(0x4/*_COLOR_MENU*/);
// rgb → argb
var argbForm = ( (rgbForm & 0xFF) << 16 ) | (rgbForm & 0xFF00) | (rgbForm>> 16 & 0xFF) | 0xFF000000;
graphics.clear( argbForm );
//自适应显示器的分辨率
var scaleX, scaleY = winform.getScale();
graphics.scale(scaleX, scaleY);
// 计算坐标
var projected,maxz,maxp = {},0,0;
for(i=1;#vertices){
var v = vertices[i];
var x, y, z = rotate(v, cubeState.angleX, cubeState.angleY);
..table.push(projected, {
x = x * cubeState.scale + cubeState.offsetX;
y = y * cubeState.scale + cubeState.offsetY;
});
if z>maxz {
maxz = z;
maxp = i;
}
}
//绘制面
var pen = gdip.pen(0xFF000000,1);
for(i=1;#faces;1){
if ..table.find(faces[i],maxp){
var brush = ..gdip.solidBrush(facecolors[i])
graphics.fillPolygon(brush,
[projected[faces[i][1]].x,
projected[faces[i][1]].y,
projected[faces[i][2]].x,
projected[faces[i][2]].y,
projected[faces[i][3]].x,
projected[faces[i][3]].y,
projected[faces[i][4]].x,
projected[faces[i][4]].y]
)
graphics.drawPolygon(pen,
[projected[faces[i][1]].x,
projected[faces[i][1]].y,
projected[faces[i][2]].x,
projected[faces[i][2]].y,
projected[faces[i][3]].x,
projected[faces[i][3]].y,
projected[faces[i][4]].x,
projected[faces[i][4]].y])
brush.delete()
}
}
pen.delete();
// 绘制文本
var fontFamily = gdip.family("Segoe UI Emoji");
var font = fontFamily.createFont(12, 0/*_FontStyleRegular*/);
var strformat = gdip.stringformat();
var brushText = gdip.solidBrush(0xFFFF0000);
graphics.drawString(
"按🖱左键:移动 / 按🖱右键:旋转 / 拨🖱中键:缩放",
font,
::RECTF(10, 10, 400, 50),
strformat,
brushText
);
//绘制节点序号
for(i=1;#projected){
graphics.drawString(i++"",
font,
::RECTF(projected[i].x,projected[i].y, 50, 50),
strformat,
brushText
)
}
font.delete(); brushText.delete(); strformat.delete(); fontFamily.delete();
}
// 鼠标交互逻辑
var mousePos = {x=0; y=0};
var isDragging = false;
var isRotating = false;
// 处理鼠标事件
winform.plus.wndproc = function(hwnd,message,wParam,lParam){
select( message ) {
case 0x201/*_WM_LBUTTONDOWN*/{
var x, y = win.getMessagePos(lParam);
mousePos.x, mousePos.y = x, y;
isDragging = true;
winform.plus.capture = true;
}
case 0x204/*_WM_RBUTTONDOWN*/, 0x207/*_WM_MBUTTONDOWN*/{
isRotating = true;
winform.plus.capture = true;
}
case 0x20A/*_WM_MOUSEWHEEL*/{
var delta = wParam >> 16;
cubeState.scale = cubeState.scale + (delta / 120) * 10;
if(cubeState.scale < 10) cubeState.scale = 10;
winform.plus.redraw();
}
case 0x202/*_WM_LBUTTONUP*/,0x205/*_WM_RBUTTONUP*/,0x208/*_WM_MBUTTONUP*/{
isDragging = false; isRotating = false;
winform.plus.capture = false;
}
}
}
winform.plus.onMouseMove = function(wParam,lParam){
var x, y = win.getMessagePos(lParam);
var dx = x - mousePos.x;
var dy = y - mousePos.y;
if(isDragging){
cubeState.offsetX = cubeState.offsetX + dx;
cubeState.offsetY = cubeState.offsetY + dy;
winform.plus.redraw();
}
elseif(isRotating){
cubeState.angleY = cubeState.angleY + dx * 0.01;
cubeState.angleX = cubeState.angleX + dy * 0.01;
winform.plus.redraw();
}
mousePos.x = x;
mousePos.y = y;
}
winform.show();
win.loopMessage();