魔方吧·中文魔方俱乐部

 找回密码
 注册
搜索
热搜: 魔方
楼主: Fenz

Fenz 的在线魔方程序【更新变形魔方】 [复制链接]

银魔

魔方思者

Rank: 7Rank: 7Rank: 7

积分
2991
帖子
1816
精华
6
UID
102191
性别
保密
兴趣爱好
理论
结构
破解

四年元老

发表于 2014-5-6 23:35:41 |显示全部楼层
redcarrot 发表于 2014-5-5 17:30
个人觉得空心点角块才能转的操作方式有点奇怪。。。还是想去点中间。。。
求公布剩下两个,试不出来!!!

现在空心魔方的中间可以点了。

使用道具 举报

Rank: 8Rank: 8

积分
18017
帖子
16456
精华
9
UID
449
性别

魔方理论探索者 论坛建设奖 爱心大使 十年元老

发表于 2014-5-7 10:35:59 |显示全部楼层
本帖最后由 乌木 于 2014-5-7 11:37 编辑

初一看,以为那个“2x2x2 偏移”是如下这种捆绑魔方;再转动转动它们,两者大不同!那个“偏移二阶”有如通过一种严重而有规则的畸变透镜看二阶,一个块的形状会随着转动而变形(有如一个个变形虫,或者某种气态物质,所以无法做成实物),以致有一种魔幻效果,真有意思。

不知能否对三阶魔方也来个“块畸变三阶”?










使用道具 举报

银魔

魔方思者

Rank: 7Rank: 7Rank: 7

积分
2991
帖子
1816
精华
6
UID
102191
性别
保密
兴趣爱好
理论
结构
破解

四年元老

发表于 2014-5-7 22:05:34 |显示全部楼层
乌木 发表于 2014-5-7 10:35
初一看,以为那个“2x2x2 偏移”是如下这种捆绑魔方;再转动转动它们,两者大不同!那个“偏移二阶”有如通 ...

额,这个捆绑能用吗。。。
那个要做实物我想也是可以通过像鱼竿那样的伸缩原理做的。具体实现结构没有想过。
三阶也可以做畸变的,只要改一些坐标位置(虽然说是“只要”,目前的条件下也是个累人的差事)就能做到。
我这个程序本质就是把块的所有点按一定路径运动到目标点来实现块的运动,所以很容易实现变形。

使用道具 举报

银魔

魔方思者

Rank: 7Rank: 7Rank: 7

积分
2991
帖子
1816
精华
6
UID
102191
性别
保密
兴趣爱好
理论
结构
破解

四年元老

发表于 2014-5-9 00:59:11 |显示全部楼层
hubo5563 发表于 2014-5-5 11:16
[ 本帖最后由 hubo5563 于 2014-5-5 11:53 编辑 ]

转动操作的块轮换我也是手工输入的,魔方复杂时数据很多 ...

胡老师,请教一下视角转动的问题?
我的程序之前视角只有二维转动,现在写成三维转动,具体算法是这样的:
这里Dy和Dx是鼠标移动的“速度”(两个事件间单位时间移动的距离);
camera.lat是摄像机的纬度;
camera.lon是经度;
camera.rot是摄像机绕垂直于屏幕轴转的角度。
那几个三角函数是刚算好的。
                        camera.lat+=Dy*cosRot-Dx*sinRot;
                        var Dlon=(Dx*cosRot+Dy*sinRot)/cosLat;
                        camera.lon+=Dlon;
                        camera.rot+=Dlon*sinLat;

问题在于鼠标移动的事件是一步一步的,做不到真正的微分,所以会有少量的偏差,在一些地方偏差比较大,如果拖动得太快,偏差会大得无法忍受。
我看您的魔方是没有这个问题的,请问应该如何避免这个问题呢?

使用道具 举报

Rank: 8Rank: 8

积分
6693
帖子
2430
精华
79
UID
4618
性别

论坛建设奖 十年元老

发表于 2014-5-9 11:23:01 |显示全部楼层
Fenz 发表于 2014-5-9 00:59
胡老师,请教一下视角转动的问题?
我的程序之前视角只有二维转动,现在写成三维转动,具体算法是这样的 ...

我处理的方法和你不同,鼠标拖动不改变模型的3D坐标。
我用一个矩阵记录转动积累,每次鼠标拖动计算x和y方向的转动角度,然后变换那个矩阵。
具体显示时,用当前矩阵变换模型中的点,再显示。
模型中的坐标只有转动魔方的某层时才变化,平常鼠标拖动是不变的。

使用道具 举报

Rank: 5Rank: 5

积分
3319
帖子
1842
精华
8
UID
1330033
性别
兴趣爱好
破解
DIY
巧环
其它

魔方破解达人 两年元老 四年元老 八年元老

发表于 2014-5-9 15:42:45 |显示全部楼层
奇怪的东东···········果然很奇怪

使用道具 举报

银魔

魔方思者

Rank: 7Rank: 7Rank: 7

积分
2991
帖子
1816
精华
6
UID
102191
性别
保密
兴趣爱好
理论
结构
破解

四年元老

发表于 2014-5-9 19:32:43 |显示全部楼层
hubo5563 发表于 2014-5-9 11:23
我处理的方法和你不同,鼠标拖动不改变模型的3D坐标。
我用一个矩阵记录转动积累,每次鼠标拖动计算x和y ...

其实我的也不会改变魔方的坐标,改变的是摄像机的坐标。然后再根据摄像机坐标来投影绘图。原理是一样的,区别在于算法。您用矩阵,我用的是坐标变换的微分关系。
我的算法是有问题的,所以想学习一下更好的算法。可否详细描述一下您的算法?
www.fenzland.com新做的个人站,欢迎光临

使用道具 举报

Rank: 8Rank: 8

积分
6693
帖子
2430
精华
79
UID
4618
性别

论坛建设奖 十年元老

发表于 2014-5-9 22:10:10 |显示全部楼层
本帖最后由 hubo5563 于 2014-5-9 22:20 编辑
Fenz 发表于 2014-5-9 19:32
其实我的也不会改变魔方的坐标,改变的是摄像机的坐标。然后再根据摄像机坐标来投影绘图。原理是一样的, ...


程序:
//////////////////////////////////////////////
//鼠标拖动事件处理
public void mouseDragged(MouseEvent e){
    int x = e.getX();
    int y = e.getY();
    if (pushed)
    return;
    if (dragging) {
    if(prevy>top && prevy<height+top)
    {
    if (painted) {
      painted = false;
      double xtheta = (y-prevy) * (360.0d / getSize().width);     //计算按x轴转动的角度
      double ytheta = (prevx-x) * (360.0d / getSize().height);    //计算按y轴转动的角度
      SpinX(xtheta);                //变换矩阵
      SpinY(ytheta);                //变换矩阵
      Graphics gg=getGraphics();
      xianshimq(gg);             //显示魔方
      drawButtons(gg);           //画底下的按钮
      painted = true;
       };   
     };  
     };
    prevx = x;
    prevy = y;
    e.consume();
};



        初始化矩阵
       //将坐标变换矩阵设为单位矩阵
        da11=1;        da12=0;        da13=0;
        da21=0;        da22=1;        da23=0;
        da31=0;        da32=0;        da33=1;


void  SpinX(double jiao)
{
double a11,a12,a13,a21,a22,a23,a31,a32,a33;
double sina,cosa;
sina=Math.sin( jiao*Math.PI/180);
cosa=Math.cos( jiao*Math.PI/180);
a11=da11;
a21=cosa*da21+sina*da31;
a31=-sina*da21+cosa*da31;
a12=da12;
a22=cosa*da22+sina*da32;
a32=-sina*da22+cosa*da32;
a13=da13;
a23=cosa*da23+sina*da33;
a33=-sina*da23+cosa*da33;
//给全局变量赋值
da11=a11;da12=a12;da13=a13;
da21=a21;da22=a22;da23=a23;
da31=a31;da32=a32;da33=a33;
};
//以Y轴为轴魔方整体顺时针旋转一个角度
void  SpinY(double jiao)
{

        double a11,a12,a13,a21,a22,a23,a31,a32,a33;
double sina,cosa;
sina=Math.sin( jiao*Math.PI/180);
cosa=Math.cos( jiao*Math.PI/180);
a11=cosa*da11+sina*da31;
a21=da21;
a31=-sina*da11+cosa*da31;
a12=cosa*da12+sina*da32;
a22=da22;
a32=-sina*da12+cosa*da32;
a13=cosa*da13+sina*da33;
a23=da23;
a33=-sina*da13+cosa*da33;
//给全局变量赋值
da11=a11;da12=a12;da13=a13;
da21=a21;da22=a22;da23=a23;
da31=a31;da32=a32;da33=a33;
};

//以当前旋转矩阵变换三维点,整体旋转时采用
void  dbh3(Point3d p,Point3d pp)
{
        p.x=(pp.x)*da11+(pp.y)*da12+(pp.z)*da13;
        p.y=(pp.x)*da21+(pp.y)*da22+(pp.z)*da23;
        p.z=(pp.x)*da31+(pp.y)*da32+(pp.z)*da33;
};

//将三维坐标转换为2维透视坐标,转换x坐标
int  dbh5x(Point3d p)
{
double xx,zz;int ii;
xx=p.x+xx1;
zz=p.z+zz1;
xx=xx*zz0/(zz0+zz);
xx=xx0+factor_x*xx;
ii=(int)xx;
return ii;
};
//将三维坐标转换为2维透视坐标,转换y坐标
int  dbh5y(Point3d p)
{
double yy,zz;int ii;
yy=p.y+yy1;
zz=p.z+zz1;
yy=yy*zz0/(zz0+zz);
yy=yy0-factor_y*yy;
ii=(int)yy;
return ii;
};

经过变换就是屏幕的实际坐标。

使用道具 举报

银魔

魔方思者

Rank: 7Rank: 7Rank: 7

积分
2991
帖子
1816
精华
6
UID
102191
性别
保密
兴趣爱好
理论
结构
破解

四年元老

发表于 2014-5-9 23:50:26 |显示全部楼层
本帖最后由 Fenz 于 2014-5-10 00:07 编辑
hubo5563 发表于 2014-5-9 22:10
程序:
//////////////////////////////////////////////
//鼠标拖动事件处理


多谢胡老师。我慢慢学习。
今晚我又写了另一个基于坐标变换的算法,看看是否正确可用,如果还行,就要借用您的算法了。

--------------
原来如此,我用的是通过三个表示摄像机状态的角来完成从世界坐标系到屏幕坐标的变换,相当于每次通过三角函数的计算得到变换矩阵,而您的程序则是直接储存这个变换矩阵来表示摄像机状态。

使用道具 举报

银魔

魔方思者

Rank: 7Rank: 7Rank: 7

积分
2991
帖子
1816
精华
6
UID
102191
性别
保密
兴趣爱好
理论
结构
破解

四年元老

发表于 2014-5-10 16:16:26 |显示全部楼层
hubo5563 发表于 2014-5-9 22:10
程序:
//////////////////////////////////////////////
//鼠标拖动事件处理

最后还是改用了您的方法,用矩阵表示摄像机位置和方向,这样比我原来的算法少了许多三角函数和反三角函数(以及带来的正负判断)等计算。矩阵这块看来我需要补一补。

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

Archiver|手机版|魔方吧·中文魔方俱乐部

GMT+8, 2024-3-29 03:39

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部