魔方吧·中文魔方俱乐部

 找回密码
 注册
搜索
热搜: 魔方
查看: 2832|回复: 1
打印 上一主题 下一主题

魔方模拟器twisty-sphere [复制链接]

Rank: 2

积分
301
帖子
209
精华
0
UID
1329505

四年元老 六年元老 八年元老

跳转到指定楼层
1#
发表于 2022-5-12 18:41:52 |只看该作者 |倒序浏览
本帖最后由 怀表 于 2022-5-12 23:32 编辑

https://github.com/worldmaker18349276/twisty-sphere
没有文档,我也搞不清楚是怎么自定义的。从例子看很炫酷。不过没边框很难看清块。

切割好像有两个方法sliceBySphere和sliceByPlane。不过球面切割生成魔方很慢,把resolution参数调小可提高速度。

调了半天弄出了个斜转,等明天再来试一下球面切割。
  1. cube = CSG.cube({center: [0, 0, 0], radius: [1.1, 1.1, 1.1]})
  2.   .intersect(CSG.cube({center: [ 0,-1, 0], radius: [2, 2, 2]}).setColor(1,1,1))
  3.   .intersect(CSG.cube({center: [ 0, 1, 0], radius: [2, 2, 2]}).setColor(1,1,0))
  4.   .intersect(CSG.cube({center: [-1, 0, 0], radius: [2, 2, 2]}).setColor(0,0,1))
  5.   .intersect(CSG.cube({center: [ 1, 0, 0], radius: [2, 2, 2]}).setColor(0,1,0))
  6.   .intersect(CSG.cube({center: [ 0, 0,-1], radius: [2, 2, 2]}).setColor(1,0,0))
  7.   .intersect(CSG.cube({center: [ 0, 0, 1], radius: [2, 2, 2]}).setColor(1,0.6,0.2));
  8. var puzzle = new ModeledSphPuzzle(cube);

  9. puzzle.sliceByPlane([1,1,1],0)
  10. puzzle.sliceByPlane([-1,1,1],0)
  11. puzzle.sliceByPlane([-1,-1,1],0)
  12. puzzle.sliceByPlane([-1,-1,-1],0)
  13. puzzle.sliceByPlane([-1,1,-1],0)
  14. puzzle.sliceByPlane([1,-1,1],0)
  15. puzzle.sliceByPlane([1,-1,-1],0)
  16. puzzle.sliceByPlane([1,1,-1],0)
  17. puzzle.clean();
  18. puzzle.prepare();

  19. var world = new ModeledSphPuzzleWorld(puzzle, "display");
复制代码
s1-fs8.png
  1. cube = CSG.cube({center: [0, 0, 0], radius: [1.1, 1.1, 1.1]})
  2.   .intersect(CSG.cube({center: [ 0,-1, 0], radius: [2, 2, 2]}).setColor(1,1,1))
  3.   .intersect(CSG.cube({center: [ 0, 1, 0], radius: [2, 2, 2]}).setColor(1,1,0))
  4.   .intersect(CSG.cube({center: [-1, 0, 0], radius: [2, 2, 2]}).setColor(0,0,1))
  5.   .intersect(CSG.cube({center: [ 1, 0, 0], radius: [2, 2, 2]}).setColor(0,1,0))
  6.   .intersect(CSG.cube({center: [ 0, 0,-1], radius: [2, 2, 2]}).setColor(1,0,0))
  7.   .intersect(CSG.cube({center: [ 0, 0, 1], radius: [2, 2, 2]}).setColor(1,0.6,0.2));
  8. var puzzle = new ModeledSphPuzzle(cube);


  9. puzzle.sliceByPlane([0,1,0],0)
  10. puzzle.sliceByPlane([1,0,1],0)
  11. puzzle.sliceByPlane([-1,0,1],0)
  12. puzzle.sliceByPlane([1,0,0],0)
  13. puzzle.sliceByPlane([0,0,1],0)

  14. puzzle.clean();
  15. puzzle.prepare();

  16. var world = new ModeledSphPuzzleWorld(puzzle, "display")
复制代码
s3-fs8.png
  1. var phi = (Math.sqrt(5) + 1)/2;

  2. function fzy_add(set, elem) {
  3.   set.add(fzy_snap(elem, set));
  4. }
  5. function csort(arr0) {
  6.   var arr_min = arr0.slice();
  7.   var arr_ = arr0.slice();

  8.   for ( let i=0,len=arr0.length; i<len; i++ ) {
  9.     if ( fzy_cmp(arr_, arr_min) < 0 )
  10.       arr_min = arr_.slice();
  11.     arr_.push(arr_.shift());
  12.   }
  13.   return arr_min;
  14. }

  15. var radius = (phi + 1)/Math.sqrt(phi + 2);
  16. var offset = 1;


  17. var faces = new Set();
  18. var vertices = [[1,1,1]];
  19. for ( let i=0; i<4; i++ )
  20.   vertices.push(rotate(vertices[vertices.length-1], [1/2,0,1/phi/2,phi/2]));
  21. faces.add(csort(vertices));
  22. for ( let face of faces ) {
  23.   fzy_add(faces, csort(face.map(v => rotate(v, [1/2,1/2,1/2,1/2]))));
  24.   fzy_add(faces, csort(face.map(v => rotate(v, [1/2,0,1/phi/2,phi/2]))));
  25. }

  26. var polygons = [];
  27. for ( let face of faces ) {
  28.   let polygon = new CSG.Polygon(face.map(v => new CSG.Vertex(new CSG.Vector3D(...v))));
  29.   let {x, y, z} = polygon.plane.normal;
  30.   let [r, g, b] = [x, y, z].map(v => Math.sign(v) * Math.ceil(Math.abs(v) - 0.01)).map(v => (v+1)/2);
  31.   polygon.setColor(r, g, b);
  32.   polygons.push(polygon);
  33. }
  34. var dodeca = CSG.fromPolygons(polygons);

  35. var puzzle = new ModeledSphPuzzle(dodeca, radius);

  36. puzzle.sliceByPlane([0,1,0],0)
  37. puzzle.sliceByPlane([1,0,1],0)
  38. puzzle.sliceByPlane([-1,0,1],0)
  39. puzzle.sliceByPlane([1,0,0],0)
  40. puzzle.sliceByPlane([0,0,1],0)

  41. puzzle.clean(1);
  42. puzzle.prepare();

  43. var world = new ModeledSphPuzzleWorld(puzzle, "display")
复制代码
s4-fs8.png
感觉跟胡波的正四面体切割群魔方java助手的用法有些像,不过定义多面体得手写,切割的面的法向量也得手写,调配色也很麻烦。

居然没有打乱功能。

Rank: 2

积分
301
帖子
209
精华
0
UID
1329505

四年元老 六年元老 八年元老

2#
发表于 2022-5-16 18:17:20 |只看该作者
  1. cube = CSG.cube({center: [0, 0, 0], radius: [1.1, 1.1, 1.1]})
  2.   .intersect(CSG.cube({center: [ 0,-1, 0], radius: [2, 2, 2]}).setColor(1,1,1))
  3.   .intersect(CSG.cube({center: [ 0, 1, 0], radius: [2, 2, 2]}).setColor(1,1,0))
  4.   .intersect(CSG.cube({center: [-1, 0, 0], radius: [2, 2, 2]}).setColor(0,0,1))
  5.   .intersect(CSG.cube({center: [ 1, 0, 0], radius: [2, 2, 2]}).setColor(0,1,0))
  6.   .intersect(CSG.cube({center: [ 0, 0,-1], radius: [2, 2, 2]}).setColor(1,0,0))
  7.   .intersect(CSG.cube({center: [ 0, 0, 1], radius: [2, 2, 2]}).setColor(1,0.6,0.2));
  8. var puzzle = new ModeledSphPuzzle(cube);

  9. var g = 5/3
  10. var radius = Math.sqrt(29)/3
  11. puzzle.sliceBySphere([ g, 0, g], radius)
  12. puzzle.sliceBySphere([ -g,0, g], radius)
  13. puzzle.sliceBySphere([ g,0,-g], radius)
  14. puzzle.sliceBySphere([ -g,0,-g], radius)
  15. puzzle.sliceByPlane([0,1,0],0)
  16. puzzle.sliceByPlane([1,0,1],0)
  17. puzzle.sliceByPlane([-1,0,1],0)

  18. puzzle.clean();
  19. puzzle.prepare();

  20. var world = new ModeledSphPuzzleWorld(puzzle, "display");
复制代码
s5-fs8.png

使用道具 举报

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

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

GMT+8, 2024-12-4 02:59

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部