cubing 0.20.2 → 0.21.0-pre12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -9
- package/dist/.DS_Store +0 -0
- package/dist/bin/puzzle-geometry-bin.js +1124 -1128
- package/dist/bin/puzzle-geometry-bin.js.map +3 -3
- package/dist/bundle-global/cubing.bundle-global.js +3978 -3587
- package/dist/esm/.DS_Store +0 -0
- package/dist/esm/{2x2x2.kpuzzle.json_-ZLJSYD5K.js → 2x2x2.kpuzzle.json-JOGUSQ4N.js} +3 -3
- package/dist/esm/{2x2x2.kpuzzle.json_-ZLJSYD5K.js.map → 2x2x2.kpuzzle.json-JOGUSQ4N.js.map} +1 -1
- package/dist/esm/{2x2x2.kpuzzle.svg-BNXPAM3A.js → 2x2x2.kpuzzle.svg-CQF2FTV7.js} +2 -2
- package/dist/esm/{2x2x2.kpuzzle.svg-BNXPAM3A.js.map → 2x2x2.kpuzzle.svg-CQF2FTV7.js.map} +0 -0
- package/dist/esm/3d-JZD3V366.js +39 -0
- package/dist/esm/3d-JZD3V366.js.map +7 -0
- package/dist/esm/{3x3x3-ll.kpuzzle.svg-EC42JHOH.js → 3x3x3-ll.kpuzzle.svg-53CBPG5O.js} +2 -2
- package/dist/esm/{3x3x3-ll.kpuzzle.svg-EC42JHOH.js.map → 3x3x3-ll.kpuzzle.svg-53CBPG5O.js.map} +0 -0
- package/dist/esm/{3x3x3.kpuzzle.svg-DUKG2WHC.js → 3x3x3.kpuzzle.svg-ERSSH66P.js} +2 -2
- package/dist/esm/{3x3x3.kpuzzle.svg-DUKG2WHC.js.map → 3x3x3.kpuzzle.svg-ERSSH66P.js.map} +0 -0
- package/dist/esm/alg/index.js +2 -2
- package/dist/esm/bluetooth/index.js +13 -11
- package/dist/esm/bluetooth/index.js.map +2 -2
- package/dist/esm/chunk-5DN4DAAX.js +2512 -0
- package/dist/esm/chunk-5DN4DAAX.js.map +7 -0
- package/dist/esm/{chunk-KKSDHNLH.js → chunk-7GADUDIG.js} +49 -71
- package/dist/esm/chunk-7GADUDIG.js.map +7 -0
- package/dist/esm/{chunk-YNB7QLBF.js → chunk-BU5PUJK3.js} +9 -10
- package/dist/esm/chunk-BU5PUJK3.js.map +7 -0
- package/dist/esm/chunk-CQS6JZ7G.js +762 -0
- package/dist/esm/chunk-CQS6JZ7G.js.map +7 -0
- package/dist/esm/{chunk-2GRKPQQL.js → chunk-RE7MIN5R.js} +2 -2
- package/dist/esm/{chunk-2GRKPQQL.js.map → chunk-RE7MIN5R.js.map} +0 -0
- package/dist/esm/{chunk-WJ7AVUI7.js → chunk-WO2AXYFE.js} +12 -1
- package/dist/esm/{chunk-WJ7AVUI7.js.map → chunk-WO2AXYFE.js.map} +0 -0
- package/dist/esm/{chunk-CWVB5RRW.js → chunk-YV3RT5PX.js} +625 -1282
- package/dist/esm/chunk-YV3RT5PX.js.map +7 -0
- package/dist/esm/{clock.kpuzzle.json_-PXORG6YF.js → clock.kpuzzle.json-EKWRMHJM.js} +3 -3
- package/dist/esm/{clock.kpuzzle.json_-PXORG6YF.js.map → clock.kpuzzle.json-EKWRMHJM.js.map} +1 -1
- package/dist/esm/{clock.kpuzzle.svg-E52B5OQV.js → clock.kpuzzle.svg-B7TMN3SY.js} +2 -2
- package/dist/esm/{clock.kpuzzle.svg-E52B5OQV.js.map → clock.kpuzzle.svg-B7TMN3SY.js.map} +0 -0
- package/dist/esm/esm-test-worker.js +2 -2
- package/dist/esm/esm-test-worker.js.map +1 -1
- package/dist/esm/kpuzzle/index.js +5 -3
- package/dist/esm/{node-SIGYKAZG.js → node-BSAQKO3G.js} +2 -2
- package/dist/esm/{node-SIGYKAZG.js.map → node-BSAQKO3G.js.map} +0 -0
- package/dist/esm/{node-BHGOVUN3.js → node-WEHVBEKP.js} +2 -2
- package/dist/esm/{node-BHGOVUN3.js.map → node-WEHVBEKP.js.map} +0 -0
- package/dist/esm/notation/index.js +3 -3
- package/dist/esm/protocol/index.js +3 -3
- package/dist/esm/puzzle-geometry/index.js +1085 -1179
- package/dist/esm/puzzle-geometry/index.js.map +3 -3
- package/dist/esm/puzzles/index.js +10 -4
- package/dist/esm/{pyraminx.kpuzzle.svg-QKUJX37T.js → pyraminx.kpuzzle.svg-QBBMZVDY.js} +2 -2
- package/dist/esm/{pyraminx.kpuzzle.svg-QKUJX37T.js.map → pyraminx.kpuzzle.svg-QBBMZVDY.js.map} +0 -0
- package/dist/esm/scramble/index.js +5 -4
- package/dist/esm/search/index.js +7 -4
- package/dist/esm/{sq1-hyperorbit.kpuzzle.json_-7KW5LSXC.js → sq1-hyperorbit.kpuzzle.json-N3FGCPML.js} +3 -3
- package/dist/esm/{sq1-hyperorbit.kpuzzle.json_-7KW5LSXC.js.map → sq1-hyperorbit.kpuzzle.json-N3FGCPML.js.map} +1 -1
- package/dist/esm/{sq1-hyperorbit.kpuzzle.svg-7Y7N37NN.js → sq1-hyperorbit.kpuzzle.svg-ID57EER7.js} +2 -2
- package/dist/esm/{sq1-hyperorbit.kpuzzle.svg-7Y7N37NN.js.map → sq1-hyperorbit.kpuzzle.svg-ID57EER7.js.map} +0 -0
- package/dist/esm/stream/index.js +3 -3
- package/dist/esm/stream/index.js.map +2 -2
- package/dist/esm/twisty/index.js +4442 -3214
- package/dist/esm/twisty/index.js.map +3 -3
- package/dist/esm/worker-inside-generated-string-KDZOUGJF.js +2831 -0
- package/dist/esm/worker-inside-generated-string-KDZOUGJF.js.map +7 -0
- package/dist/types/alg/Alg.d.ts +88 -0
- package/dist/types/alg/Alg.d.ts.map +1 -1
- package/dist/types/alg/Alg.spec.d.ts +2 -0
- package/dist/types/alg/Alg.spec.d.ts.map +1 -0
- package/dist/types/alg/common.d.ts.map +1 -1
- package/dist/types/alg/operation.spec.d.ts +2 -0
- package/dist/types/alg/operation.spec.d.ts.map +1 -0
- package/dist/types/alg/parse.spec.d.ts +2 -0
- package/dist/types/alg/parse.spec.d.ts.map +1 -0
- package/dist/types/alg/test/alg-comparison.d.ts.map +1 -1
- package/dist/types/alg/test/alg.spec.d.ts +2 -0
- package/dist/types/alg/test/alg.spec.d.ts.map +1 -0
- package/dist/types/alg/units/leaves/LineComment.spec.d.ts +2 -0
- package/dist/types/alg/units/leaves/LineComment.spec.d.ts.map +1 -0
- package/dist/types/alg/units/leaves/Move.spec.d.ts +2 -0
- package/dist/types/alg/units/leaves/Move.spec.d.ts.map +1 -0
- package/dist/types/alg/url.spec.d.ts +2 -0
- package/dist/types/alg/url.spec.d.ts.map +1 -0
- package/dist/types/bluetooth/smart-puzzle/bluetooth-puzzle.d.ts +1 -1
- package/dist/types/bluetooth/smart-puzzle/bluetooth-puzzle.d.ts.map +1 -1
- package/dist/types/bluetooth/smart-puzzle/giiker.spec.d.ts +5 -0
- package/dist/types/bluetooth/smart-puzzle/giiker.spec.d.ts.map +1 -0
- package/dist/types/kpuzzle/3x3x3/3x3x3.kpuzzle.json.d.ts +3 -0
- package/dist/types/kpuzzle/3x3x3/3x3x3.kpuzzle.json.d.ts.map +1 -0
- package/dist/types/kpuzzle/3x3x3/3x3x3.kpuzzle.json.spec.d.ts +2 -0
- package/dist/types/kpuzzle/3x3x3/3x3x3.kpuzzle.json.spec.d.ts.map +1 -0
- package/dist/types/kpuzzle/canon.spec.d.ts +2 -0
- package/dist/types/kpuzzle/canon.spec.d.ts.map +1 -0
- package/dist/types/kpuzzle/index.d.ts +1 -0
- package/dist/types/kpuzzle/index.d.ts.map +1 -1
- package/dist/types/kpuzzle/kpuzzle.spec.d.ts +2 -0
- package/dist/types/kpuzzle/kpuzzle.spec.d.ts.map +1 -0
- package/dist/types/kpuzzle/prunetable.spec.d.ts +2 -0
- package/dist/types/kpuzzle/prunetable.spec.d.ts.map +1 -0
- package/dist/types/kpuzzle/svg.d.ts.map +1 -1
- package/dist/types/kpuzzle/transformations.spec.d.ts +2 -0
- package/dist/types/kpuzzle/transformations.spec.d.ts.map +1 -0
- package/dist/types/protocol/binary/binary3x3x3.spec.d.ts +2 -0
- package/dist/types/protocol/binary/binary3x3x3.spec.d.ts.map +1 -0
- package/dist/types/protocol/binary/hex.spec.d.ts +2 -0
- package/dist/types/protocol/binary/hex.spec.d.ts.map +1 -0
- package/dist/types/protocol/binary/orbit-indexing.spec.d.ts +2 -0
- package/dist/types/protocol/binary/orbit-indexing.spec.d.ts.map +1 -0
- package/dist/types/puzzle-geometry/Options.d.ts +45 -1
- package/dist/types/puzzle-geometry/Options.d.ts.map +1 -1
- package/dist/types/puzzle-geometry/PGPuzzles.spec.d.ts +2 -0
- package/dist/types/puzzle-geometry/PGPuzzles.spec.d.ts.map +1 -0
- package/dist/types/puzzle-geometry/PermOriSet.d.ts +39 -39
- package/dist/types/puzzle-geometry/PermOriSet.d.ts.map +1 -1
- package/dist/types/puzzle-geometry/PuzzleGeometry.d.ts +118 -110
- package/dist/types/puzzle-geometry/PuzzleGeometry.d.ts.map +1 -1
- package/dist/types/puzzle-geometry/Quat.d.ts +0 -11
- package/dist/types/puzzle-geometry/Quat.d.ts.map +1 -1
- package/dist/types/puzzle-geometry/Quat.spec.d.ts +2 -0
- package/dist/types/puzzle-geometry/Quat.spec.d.ts.map +1 -0
- package/dist/types/puzzle-geometry/SchreierSims.d.ts.map +1 -1
- package/dist/types/puzzle-geometry/index.d.ts +2 -4
- package/dist/types/puzzle-geometry/index.d.ts.map +1 -1
- package/dist/types/puzzle-geometry/interfaces.d.ts +1 -21
- package/dist/types/puzzle-geometry/interfaces.d.ts.map +1 -1
- package/dist/types/puzzle-geometry/orientcenters.spec.d.ts +2 -0
- package/dist/types/puzzle-geometry/orientcenters.spec.d.ts.map +1 -0
- package/dist/types/puzzles/async/async-pg3d.d.ts.map +1 -1
- package/dist/types/puzzles/customPGPuzzleLoader.d.ts +12 -0
- package/dist/types/puzzles/customPGPuzzleLoader.d.ts.map +1 -0
- package/dist/types/puzzles/implementations/2x2x2/{2x2x2.kpuzzle.json_.d.ts → 2x2x2.kpuzzle.json.d.ts} +1 -1
- package/dist/types/puzzles/implementations/2x2x2/2x2x2.kpuzzle.json.d.ts.map +1 -0
- package/dist/types/puzzles/implementations/3x3x3/index.d.ts.map +1 -1
- package/dist/types/puzzles/implementations/clock/{clock.kpuzzle.json_.d.ts → clock.kpuzzle.json.d.ts} +1 -1
- package/dist/types/puzzles/implementations/clock/clock.kpuzzle.json.d.ts.map +1 -0
- package/dist/types/puzzles/implementations/fto/index.d.ts +2 -2
- package/dist/types/puzzles/implementations/fto/index.d.ts.map +1 -1
- package/dist/types/puzzles/implementations/pyraminx/{pyraminx.kpuzzle.json_.d.ts → pyraminx.kpuzzle.json.d.ts} +1 -1
- package/dist/types/puzzles/implementations/pyraminx/pyraminx.kpuzzle.json.d.ts.map +1 -0
- package/dist/types/puzzles/implementations/square1/index.d.ts.map +1 -1
- package/dist/types/puzzles/implementations/square1/{sq1-hyperorbit.kpuzzle.json_.d.ts → sq1-hyperorbit.kpuzzle.json.d.ts} +1 -1
- package/dist/types/puzzles/implementations/square1/sq1-hyperorbit.kpuzzle.json.d.ts.map +1 -0
- package/dist/types/puzzles/index.d.ts +4 -2
- package/dist/types/puzzles/index.d.ts.map +1 -1
- package/dist/types/puzzles/stickerings/appearance.d.ts +9 -9
- package/dist/types/puzzles/stickerings/appearance.d.ts.map +1 -1
- package/dist/types/puzzles/stickerings/cube-stickerings.d.ts.map +1 -1
- package/dist/types/puzzles/stickerings/fto-stickerings.d.ts.map +1 -1
- package/dist/types/puzzles/stickerings/global-custom-stickering-hack.d.ts +3 -0
- package/dist/types/puzzles/stickerings/global-custom-stickering-hack.d.ts.map +1 -0
- package/dist/types/search/index.d.ts +1 -1
- package/dist/types/search/index.d.ts.map +1 -1
- package/dist/types/search/inside/api.d.ts +2 -1
- package/dist/types/search/inside/api.d.ts.map +1 -1
- package/dist/types/search/inside/api.spec.d.ts +2 -0
- package/dist/types/search/inside/api.spec.d.ts.map +1 -0
- package/dist/types/search/inside/solve/parseSGS.d.ts.map +1 -1
- package/dist/types/search/inside/solve/puzzles/3x3x3/filter.d.ts.map +1 -1
- package/dist/types/search/inside/solve/puzzles/3x3x3/index.d.ts.map +1 -1
- package/dist/types/search/inside/solve/puzzles/megaminx.sgs.json.d.ts.map +1 -1
- package/dist/types/search/inside/solve/puzzles/sgs-defs.spec.d.ts +2 -0
- package/dist/types/search/inside/solve/puzzles/sgs-defs.spec.d.ts.map +1 -0
- package/dist/types/search/inside/solve/puzzles/skewb.sgs.json.d.ts.map +1 -1
- package/dist/types/search/inside/solve/tremble.d.ts.map +1 -1
- package/dist/types/search/inside/solve/vendor/cstimer/src/js/lib/mathlib.d.ts +4 -31
- package/dist/types/search/inside/solve/vendor/cstimer/src/js/lib/mathlib.d.ts.map +1 -1
- package/dist/types/search/inside/solve/vendor/cstimer/src/js/scramble/scramble_444.d.ts.map +1 -1
- package/dist/types/search/inside/solve/vendor/min2phase/gwt.d.ts +3 -0
- package/dist/types/search/inside/solve/vendor/min2phase/gwt.d.ts.map +1 -0
- package/dist/types/search/inside/solve/vendor/random-uint-below/get-random-values.d.ts.map +1 -1
- package/dist/types/search/inside/solve/vendor/random-uint-below/random-int.d.ts.map +1 -1
- package/dist/types/search/inside/solve/vendor/sq12phase/scramble_sq1.d.ts.map +1 -1
- package/dist/types/search/instantiator.d.ts.map +1 -1
- package/dist/types/search/outside.d.ts +4 -2
- package/dist/types/search/outside.d.ts.map +1 -1
- package/dist/types/search/worker-inside-generated-string.d.ts +1 -1
- package/dist/types/search/worker-inside-generated-string.d.ts.map +1 -1
- package/dist/types/stream/twizzle/TwizzleStream.d.ts +9 -8
- package/dist/types/stream/twizzle/TwizzleStream.d.ts.map +1 -1
- package/dist/types/stream/websocket-proxy.d.ts +1 -1
- package/dist/types/stream/websocket-proxy.d.ts.map +1 -1
- package/dist/types/twisty/controllers/TwistyAnimationController.d.ts +34 -0
- package/dist/types/twisty/controllers/TwistyAnimationController.d.ts.map +1 -0
- package/dist/types/twisty/controllers/TwistyPlayerController.d.ts +16 -0
- package/dist/types/twisty/controllers/TwistyPlayerController.d.ts.map +1 -0
- package/dist/types/twisty/heavy-code-imports/3d.d.ts +3 -0
- package/dist/types/twisty/heavy-code-imports/3d.d.ts.map +1 -0
- package/dist/types/twisty/heavy-code-imports/dynamic-entries/3d.d.ts +12 -0
- package/dist/types/twisty/heavy-code-imports/dynamic-entries/3d.d.ts.map +1 -0
- package/dist/types/twisty/index.d.ts +20 -15
- package/dist/types/twisty/index.d.ts.map +1 -1
- package/dist/types/twisty/model/PromiseFreshener.d.ts +14 -0
- package/dist/types/twisty/model/PromiseFreshener.d.ts.map +1 -0
- package/dist/types/twisty/model/TwistyPlayerModel.d.ts +84 -0
- package/dist/types/twisty/model/TwistyPlayerModel.d.ts.map +1 -0
- package/dist/types/twisty/model/UserVisibleErrorTracker.d.ts +11 -0
- package/dist/types/twisty/model/UserVisibleErrorTracker.d.ts.map +1 -0
- package/dist/types/twisty/model/helpers.d.ts +5 -0
- package/dist/types/twisty/model/helpers.d.ts.map +1 -0
- package/dist/types/twisty/model/props/TwistyProp.d.ts +60 -0
- package/dist/types/twisty/model/props/TwistyProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/TwistyProp.spec.d.ts +5 -0
- package/dist/types/twisty/model/props/TwistyProp.spec.d.ts.map +1 -0
- package/dist/types/twisty/model/props/TwistyPropDebugger.d.ts +28 -0
- package/dist/types/twisty/model/props/TwistyPropDebugger.d.ts.map +1 -0
- package/dist/types/twisty/model/props/general/URLProp.d.ts +6 -0
- package/dist/types/twisty/model/props/general/URLProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/display/HintFaceletProp.d.ts +7 -0
- package/dist/types/twisty/model/props/puzzle/display/HintFaceletProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/display/SpriteProp.d.ts +10 -0
- package/dist/types/twisty/model/props/puzzle/display/SpriteProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/display/StickeringProp.d.ts +6 -0
- package/dist/types/twisty/model/props/puzzle/display/StickeringProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/state/AlgProp.d.ts +27 -0
- package/dist/types/twisty/model/props/puzzle/state/AlgProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/state/AlgTransformationProp.d.ts +14 -0
- package/dist/types/twisty/model/props/puzzle/state/AlgTransformationProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/state/AnchoredStartProp.d.ts +15 -0
- package/dist/types/twisty/model/props/puzzle/state/AnchoredStartProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/state/CurrentLeavesProp.d.ts +12 -0
- package/dist/types/twisty/model/props/puzzle/state/CurrentLeavesProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/state/CurrentLeavesSimplified.d.ts +17 -0
- package/dist/types/twisty/model/props/puzzle/state/CurrentLeavesSimplified.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/state/CurrentTransformationProp.d.ts +15 -0
- package/dist/types/twisty/model/props/puzzle/state/CurrentTransformationProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/state/IndexerConstructorProp.d.ts +17 -0
- package/dist/types/twisty/model/props/puzzle/state/IndexerConstructorProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/state/IndexerConstructorRequestProp.d.ts +12 -0
- package/dist/types/twisty/model/props/puzzle/state/IndexerConstructorRequestProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/state/IndexerProp.d.ts +15 -0
- package/dist/types/twisty/model/props/puzzle/state/IndexerProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/state/LegacyPositionProp.d.ts +12 -0
- package/dist/types/twisty/model/props/puzzle/state/LegacyPositionProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/state/PuzzleAlgProp.d.ts +13 -0
- package/dist/types/twisty/model/props/puzzle/state/PuzzleAlgProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/state/SetupAnchorProp.d.ts +6 -0
- package/dist/types/twisty/model/props/puzzle/state/SetupAnchorProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/structure/PuzzleDefProp.d.ts +11 -0
- package/dist/types/twisty/model/props/puzzle/structure/PuzzleDefProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/structure/PuzzleDescriptionProp.d.ts +6 -0
- package/dist/types/twisty/model/props/puzzle/structure/PuzzleDescriptionProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/structure/PuzzleIDProp.d.ts +11 -0
- package/dist/types/twisty/model/props/puzzle/structure/PuzzleIDProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/structure/PuzzleIDRequestProp.d.ts +6 -0
- package/dist/types/twisty/model/props/puzzle/structure/PuzzleIDRequestProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/puzzle/structure/PuzzleLoaderProp.d.ts +13 -0
- package/dist/types/twisty/model/props/puzzle/structure/PuzzleLoaderProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/timeline/CoarseTimelineInfoProp.d.ts +25 -0
- package/dist/types/twisty/model/props/timeline/CoarseTimelineInfoProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/timeline/DetailedTimelineInfoProp.d.ts +23 -0
- package/dist/types/twisty/model/props/timeline/DetailedTimelineInfoProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/timeline/PlayingInfoProp.d.ts +15 -0
- package/dist/types/twisty/model/props/timeline/PlayingInfoProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/timeline/TempoScaleProp.d.ts +6 -0
- package/dist/types/twisty/model/props/timeline/TempoScaleProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/timeline/TimestampRequestProp.d.ts +16 -0
- package/dist/types/twisty/model/props/timeline/TimestampRequestProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/viewer/BackViewProp.d.ts +7 -0
- package/dist/types/twisty/model/props/viewer/BackViewProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/viewer/BackgroundProp.d.ts +7 -0
- package/dist/types/twisty/model/props/viewer/BackgroundProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/viewer/ButtonAppearanceProp.d.ts +22 -0
- package/dist/types/twisty/model/props/viewer/ButtonAppearanceProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/viewer/ControlPanelProp.d.ts +7 -0
- package/dist/types/twisty/model/props/viewer/ControlPanelProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/viewer/LatitudeLimit.d.ts +6 -0
- package/dist/types/twisty/model/props/viewer/LatitudeLimit.d.ts.map +1 -0
- package/dist/types/twisty/model/props/viewer/OrbitCoordinatesProp.d.ts +16 -0
- package/dist/types/twisty/model/props/viewer/OrbitCoordinatesProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/viewer/OrbitCoordinatesRequestProp.d.ts +15 -0
- package/dist/types/twisty/model/props/viewer/OrbitCoordinatesRequestProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/viewer/TimeRangeProp.d.ts +11 -0
- package/dist/types/twisty/model/props/viewer/TimeRangeProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/viewer/ViewerLinkProp.d.ts +7 -0
- package/dist/types/twisty/model/props/viewer/ViewerLinkProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/viewer/VisualizationProp.d.ts +7 -0
- package/dist/types/twisty/model/props/viewer/VisualizationProp.d.ts.map +1 -0
- package/dist/types/twisty/model/props/viewer/VisualizationStrategyProp.d.ts +13 -0
- package/dist/types/twisty/model/props/viewer/VisualizationStrategyProp.d.ts.map +1 -0
- package/dist/types/twisty/{animation → old/animation}/RenderScheduler.d.ts +3 -0
- package/dist/types/twisty/old/animation/RenderScheduler.d.ts.map +1 -0
- package/dist/types/twisty/{animation → old/animation}/Timeline.d.ts +0 -0
- package/dist/types/twisty/old/animation/Timeline.d.ts.map +1 -0
- package/dist/types/twisty/{animation → old/animation}/cursor/AlgCursor.d.ts +4 -4
- package/dist/types/twisty/old/animation/cursor/AlgCursor.d.ts.map +1 -0
- package/dist/types/twisty/{animation → old/animation}/cursor/CursorTypes.d.ts +4 -4
- package/dist/types/twisty/old/animation/cursor/CursorTypes.d.ts.map +1 -0
- package/dist/types/twisty/{animation → old/animation}/easing.d.ts +0 -0
- package/dist/types/twisty/old/animation/easing.d.ts.map +1 -0
- package/dist/types/twisty/{animation → old/animation}/indexer/AlgDuration.d.ts +1 -1
- package/dist/types/twisty/old/animation/indexer/AlgDuration.d.ts.map +1 -0
- package/dist/types/twisty/old/animation/indexer/AlgIndexer.d.ts +36 -0
- package/dist/types/twisty/old/animation/indexer/AlgIndexer.d.ts.map +1 -0
- package/dist/types/twisty/{animation → old/animation}/indexer/SimpleAlgIndexer.d.ts +3 -3
- package/dist/types/twisty/old/animation/indexer/SimpleAlgIndexer.d.ts.map +1 -0
- package/dist/types/twisty/{animation → old/animation}/indexer/simultaneous-moves/SimultaneousMoveIndexer.d.ts +6 -5
- package/dist/types/twisty/old/animation/indexer/simultaneous-moves/SimultaneousMoveIndexer.d.ts.map +1 -0
- package/dist/types/twisty/old/animation/indexer/simultaneous-moves/SimultaneousMoveIndexerV2.d.ts +22 -0
- package/dist/types/twisty/old/animation/indexer/simultaneous-moves/SimultaneousMoveIndexerV2.d.ts.map +1 -0
- package/dist/types/twisty/old/animation/indexer/simultaneous-moves/simul-moves.d.ts +26 -0
- package/dist/types/twisty/old/animation/indexer/simultaneous-moves/simul-moves.d.ts.map +1 -0
- package/dist/types/twisty/{animation → old/animation}/indexer/tree/AlgWalker.d.ts +2 -2
- package/dist/types/twisty/old/animation/indexer/tree/AlgWalker.d.ts.map +1 -0
- package/dist/types/twisty/{animation → old/animation}/indexer/tree/TreeAlgIndexer.d.ts +3 -3
- package/dist/types/twisty/old/animation/indexer/tree/TreeAlgIndexer.d.ts.map +1 -0
- package/dist/types/twisty/old/animation/indexer/tree/chunkAlgs.d.ts +3 -0
- package/dist/types/twisty/old/animation/indexer/tree/chunkAlgs.d.ts.map +1 -0
- package/dist/types/twisty/{animation → old/animation}/stream/timeline-move-calculation-draft.d.ts +1 -1
- package/dist/types/twisty/old/animation/stream/timeline-move-calculation-draft.d.ts.map +1 -0
- package/dist/types/twisty/{dom/TwistyAlgViewer.css_.d.ts → old/dom/TwistyAlgViewerV1.css.d.ts} +1 -1
- package/dist/types/twisty/old/dom/TwistyAlgViewerV1.css.d.ts.map +1 -0
- package/dist/types/twisty/old/dom/TwistyAlgViewerV1.d.ts +52 -0
- package/dist/types/twisty/old/dom/TwistyAlgViewerV1.d.ts.map +1 -0
- package/dist/types/twisty/{dom/TwistyPlayer.css_.d.ts → old/dom/TwistyPlayer.css.d.ts} +1 -1
- package/dist/types/twisty/old/dom/TwistyPlayer.css.d.ts.map +1 -0
- package/dist/types/twisty/{dom → old/dom}/TwistyPlayer.d.ts +8 -8
- package/dist/types/twisty/old/dom/TwistyPlayer.d.ts.map +1 -0
- package/dist/types/twisty/old/dom/TwistyPlayer.spec.d.ts +5 -0
- package/dist/types/twisty/old/dom/TwistyPlayer.spec.d.ts.map +1 -0
- package/dist/types/twisty/{dom → old/dom}/TwistyPlayerConfig.d.ts +10 -5
- package/dist/types/twisty/old/dom/TwistyPlayerConfig.d.ts.map +1 -0
- package/dist/types/twisty/old/dom/controls/TwistyControlElement.d.ts +2 -0
- package/dist/types/twisty/old/dom/controls/TwistyControlElement.d.ts.map +1 -0
- package/dist/types/twisty/{dom/controls/TwistyScrubber.css_.d.ts → old/dom/controls/TwistyScrubber.css.d.ts} +1 -1
- package/dist/types/twisty/old/dom/controls/TwistyScrubber.css.d.ts.map +1 -0
- package/dist/types/twisty/{dom → old/dom}/controls/TwistyScrubber.d.ts +1 -1
- package/dist/types/twisty/old/dom/controls/TwistyScrubber.d.ts.map +1 -0
- package/dist/types/twisty/{dom/controls/buttons.css_.d.ts → old/dom/controls/buttons.css.d.ts} +1 -1
- package/dist/types/twisty/old/dom/controls/buttons.css.d.ts.map +1 -0
- package/dist/types/twisty/{dom → old/dom}/controls/buttons.d.ts +1 -1
- package/dist/types/twisty/old/dom/controls/buttons.d.ts.map +1 -0
- package/dist/types/twisty/old/dom/controls/buttons.spec.d.ts +5 -0
- package/dist/types/twisty/old/dom/controls/buttons.spec.d.ts.map +1 -0
- package/dist/types/twisty/{dom → old/dom}/element/ClassListManager.d.ts +0 -0
- package/dist/types/twisty/old/dom/element/ClassListManager.d.ts.map +1 -0
- package/dist/types/twisty/{dom → old/dom}/element/ElementConfig.d.ts +1 -1
- package/dist/types/twisty/old/dom/element/ElementConfig.d.ts.map +1 -0
- package/dist/types/twisty/{dom → old/dom}/element/ManagedCustomElement.d.ts +0 -0
- package/dist/types/twisty/old/dom/element/ManagedCustomElement.d.ts.map +1 -0
- package/dist/types/twisty/{dom → old/dom}/element/node-custom-element-shims.d.ts +0 -0
- package/dist/types/twisty/old/dom/element/node-custom-element-shims.d.ts.map +1 -0
- package/dist/types/twisty/{dom/stream/TwistyStreamSource.css_.d.ts → old/dom/stream/TwistyStreamSource.css.d.ts} +1 -1
- package/dist/types/twisty/old/dom/stream/TwistyStreamSource.css.d.ts.map +1 -0
- package/dist/types/twisty/{dom → old/dom}/stream/TwistyStreamSource.d.ts +0 -0
- package/dist/types/twisty/old/dom/stream/TwistyStreamSource.d.ts.map +1 -0
- package/dist/types/twisty/{dom → old/dom}/viewers/Twisty2DSVG.d.ts +2 -2
- package/dist/types/twisty/old/dom/viewers/Twisty2DSVG.d.ts.map +1 -0
- package/dist/types/twisty/{dom/viewers/Twisty2DSVGView.css_.d.ts → old/dom/viewers/Twisty2DSVGView.css.d.ts} +1 -1
- package/dist/types/twisty/old/dom/viewers/Twisty2DSVGView.css.d.ts.map +1 -0
- package/dist/types/twisty/{dom/viewers/Twisty3DCanvas.css_.d.ts → old/dom/viewers/Twisty3DCanvas.css.d.ts} +1 -1
- package/dist/types/twisty/old/dom/viewers/Twisty3DCanvas.css.d.ts.map +1 -0
- package/dist/types/twisty/{dom → old/dom}/viewers/Twisty3DCanvas.d.ts +1 -2
- package/dist/types/twisty/old/dom/viewers/Twisty3DCanvas.d.ts.map +1 -0
- package/dist/types/twisty/{dom → old/dom}/viewers/TwistyOrbitControls.d.ts +0 -0
- package/dist/types/twisty/old/dom/viewers/TwistyOrbitControls.d.ts.map +1 -0
- package/dist/types/twisty/old/dom/viewers/TwistyViewerElement.d.ts +4 -0
- package/dist/types/twisty/old/dom/viewers/TwistyViewerElement.d.ts.map +1 -0
- package/dist/types/twisty/{dom/viewers/TwistyViewerWrapper.css_.d.ts → old/dom/viewers/TwistyViewerWrapper.css.d.ts} +1 -1
- package/dist/types/twisty/old/dom/viewers/TwistyViewerWrapper.css.d.ts.map +1 -0
- package/dist/types/twisty/{dom → old/dom}/viewers/TwistyViewerWrapper.d.ts +0 -0
- package/dist/types/twisty/old/dom/viewers/TwistyViewerWrapper.d.ts.map +1 -0
- package/dist/types/twisty/old/dom/viewers/canvas.d.ts +3 -0
- package/dist/types/twisty/old/dom/viewers/canvas.d.ts.map +1 -0
- package/dist/types/twisty/views/2D/Twisty2DPuzzle.d.ts +29 -0
- package/dist/types/twisty/views/2D/Twisty2DPuzzle.d.ts.map +1 -0
- package/dist/types/twisty/views/2D/Twisty2DPuzzleWrapper.d.ts +16 -0
- package/dist/types/twisty/views/2D/Twisty2DPuzzleWrapper.d.ts.map +1 -0
- package/dist/types/twisty/views/2D/Twisty2DSceneWrapper.d.ts +20 -0
- package/dist/types/twisty/views/2D/Twisty2DSceneWrapper.d.ts.map +1 -0
- package/dist/types/twisty/views/3D/RendererPool.d.ts +4 -0
- package/dist/types/twisty/views/3D/RendererPool.d.ts.map +1 -0
- package/dist/types/twisty/{3D → views/3D}/TAU.d.ts +0 -0
- package/dist/types/twisty/views/3D/TAU.d.ts.map +1 -0
- package/dist/types/twisty/views/3D/Twisty3DPuzzleWrapper.d.ts +17 -0
- package/dist/types/twisty/views/3D/Twisty3DPuzzleWrapper.d.ts.map +1 -0
- package/dist/types/twisty/{3D → views/3D}/Twisty3DRenderTarget.d.ts +0 -0
- package/dist/types/twisty/views/3D/Twisty3DRenderTarget.d.ts.map +1 -0
- package/dist/types/twisty/{3D → views/3D}/Twisty3DScene.d.ts +0 -0
- package/dist/types/twisty/views/3D/Twisty3DScene.d.ts.map +1 -0
- package/dist/types/twisty/views/3D/Twisty3DSceneWrapper.d.ts +28 -0
- package/dist/types/twisty/views/3D/Twisty3DSceneWrapper.d.ts.map +1 -0
- package/dist/types/twisty/views/3D/Twisty3DVantage.d.ts +32 -0
- package/dist/types/twisty/views/3D/Twisty3DVantage.d.ts.map +1 -0
- package/dist/types/twisty/views/3D/TwistyOrbitControlsV2.d.ts +41 -0
- package/dist/types/twisty/views/3D/TwistyOrbitControlsV2.d.ts.map +1 -0
- package/dist/types/twisty/views/3D/TwistyOrbitControlsV2.spec.d.ts +5 -0
- package/dist/types/twisty/views/3D/TwistyOrbitControlsV2.spec.d.ts.map +1 -0
- package/dist/types/twisty/{3D → views/3D}/puzzles/Cube3D.d.ts +11 -7
- package/dist/types/twisty/views/3D/puzzles/Cube3D.d.ts.map +1 -0
- package/dist/types/twisty/{3D → views/3D}/puzzles/KPuzzleWrapper.d.ts +2 -2
- package/dist/types/twisty/views/3D/puzzles/KPuzzleWrapper.d.ts.map +1 -0
- package/dist/types/twisty/views/3D/puzzles/PG3D.d.ts +57 -0
- package/dist/types/twisty/views/3D/puzzles/PG3D.d.ts.map +1 -0
- package/dist/types/twisty/{3D → views/3D}/puzzles/Twisty3DPuzzle.d.ts +1 -1
- package/dist/types/twisty/views/3D/puzzles/Twisty3DPuzzle.d.ts.map +1 -0
- package/dist/types/twisty/{3D → views/3D}/puzzles/TwistyTestBox.d.ts +2 -2
- package/dist/types/twisty/views/3D/puzzles/TwistyTestBox.d.ts.map +1 -0
- package/dist/types/twisty/views/TwistyAlgEditor/LeafTokens.d.ts +18 -0
- package/dist/types/twisty/views/TwistyAlgEditor/LeafTokens.d.ts.map +1 -0
- package/dist/types/twisty/views/TwistyAlgEditor/TwistyAlgEditor.css.d.ts +3 -0
- package/dist/types/twisty/views/TwistyAlgEditor/TwistyAlgEditor.css.d.ts.map +1 -0
- package/dist/types/twisty/views/TwistyAlgEditor/TwistyAlgEditor.d.ts +40 -0
- package/dist/types/twisty/views/TwistyAlgEditor/TwistyAlgEditor.d.ts.map +1 -0
- package/dist/types/twisty/views/TwistyAlgEditor/TwistyAlgEditor.spec.d.ts +5 -0
- package/dist/types/twisty/views/TwistyAlgEditor/TwistyAlgEditor.spec.d.ts.map +1 -0
- package/dist/types/twisty/views/TwistyAlgEditor/model.d.ts +61 -0
- package/dist/types/twisty/views/TwistyAlgEditor/model.d.ts.map +1 -0
- package/dist/types/twisty/views/TwistyAlgViewer.css.d.ts +3 -0
- package/dist/types/twisty/views/TwistyAlgViewer.css.d.ts.map +1 -0
- package/dist/types/twisty/{dom → views}/TwistyAlgViewer.d.ts +6 -6
- package/dist/types/twisty/views/TwistyAlgViewer.d.ts.map +1 -0
- package/dist/types/twisty/views/TwistyPlayer.d.ts +97 -0
- package/dist/types/twisty/views/TwistyPlayer.d.ts.map +1 -0
- package/dist/types/twisty/views/TwistyPlayerSettable.d.ts +71 -0
- package/dist/types/twisty/views/TwistyPlayerSettable.d.ts.map +1 -0
- package/dist/types/twisty/views/control-panel/TwistyButtonsV2.d.ts +33 -0
- package/dist/types/twisty/views/control-panel/TwistyButtonsV2.d.ts.map +1 -0
- package/dist/types/twisty/views/control-panel/TwistyScrubberV2.d.ts +14 -0
- package/dist/types/twisty/views/control-panel/TwistyScrubberV2.d.ts.map +1 -0
- package/dist/types/twisty/views/control-panel/webkit-fullscreen.d.ts +15 -0
- package/dist/types/twisty/views/control-panel/webkit-fullscreen.d.ts.map +1 -0
- package/dist/types/twisty/views/document.d.ts +2 -0
- package/dist/types/twisty/views/document.d.ts.map +1 -0
- package/dist/types/twisty/views/screenshot.d.ts +12 -0
- package/dist/types/twisty/views/screenshot.d.ts.map +1 -0
- package/dist/types/vendor/p-lazy/p-lazy.d.ts +10 -0
- package/dist/types/vendor/p-lazy/p-lazy.d.ts.map +1 -0
- package/dist/types/vendor/three/examples/jsm/libs/stats.modified.module.d.ts +33 -0
- package/dist/types/vendor/three/examples/jsm/libs/stats.modified.module.d.ts.map +1 -0
- package/docs/.DS_Store +0 -0
- package/docs/cubing/.DS_Store +0 -0
- package/docs/cubing/alg/index.html +37 -23
- package/docs/cubing/index.html +56 -252
- package/docs/cubing/scramble/index.html +122 -0
- package/docs/cubing/twisty/index.html +329 -0
- package/docs/main.css +15 -3
- package/package.json +83 -57
- package/src/cubing/.DS_Store +0 -0
- package/src/cubing/alg/.DS_Store +0 -0
- package/src/cubing/alg/Alg.ts +89 -0
- package/src/cubing/alg/common.ts +4 -2
- package/src/cubing/alg/iteration.ts +1 -1
- package/src/cubing/alg/parse.ts +2 -0
- package/src/cubing/alg/test/alg-comparison.ts +1 -0
- package/src/cubing/alg/units/.DS_Store +0 -0
- package/src/cubing/alg/units/Unit.ts +0 -3
- package/src/cubing/alg/units/containers/Commutator.ts +1 -1
- package/src/cubing/alg/units/leaves/Move.ts +4 -4
- package/src/cubing/bluetooth/.DS_Store +0 -0
- package/src/cubing/bluetooth/connect/index.ts +1 -1
- package/src/cubing/bluetooth/smart-puzzle/Heykube.ts +1 -1
- package/src/cubing/bluetooth/smart-puzzle/bluetooth-puzzle.ts +1 -1
- package/src/cubing/bluetooth/smart-puzzle/gan.ts +5 -5
- package/src/cubing/bluetooth/smart-puzzle/giiker.ts +2 -2
- package/src/cubing/bluetooth/smart-puzzle/gocube.ts +5 -5
- package/src/cubing/bluetooth/smart-robot/GanRobot.ts +5 -5
- package/src/cubing/bluetooth/smart-timer/GanTimer.ts +2 -2
- package/src/cubing/kpuzzle/.DS_Store +0 -0
- package/src/cubing/kpuzzle/3x3x3/3x3x3.kpuzzle.json.spec.ts +40 -0
- package/src/cubing/{puzzles/implementations/3x3x3/3x3x3.kpuzzle.json_.ts → kpuzzle/3x3x3/3x3x3.kpuzzle.json.ts} +11 -6
- package/src/cubing/kpuzzle/canon.spec.ts +6 -11
- package/src/cubing/kpuzzle/canonicalize.ts +1 -1
- package/src/cubing/kpuzzle/definition_types.ts +0 -3
- package/src/cubing/kpuzzle/index.ts +1 -0
- package/src/cubing/kpuzzle/prunetable.spec.ts +2 -4
- package/src/cubing/kpuzzle/puzzle-orientation.ts +1 -1
- package/src/cubing/kpuzzle/svg.ts +4 -9
- package/src/cubing/kpuzzle/transformations.ts +1 -1
- package/src/cubing/protocol/binary/binary3x3x3.spec.ts +5 -2
- package/src/cubing/protocol/binary/hex.ts +4 -4
- package/src/cubing/protocol/binary/orbit-indexing.ts +2 -2
- package/src/cubing/protocol/binary/puzzle-orientation.ts +2 -2
- package/src/cubing/puzzle-geometry/Options.ts +151 -22
- package/src/cubing/puzzle-geometry/PGPuzzles.spec.ts +24 -28
- package/src/cubing/puzzle-geometry/PermOriSet.ts +99 -98
- package/src/cubing/puzzle-geometry/PlatonicGenerator.ts +1 -1
- package/src/cubing/puzzle-geometry/PuzzleGeometry.ts +836 -867
- package/src/cubing/puzzle-geometry/Quat.ts +1 -68
- package/src/cubing/puzzle-geometry/SchreierSims.ts +2 -13
- package/src/cubing/puzzle-geometry/index.ts +2 -11
- package/src/cubing/puzzle-geometry/interfaces.ts +1 -27
- package/src/cubing/puzzle-geometry/orientcenters.spec.ts +24 -30
- package/src/cubing/puzzles/.DS_Store +0 -0
- package/src/cubing/puzzles/PuzzleLoader.ts +1 -1
- package/src/cubing/puzzles/async/async-pg3d.ts +5 -8
- package/src/cubing/puzzles/customPGPuzzleLoader.ts +60 -0
- package/src/cubing/puzzles/implementations/.DS_Store +0 -0
- package/src/cubing/puzzles/implementations/2x2x2/{2x2x2.kpuzzle.json_.ts → 2x2x2.kpuzzle.json.ts} +0 -0
- package/src/cubing/puzzles/implementations/2x2x2/index.ts +1 -1
- package/src/cubing/puzzles/implementations/3x3x3/index.ts +2 -3
- package/src/cubing/puzzles/implementations/clock/{clock.kpuzzle.json_.ts → clock.kpuzzle.json.ts} +0 -0
- package/src/cubing/puzzles/implementations/clock/index.ts +1 -1
- package/src/cubing/puzzles/implementations/fto/index.ts +19 -11
- package/src/cubing/puzzles/implementations/pyraminx/{pyraminx.kpuzzle.json_.ts → pyraminx.kpuzzle.json.ts} +0 -0
- package/src/cubing/puzzles/implementations/square1/index.ts +1 -2
- package/src/cubing/puzzles/implementations/square1/{sq1-hyperorbit.kpuzzle.json_.ts → sq1-hyperorbit.kpuzzle.json.ts} +0 -0
- package/src/cubing/puzzles/index.ts +30 -20
- package/src/cubing/puzzles/stickerings/appearance.ts +10 -9
- package/src/cubing/puzzles/stickerings/cube-stickerings.ts +8 -0
- package/src/cubing/puzzles/stickerings/fto-stickerings.ts +9 -0
- package/src/cubing/puzzles/stickerings/global-custom-stickering-hack.ts +61 -0
- package/src/cubing/search/.DS_Store +0 -0
- package/src/cubing/search/.gitignore +1 -2
- package/src/cubing/search/esm-test-worker.js +1 -1
- package/src/cubing/search/index.ts +1 -0
- package/src/cubing/search/inside/api.spec.ts +1 -0
- package/src/cubing/search/inside/api.ts +6 -1
- package/src/cubing/search/inside/solve/parseSGS.ts +7 -11
- package/src/cubing/search/inside/solve/puzzles/2x2x2.ts +3 -3
- package/src/cubing/search/inside/solve/puzzles/3x3x3/filter.ts +0 -6
- package/src/cubing/search/inside/solve/puzzles/3x3x3/index.ts +0 -2
- package/src/cubing/search/inside/solve/puzzles/FTO.sgs +264 -0
- package/src/cubing/search/inside/solve/puzzles/megaminx.sgs.json.ts +4 -6
- package/src/cubing/search/inside/solve/puzzles/skewb.sgs.json.ts +4 -6
- package/src/cubing/search/inside/solve/tremble.ts +6 -9
- package/src/cubing/search/inside/solve/vendor/cstimer/src/js/lib/mathlib.ts +20 -822
- package/src/cubing/search/inside/solve/vendor/cstimer/src/js/scramble/scramble_444.ts +177 -252
- package/src/cubing/search/inside/solve/vendor/min2phase/gwt.js +62 -222
- package/src/cubing/search/inside/solve/vendor/random-uint-below/get-random-values.ts +4 -5
- package/src/cubing/search/inside/solve/vendor/random-uint-below/random-int.ts +9 -11
- package/src/cubing/search/inside/solve/vendor/sq12phase/scramble_sq1.js +13 -582
- package/src/cubing/search/instantiator.ts +11 -7
- package/src/cubing/search/outside.ts +8 -2
- package/src/cubing/search/worker-inside-generated-string.js +1 -1
- package/src/cubing/stream/.DS_Store +0 -0
- package/src/cubing/stream/process/ReorientedStream.ts +1 -1
- package/src/cubing/stream/twizzle/TwizzleStream.ts +11 -8
- package/src/cubing/stream/websocket-proxy.ts +1 -3
- package/src/cubing/twisty/.DS_Store +0 -0
- package/src/cubing/twisty/controllers/TwistyAnimationController.ts +248 -0
- package/src/cubing/twisty/controllers/TwistyPlayerController.ts +38 -0
- package/src/cubing/twisty/heavy-code-imports/3d.ts +18 -0
- package/src/cubing/twisty/heavy-code-imports/dynamic-entries/3d.ts +41 -0
- package/src/cubing/twisty/index.ts +24 -17
- package/src/cubing/twisty/model/.DS_Store +0 -0
- package/src/cubing/twisty/model/PromiseFreshener.ts +49 -0
- package/src/cubing/twisty/model/TwistyPlayerModel.ts +222 -0
- package/src/cubing/twisty/model/UserVisibleErrorTracker.ts +22 -0
- package/src/cubing/twisty/model/helpers.ts +47 -0
- package/src/cubing/{search/vendor → twisty/model/props}/.DS_Store +0 -0
- package/src/cubing/twisty/model/props/TwistyProp.spec.ts +38 -0
- package/src/cubing/twisty/model/props/TwistyProp.ts +366 -0
- package/src/cubing/twisty/model/props/TwistyPropDebugger.ts +370 -0
- package/src/cubing/twisty/model/props/general/URLProp.ts +14 -0
- package/src/cubing/{solve → twisty/model/props/puzzle}/.DS_Store +0 -0
- package/src/cubing/twisty/model/props/puzzle/display/HintFaceletProp.ts +10 -0
- package/src/cubing/twisty/model/props/puzzle/display/SpriteProp.ts +43 -0
- package/src/cubing/twisty/model/props/puzzle/display/StickeringProp.ts +8 -0
- package/src/cubing/twisty/model/props/puzzle/state/AlgProp.ts +91 -0
- package/src/cubing/twisty/model/props/puzzle/state/AlgTransformationProp.ts +28 -0
- package/src/cubing/twisty/model/props/puzzle/state/AnchoredStartProp.ts +44 -0
- package/src/cubing/twisty/model/props/puzzle/state/CurrentLeavesProp.ts +91 -0
- package/src/cubing/twisty/model/props/puzzle/state/CurrentLeavesSimplified.ts +48 -0
- package/src/cubing/twisty/model/props/puzzle/state/CurrentTransformationProp.ts +46 -0
- package/src/cubing/twisty/model/props/puzzle/state/IndexerConstructorProp.ts +46 -0
- package/src/cubing/twisty/model/props/puzzle/state/IndexerConstructorRequestProp.ts +15 -0
- package/src/cubing/twisty/model/props/puzzle/state/IndexerProp.ts +24 -0
- package/src/cubing/twisty/model/props/puzzle/state/LegacyPositionProp.ts +22 -0
- package/src/cubing/twisty/model/props/puzzle/state/PuzzleAlgProp.ts +28 -0
- package/src/cubing/twisty/model/props/puzzle/state/SetupAnchorProp.ts +8 -0
- package/src/cubing/twisty/model/props/puzzle/structure/PuzzleDefProp.ts +14 -0
- package/src/cubing/twisty/model/props/puzzle/structure/PuzzleDescriptionProp.ts +14 -0
- package/src/cubing/twisty/model/props/puzzle/structure/PuzzleIDProp.ts +12 -0
- package/src/cubing/twisty/model/props/puzzle/structure/PuzzleIDRequestProp.ts +17 -0
- package/src/cubing/twisty/model/props/puzzle/structure/PuzzleLoaderProp.ts +38 -0
- package/src/cubing/twisty/model/props/timeline/CoarseTimelineInfoProp.ts +45 -0
- package/src/cubing/twisty/model/props/timeline/DetailedTimelineInfoProp.ts +76 -0
- package/src/cubing/twisty/model/props/timeline/PlayingInfoProp.ts +51 -0
- package/src/cubing/twisty/model/props/timeline/TempoScaleProp.ts +13 -0
- package/src/cubing/twisty/model/props/timeline/TimestampRequestProp.ts +38 -0
- package/src/cubing/twisty/model/props/viewer/BackViewProp.ts +10 -0
- package/src/cubing/twisty/model/props/viewer/BackgroundProp.ts +10 -0
- package/src/cubing/twisty/model/props/viewer/ButtonAppearanceProp.ts +86 -0
- package/src/cubing/twisty/model/props/viewer/ControlPanelProp.ts +10 -0
- package/src/cubing/twisty/model/props/viewer/LatitudeLimit.ts +11 -0
- package/src/cubing/twisty/model/props/viewer/OrbitCoordinatesProp.ts +56 -0
- package/src/cubing/twisty/model/props/viewer/OrbitCoordinatesRequestProp.ts +69 -0
- package/src/cubing/twisty/model/props/viewer/TimeRangeProp.ts +15 -0
- package/src/cubing/twisty/model/props/viewer/ViewerLinkProp.ts +10 -0
- package/src/cubing/twisty/model/props/viewer/VisualizationProp.ts +10 -0
- package/src/cubing/twisty/model/props/viewer/VisualizationStrategyProp.ts +45 -0
- package/src/cubing/twisty/old/.DS_Store +0 -0
- package/src/cubing/twisty/old/animation/.DS_Store +0 -0
- package/src/cubing/twisty/{animation → old/animation}/RenderScheduler.ts +5 -0
- package/src/cubing/twisty/{animation → old/animation}/Timeline.ts +0 -0
- package/src/cubing/twisty/{animation → old/animation}/cursor/AlgCursor.ts +15 -8
- package/src/cubing/twisty/{animation → old/animation}/cursor/CursorTypes.ts +4 -4
- package/src/cubing/twisty/{animation → old/animation}/easing.ts +0 -0
- package/src/cubing/{search/inside → twisty/old/animation/indexer}/.DS_Store +0 -0
- package/src/cubing/twisty/{animation → old/animation}/indexer/AlgDuration.ts +1 -1
- package/src/cubing/twisty/old/animation/indexer/AlgIndexer.ts +86 -0
- package/src/cubing/twisty/{animation → old/animation}/indexer/SimpleAlgIndexer.ts +9 -6
- package/src/cubing/twisty/old/animation/indexer/simultaneous-moves/SimultaneousMoveIndexer.ts +181 -0
- package/src/cubing/twisty/old/animation/indexer/simultaneous-moves/SimultaneousMoveIndexerV2.ts +243 -0
- package/src/cubing/twisty/{animation → old/animation}/indexer/simultaneous-moves/simul-moves.ts +46 -34
- package/src/cubing/twisty/{animation → old/animation}/indexer/tree/AlgWalker.ts +6 -3
- package/src/cubing/twisty/{animation → old/animation}/indexer/tree/TreeAlgIndexer.ts +8 -5
- package/src/cubing/twisty/{animation → old/animation}/indexer/tree/chunkAlgs.ts +2 -2
- package/src/cubing/twisty/{animation → old/animation}/stream/timeline-move-calculation-draft.spec.ts.TODO +0 -0
- package/src/cubing/twisty/{animation → old/animation}/stream/timeline-move-calculation-draft.ts +2 -2
- package/src/cubing/twisty/old/dom/.DS_Store +0 -0
- package/src/cubing/twisty/{dom/TwistyAlgViewer.css_.ts → old/dom/TwistyAlgViewerV1.css.ts} +0 -0
- package/src/cubing/twisty/{dom/TwistyAlgViewer.ts → old/dom/TwistyAlgViewerV1.ts} +43 -36
- package/src/cubing/twisty/{dom/TwistyPlayer.css_.ts → old/dom/TwistyPlayer.css.ts} +28 -1
- package/src/cubing/twisty/{dom → old/dom}/TwistyPlayer.spec.ts +5 -6
- package/src/cubing/twisty/{dom → old/dom}/TwistyPlayer.ts +36 -43
- package/src/cubing/twisty/{dom → old/dom}/TwistyPlayerConfig.ts +27 -10
- package/src/cubing/twisty/{dom/controls/TwistyControlElement.ts.ts → old/dom/controls/TwistyControlElement.ts} +0 -0
- package/src/cubing/twisty/{dom/controls/TwistyScrubber.css_.ts → old/dom/controls/TwistyScrubber.css.ts} +0 -0
- package/src/cubing/twisty/{dom → old/dom}/controls/TwistyScrubber.ts +3 -3
- package/src/cubing/twisty/{dom/controls/buttons.css_.ts → old/dom/controls/buttons.css.ts} +14 -1
- package/src/cubing/twisty/{dom → old/dom}/controls/buttons.spec.ts +1 -1
- package/src/cubing/twisty/{dom → old/dom}/controls/buttons.ts +15 -15
- package/src/cubing/twisty/{dom → old/dom}/element/ClassListManager.ts +0 -0
- package/src/cubing/twisty/{dom → old/dom}/element/ElementConfig.ts +1 -1
- package/src/cubing/twisty/{dom → old/dom}/element/ManagedCustomElement.ts +0 -0
- package/src/cubing/twisty/{dom → old/dom}/element/node-custom-element-shims.ts +0 -0
- package/src/cubing/twisty/{dom/stream/TwistyStreamSource.css_.ts → old/dom/stream/TwistyStreamSource.css.ts} +0 -0
- package/src/cubing/twisty/{dom → old/dom}/stream/TwistyStreamSource.ts +8 -8
- package/src/cubing/twisty/{dom → old/dom}/viewers/Twisty2DSVG.ts +7 -9
- package/src/cubing/twisty/{dom/viewers/Twisty2DSVGView.css_.ts → old/dom/viewers/Twisty2DSVGView.css.ts} +0 -0
- package/src/cubing/twisty/{dom/viewers/Twisty3DCanvas.css_.ts → old/dom/viewers/Twisty3DCanvas.css.ts} +0 -0
- package/src/cubing/twisty/{dom → old/dom}/viewers/Twisty3DCanvas.ts +5 -12
- package/src/cubing/twisty/{dom → old/dom}/viewers/TwistyOrbitControls.ts +53 -20
- package/src/cubing/twisty/{dom → old/dom}/viewers/TwistyViewerElement.ts +1 -1
- package/src/cubing/twisty/{dom/viewers/TwistyViewerWrapper.css_.ts → old/dom/viewers/TwistyViewerWrapper.css.ts} +0 -0
- package/src/cubing/twisty/{dom → old/dom}/viewers/TwistyViewerWrapper.ts +1 -1
- package/src/cubing/twisty/old/dom/viewers/canvas.ts +9 -0
- package/src/cubing/twisty/views/.DS_Store +0 -0
- package/src/cubing/twisty/views/2D/Twisty2DPuzzle.ts +150 -0
- package/src/cubing/twisty/views/2D/Twisty2DPuzzleWrapper.ts +52 -0
- package/src/cubing/twisty/views/2D/Twisty2DSceneWrapper.ts +77 -0
- package/src/cubing/twisty/views/3D/RendererPool.ts +53 -0
- package/src/cubing/twisty/{3D → views/3D}/TAU.ts +0 -0
- package/src/cubing/twisty/views/3D/Twisty3DPuzzleWrapper.ts +168 -0
- package/src/cubing/twisty/{3D → views/3D}/Twisty3DRenderTarget.ts +0 -0
- package/src/cubing/twisty/{3D → views/3D}/Twisty3DScene.ts +0 -0
- package/src/cubing/twisty/views/3D/Twisty3DSceneWrapper.ts +144 -0
- package/src/cubing/twisty/views/3D/Twisty3DVantage.ts +244 -0
- package/src/cubing/twisty/views/3D/TwistyOrbitControlsV2.spec.ts +209 -0
- package/src/cubing/twisty/views/3D/TwistyOrbitControlsV2.ts +270 -0
- package/src/cubing/twisty/{3D → views/3D}/puzzles/Cube3D.ts +36 -15
- package/src/cubing/twisty/{3D → views/3D}/puzzles/KPuzzleWrapper.ts +4 -5
- package/src/cubing/twisty/views/3D/puzzles/PG3D.ts +988 -0
- package/src/cubing/twisty/views/3D/puzzles/Twisty3DPuzzle.ts +6 -0
- package/src/cubing/twisty/{3D → views/3D}/puzzles/TwistyTestBox.ts +2 -2
- package/src/cubing/twisty/views/TwistyAlgEditor/LeafTokens.ts +116 -0
- package/src/cubing/twisty/{dom/TwistyAlgEditor.css_.ts → views/TwistyAlgEditor/TwistyAlgEditor.css.ts} +3 -1
- package/src/cubing/twisty/{dom → views/TwistyAlgEditor}/TwistyAlgEditor.spec.ts +7 -6
- package/src/cubing/twisty/views/TwistyAlgEditor/TwistyAlgEditor.ts +360 -0
- package/src/cubing/twisty/views/TwistyAlgEditor/model.ts +179 -0
- package/src/cubing/twisty/views/TwistyAlgViewer.css.ts +25 -0
- package/src/cubing/twisty/views/TwistyAlgViewer.ts +502 -0
- package/src/cubing/twisty/views/TwistyPlayer.ts +327 -0
- package/src/cubing/twisty/views/TwistyPlayerSettable.ts +111 -0
- package/src/cubing/twisty/views/control-panel/TwistyButtonsV2.ts +159 -0
- package/src/cubing/twisty/views/control-panel/TwistyScrubberV2.ts +145 -0
- package/src/cubing/twisty/views/control-panel/webkit-fullscreen.ts +44 -0
- package/src/cubing/twisty/views/document.ts +4 -0
- package/src/cubing/twisty/views/screenshot.ts +90 -0
- package/src/cubing/vendor/.DS_Store +0 -0
- package/src/cubing/vendor/p-lazy/license +9 -0
- package/src/cubing/vendor/p-lazy/p-lazy.ts +52 -0
- package/src/cubing/vendor/p-lazy/readme.md +54 -0
- package/src/cubing/vendor/three/examples/jsm/libs/stats.modified.module.ts +179 -0
- package/dist/esm/chunk-CWVB5RRW.js.map +0 -7
- package/dist/esm/chunk-KKSDHNLH.js.map +0 -7
- package/dist/esm/chunk-YNB7QLBF.js.map +0 -7
- package/dist/esm/worker-inside-generated-string-LT4NV55Q.js +0 -2826
- package/dist/esm/worker-inside-generated-string-LT4NV55Q.js.map +0 -7
- package/dist/types/puzzles/implementations/2x2x2/2x2x2.kpuzzle.json_.d.ts.map +0 -1
- package/dist/types/puzzles/implementations/3x3x3/3x3x3.kpuzzle.json_.d.ts +0 -3
- package/dist/types/puzzles/implementations/3x3x3/3x3x3.kpuzzle.json_.d.ts.map +0 -1
- package/dist/types/puzzles/implementations/clock/clock.kpuzzle.json_.d.ts.map +0 -1
- package/dist/types/puzzles/implementations/pyraminx/pyraminx.kpuzzle.json_.d.ts.map +0 -1
- package/dist/types/puzzles/implementations/square1/sq1-hyperorbit.kpuzzle.json_.d.ts.map +0 -1
- package/dist/types/search/inside/solve/vendor/cstimer/src/js/lgarron-additions-for-typescript/shim-lib.d.ts +0 -3
- package/dist/types/search/inside/solve/vendor/cstimer/src/js/lgarron-additions-for-typescript/shim-lib.d.ts.map +0 -1
- package/dist/types/twisty/3D/TAU.d.ts.map +0 -1
- package/dist/types/twisty/3D/Twisty3DRenderTarget.d.ts.map +0 -1
- package/dist/types/twisty/3D/Twisty3DScene.d.ts.map +0 -1
- package/dist/types/twisty/3D/puzzles/Cube3D.d.ts.map +0 -1
- package/dist/types/twisty/3D/puzzles/KPuzzleWrapper.d.ts.map +0 -1
- package/dist/types/twisty/3D/puzzles/PG3D.d.ts +0 -51
- package/dist/types/twisty/3D/puzzles/PG3D.d.ts.map +0 -1
- package/dist/types/twisty/3D/puzzles/Twisty3DPuzzle.d.ts.map +0 -1
- package/dist/types/twisty/3D/puzzles/TwistyTestBox.d.ts.map +0 -1
- package/dist/types/twisty/animation/RenderScheduler.d.ts.map +0 -1
- package/dist/types/twisty/animation/Timeline.d.ts.map +0 -1
- package/dist/types/twisty/animation/cursor/AlgCursor.d.ts.map +0 -1
- package/dist/types/twisty/animation/cursor/CursorTypes.d.ts.map +0 -1
- package/dist/types/twisty/animation/easing.d.ts.map +0 -1
- package/dist/types/twisty/animation/indexer/AlgDuration.d.ts.map +0 -1
- package/dist/types/twisty/animation/indexer/AlgIndexer.d.ts +0 -15
- package/dist/types/twisty/animation/indexer/AlgIndexer.d.ts.map +0 -1
- package/dist/types/twisty/animation/indexer/SimpleAlgIndexer.d.ts.map +0 -1
- package/dist/types/twisty/animation/indexer/simultaneous-moves/SimultaneousMoveIndexer.d.ts.map +0 -1
- package/dist/types/twisty/animation/indexer/simultaneous-moves/simul-moves.d.ts +0 -25
- package/dist/types/twisty/animation/indexer/simultaneous-moves/simul-moves.d.ts.map +0 -1
- package/dist/types/twisty/animation/indexer/tree/AlgWalker.d.ts.map +0 -1
- package/dist/types/twisty/animation/indexer/tree/TreeAlgIndexer.d.ts.map +0 -1
- package/dist/types/twisty/animation/indexer/tree/chunkAlgs.d.ts +0 -3
- package/dist/types/twisty/animation/indexer/tree/chunkAlgs.d.ts.map +0 -1
- package/dist/types/twisty/animation/stream/timeline-move-calculation-draft.d.ts.map +0 -1
- package/dist/types/twisty/dom/TwistyAlgEditor.css_.d.ts +0 -3
- package/dist/types/twisty/dom/TwistyAlgEditor.css_.d.ts.map +0 -1
- package/dist/types/twisty/dom/TwistyAlgEditor.d.ts +0 -27
- package/dist/types/twisty/dom/TwistyAlgEditor.d.ts.map +0 -1
- package/dist/types/twisty/dom/TwistyAlgEditorStartCharSearch.d.ts +0 -26
- package/dist/types/twisty/dom/TwistyAlgEditorStartCharSearch.d.ts.map +0 -1
- package/dist/types/twisty/dom/TwistyAlgViewer.css_.d.ts.map +0 -1
- package/dist/types/twisty/dom/TwistyAlgViewer.d.ts.map +0 -1
- package/dist/types/twisty/dom/TwistyPlayer.css_.d.ts.map +0 -1
- package/dist/types/twisty/dom/TwistyPlayer.d.ts.map +0 -1
- package/dist/types/twisty/dom/TwistyPlayerConfig.d.ts.map +0 -1
- package/dist/types/twisty/dom/controls/TwistyControlElement.ts.d.ts +0 -2
- package/dist/types/twisty/dom/controls/TwistyControlElement.ts.d.ts.map +0 -1
- package/dist/types/twisty/dom/controls/TwistyScrubber.css_.d.ts.map +0 -1
- package/dist/types/twisty/dom/controls/TwistyScrubber.d.ts.map +0 -1
- package/dist/types/twisty/dom/controls/buttons.css_.d.ts.map +0 -1
- package/dist/types/twisty/dom/controls/buttons.d.ts.map +0 -1
- package/dist/types/twisty/dom/element/ClassListManager.d.ts.map +0 -1
- package/dist/types/twisty/dom/element/ElementConfig.d.ts.map +0 -1
- package/dist/types/twisty/dom/element/ManagedCustomElement.d.ts.map +0 -1
- package/dist/types/twisty/dom/element/node-custom-element-shims.d.ts.map +0 -1
- package/dist/types/twisty/dom/stream/TwistyStreamSource.css_.d.ts.map +0 -1
- package/dist/types/twisty/dom/stream/TwistyStreamSource.d.ts.map +0 -1
- package/dist/types/twisty/dom/viewers/Twisty2DSVG.d.ts.map +0 -1
- package/dist/types/twisty/dom/viewers/Twisty2DSVGView.css_.d.ts.map +0 -1
- package/dist/types/twisty/dom/viewers/Twisty3DCanvas.css_.d.ts.map +0 -1
- package/dist/types/twisty/dom/viewers/Twisty3DCanvas.d.ts.map +0 -1
- package/dist/types/twisty/dom/viewers/TwistyOrbitControls.d.ts.map +0 -1
- package/dist/types/twisty/dom/viewers/TwistyViewerElement.d.ts +0 -4
- package/dist/types/twisty/dom/viewers/TwistyViewerElement.d.ts.map +0 -1
- package/dist/types/twisty/dom/viewers/TwistyViewerWrapper.css_.d.ts.map +0 -1
- package/dist/types/twisty/dom/viewers/TwistyViewerWrapper.d.ts.map +0 -1
- package/dist/types/twisty/dom/viewers/canvas.d.ts +0 -2
- package/dist/types/twisty/dom/viewers/canvas.d.ts.map +0 -1
- package/dist/types/vendor/three/examples/jsm/libs/stats.module.d.ts +0 -2
- package/dist/types/vendor/three/examples/jsm/libs/stats.module.d.ts.map +0 -1
- package/dist/types/vendor/three/examples/jsm/libs/stats.module.wrapped.d.ts +0 -21
- package/dist/types/vendor/three/examples/jsm/libs/stats.module.wrapped.d.ts.map +0 -1
- package/src/cubing/protocol/.DS_Store +0 -0
- package/src/cubing/puzzle-geometry/.DS_Store +0 -0
- package/src/cubing/search/inside/solve/.DS_Store +0 -0
- package/src/cubing/search/inside/solve/puzzles/.DS_Store +0 -0
- package/src/cubing/search/inside/solve/puzzles/3x3x3/.DS_Store +0 -0
- package/src/cubing/search/inside/solve/vendor/.DS_Store +0 -0
- package/src/cubing/search/inside/solve/vendor/cstimer/.DS_Store +0 -0
- package/src/cubing/search/inside/solve/vendor/cstimer/src/.DS_Store +0 -0
- package/src/cubing/search/inside/solve/vendor/cstimer/src/js/.DS_Store +0 -0
- package/src/cubing/search/inside/solve/vendor/cstimer/src/js/lgarron-additions-for-typescript/.DS_Store +0 -0
- package/src/cubing/search/inside/solve/vendor/cstimer/src/js/lgarron-additions-for-typescript/shim-lib.ts +0 -13
- package/src/cubing/search/inside/solve/vendor/cstimer/src/js/lib/.DS_Store +0 -0
- package/src/cubing/search/inside/solve/vendor/cstimer/src/js/scramble/.DS_Store +0 -0
- package/src/cubing/search/inside/solve/vendor/sgs/.DS_Store +0 -0
- package/src/cubing/search/inside/solve/vendor/sgs/src/.DS_Store +0 -0
- package/src/cubing/search/inside/solve/vendor/sgs/src/test/.DS_Store +0 -0
- package/src/cubing/search/vendor/comlink-everywhere/.DS_Store +0 -0
- package/src/cubing/twisty/3D/puzzles/PG3D.ts +0 -600
- package/src/cubing/twisty/3D/puzzles/Twisty3DPuzzle.ts +0 -9
- package/src/cubing/twisty/3D/puzzles/mkbhd.svg +0 -5
- package/src/cubing/twisty/animation/indexer/AlgIndexer.ts +0 -25
- package/src/cubing/twisty/animation/indexer/simultaneous-moves/SimultaneousMoveIndexer.ts +0 -168
- package/src/cubing/twisty/dom/TwistyAlgEditor.ts +0 -373
- package/src/cubing/twisty/dom/TwistyAlgEditorStartCharSearch.ts +0 -138
- package/src/cubing/twisty/dom/viewers/canvas.ts +0 -4
- package/src/cubing/twisty/views/3D/.DS_Store +0 -0
- package/src/cubing/vendor/three/.DS_Store +0 -0
- package/src/cubing/vendor/three/examples/jsm/libs/stats.module.ts +0 -2
- package/src/cubing/vendor/three/examples/jsm/libs/stats.module.wrapped.d.ts +0 -24
- package/src/cubing/vendor/three/examples/jsm/libs/stats.module.wrapped.js +0 -178
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
/* tslint:disable no-bitwise */
|
|
2
|
-
/* tslint:disable prefer-for-of */ // TODO
|
|
3
|
-
/* tslint:disable only-arrow-functions */ // TODO
|
|
4
|
-
/* tslint:disable typedef */ // TODO
|
|
5
|
-
|
|
6
1
|
import { Move, QuantumMove } from "../alg";
|
|
7
2
|
import { FaceNameSwizzler } from "./FaceNameSwizzler";
|
|
8
|
-
import type {
|
|
9
|
-
MoveNotation,
|
|
10
|
-
PGVendoredKPuzzleDefinition,
|
|
11
|
-
Transformation as KTransformation,
|
|
12
|
-
} from "./interfaces";
|
|
3
|
+
import type { MoveNotation } from "./interfaces";
|
|
13
4
|
import {
|
|
14
5
|
FaceRenamingMapper,
|
|
15
6
|
FTONotationMapper,
|
|
@@ -21,14 +12,21 @@ import {
|
|
|
21
12
|
SkewbNotationMapper,
|
|
22
13
|
TetraminxNotationMapper,
|
|
23
14
|
} from "./notation-mapping";
|
|
15
|
+
import {
|
|
16
|
+
BaseFaceCount,
|
|
17
|
+
FaceBasedOrientationDescription,
|
|
18
|
+
FaceBasedOrientationDescriptionLookup,
|
|
19
|
+
PuzzleGeometryOptions,
|
|
20
|
+
PuzzleGeometryFullOptions,
|
|
21
|
+
} from "./Options";
|
|
24
22
|
import { iota, Perm, zeros } from "./Perm";
|
|
25
23
|
import {
|
|
26
24
|
externalName,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
PGOrbit,
|
|
26
|
+
PGOrbitDef,
|
|
27
|
+
PGOrbitsDef,
|
|
30
28
|
showcanon,
|
|
31
|
-
|
|
29
|
+
PGTransform,
|
|
32
30
|
VisibleState,
|
|
33
31
|
} from "./PermOriSet";
|
|
34
32
|
import { PGPuzzles, PuzzleDescriptionString, PuzzleName } from "./PGPuzzles";
|
|
@@ -42,20 +40,29 @@ import {
|
|
|
42
40
|
tetrahedron,
|
|
43
41
|
uniqueplanes,
|
|
44
42
|
} from "./PlatonicGenerator";
|
|
45
|
-
import { centermassface,
|
|
43
|
+
import { centermassface, Quat } from "./Quat";
|
|
44
|
+
import { schreierSims } from "./SchreierSims";
|
|
45
|
+
import type {
|
|
46
|
+
KPuzzleDefinition,
|
|
47
|
+
Transformation as KTransformation,
|
|
48
|
+
} from "../kpuzzle";
|
|
46
49
|
|
|
47
|
-
|
|
50
|
+
export interface TextureMapper {
|
|
51
|
+
getuv(fn: number, threed: number[]): number[];
|
|
52
|
+
}
|
|
48
53
|
|
|
49
54
|
export interface StickerDatSticker {
|
|
50
|
-
coords: number[]
|
|
55
|
+
coords: number[];
|
|
51
56
|
color: string;
|
|
52
57
|
orbit: string;
|
|
53
58
|
ord: number;
|
|
54
59
|
ori: number;
|
|
60
|
+
face: number;
|
|
61
|
+
isDup?: boolean;
|
|
55
62
|
}
|
|
56
63
|
|
|
57
64
|
export interface StickerDatFace {
|
|
58
|
-
coords: number[]
|
|
65
|
+
coords: number[];
|
|
59
66
|
name: string;
|
|
60
67
|
}
|
|
61
68
|
|
|
@@ -63,17 +70,116 @@ export type StickerDatAxis = [number[], string, number];
|
|
|
63
70
|
|
|
64
71
|
export interface StickerDat {
|
|
65
72
|
stickers: StickerDatSticker[];
|
|
66
|
-
foundations: StickerDatSticker[];
|
|
67
73
|
faces: StickerDatFace[];
|
|
68
74
|
axis: StickerDatAxis[];
|
|
69
75
|
unswizzle(mv: Move): string;
|
|
70
76
|
notationMapper: NotationMapper;
|
|
77
|
+
textureMapper: TextureMapper;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// you can fill these in to help with timing if you want
|
|
81
|
+
function tstart(s: string): string {
|
|
82
|
+
return s;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function tend(_: string): void {}
|
|
86
|
+
|
|
87
|
+
class Face {
|
|
88
|
+
private coords: number[];
|
|
89
|
+
public length: number;
|
|
90
|
+
constructor(q: Quat[]) {
|
|
91
|
+
this.coords = new Array(q.length * 3);
|
|
92
|
+
for (let i = 0; i < q.length; i++) {
|
|
93
|
+
this.coords[3 * i] = q[i].b;
|
|
94
|
+
this.coords[3 * i + 1] = q[i].c;
|
|
95
|
+
this.coords[3 * i + 2] = q[i].d;
|
|
96
|
+
}
|
|
97
|
+
this.length = q.length;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
get(off: number): Quat {
|
|
101
|
+
return new Quat(
|
|
102
|
+
0,
|
|
103
|
+
this.coords[3 * off],
|
|
104
|
+
this.coords[3 * off + 1],
|
|
105
|
+
this.coords[3 * off + 2],
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
centermass(): Quat {
|
|
110
|
+
let sx = 0;
|
|
111
|
+
let sy = 0;
|
|
112
|
+
let sz = 0;
|
|
113
|
+
for (let i = 0; i < this.length; i++) {
|
|
114
|
+
sx += this.coords[3 * i];
|
|
115
|
+
sy += this.coords[3 * i + 1];
|
|
116
|
+
sz += this.coords[3 * i + 2];
|
|
117
|
+
}
|
|
118
|
+
return new Quat(0, sx / this.length, sy / this.length, sz / this.length);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
rotate(q: Quat): Face {
|
|
122
|
+
const a = [];
|
|
123
|
+
for (let i = 0; i < this.length; i++) {
|
|
124
|
+
a.push(this.get(i).rotatepoint(q));
|
|
125
|
+
}
|
|
126
|
+
return new Face(a);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
rotateforward(): Face {
|
|
130
|
+
const a = [];
|
|
131
|
+
for (let i = 1; i < this.length; i++) {
|
|
132
|
+
a.push(this.get(i));
|
|
133
|
+
}
|
|
134
|
+
a.push(this.get(0));
|
|
135
|
+
return new Face(a);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export class FaceTree {
|
|
140
|
+
constructor(
|
|
141
|
+
private face: Quat[],
|
|
142
|
+
private left?: FaceTree,
|
|
143
|
+
private right?: FaceTree,
|
|
144
|
+
) {}
|
|
145
|
+
|
|
146
|
+
public split(q: Quat): FaceTree {
|
|
147
|
+
const t = q.cutface(this.face);
|
|
148
|
+
if (t !== null) {
|
|
149
|
+
if (this.left === undefined) {
|
|
150
|
+
this.left = new FaceTree(t[0]);
|
|
151
|
+
this.right = new FaceTree(t[1]);
|
|
152
|
+
} else {
|
|
153
|
+
this.left = this.left?.split(q);
|
|
154
|
+
this.right = this.right?.split(q);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return this;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
public collect(arr: Face[], leftfirst: boolean): Face[] {
|
|
161
|
+
if (this.left === undefined) {
|
|
162
|
+
arr.push(new Face(this.face));
|
|
163
|
+
} else if (leftfirst) {
|
|
164
|
+
this.left?.collect(arr, false);
|
|
165
|
+
this.right?.collect(arr, true);
|
|
166
|
+
} else {
|
|
167
|
+
this.right?.collect(arr, false);
|
|
168
|
+
this.left?.collect(arr, true);
|
|
169
|
+
}
|
|
170
|
+
return arr;
|
|
171
|
+
}
|
|
71
172
|
}
|
|
72
173
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
174
|
+
export function expandfaces(rots: Quat[], faces: Face[]): Face[] {
|
|
175
|
+
// given a set of faces, expand by rotation set
|
|
176
|
+
const nfaces = [];
|
|
177
|
+
for (const rot of rots) {
|
|
178
|
+
for (const face of faces) {
|
|
179
|
+
nfaces.push(face.rotate(rot));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return nfaces;
|
|
77
183
|
}
|
|
78
184
|
|
|
79
185
|
// Now we have a geometry class that does the 3D goemetry to calculate
|
|
@@ -266,17 +372,32 @@ function defaultfaceorders(): any {
|
|
|
266
372
|
* this information is explicitly given in the twizzle app file.
|
|
267
373
|
*/
|
|
268
374
|
// TODO: change this back to a const JSON definition.
|
|
269
|
-
function defaultOrientations():
|
|
375
|
+
function defaultOrientations(): FaceBasedOrientationDescriptionLookup {
|
|
270
376
|
return {
|
|
271
|
-
4: [
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
377
|
+
4: [
|
|
378
|
+
["FLR", [0, 1, 0]],
|
|
379
|
+
["F", [0, 0, 1]],
|
|
380
|
+
], // FLR towards viewer
|
|
381
|
+
6: [
|
|
382
|
+
["U", [0, 1, 0]],
|
|
383
|
+
["F", [0, 0, 1]],
|
|
384
|
+
], // URF towards viewer
|
|
385
|
+
8: [
|
|
386
|
+
["U", [0, 1, 0]],
|
|
387
|
+
["F", [0, 0, 1]],
|
|
388
|
+
], // FLUR towards viewer
|
|
389
|
+
12: [
|
|
390
|
+
["U", [0, 1, 0]],
|
|
391
|
+
["F", [0, 0, 1]],
|
|
392
|
+
], // F towards viewer
|
|
393
|
+
20: [
|
|
394
|
+
["GUQMJ", [0, 1, 0]],
|
|
395
|
+
["F", [0, 0, 1]],
|
|
396
|
+
], // F towards viewer
|
|
276
397
|
};
|
|
277
398
|
}
|
|
278
399
|
|
|
279
|
-
function findelement(a:
|
|
400
|
+
function findelement(a: Quat[][], p: Quat): number {
|
|
280
401
|
// find something in facenames, vertexnames, edgenames
|
|
281
402
|
for (let i = 0; i < a.length; i++) {
|
|
282
403
|
if (a[i][0].dist(p) < eps) {
|
|
@@ -296,40 +417,51 @@ export function getpuzzle(puzzleName: PuzzleName): PuzzleDescriptionString {
|
|
|
296
417
|
return PGPuzzles[puzzleName];
|
|
297
418
|
}
|
|
298
419
|
|
|
299
|
-
export
|
|
420
|
+
export type CutDescription = { cutType: string; distance: number };
|
|
421
|
+
export type PuzzleDescription = {
|
|
422
|
+
shape: string;
|
|
423
|
+
cuts: CutDescription[];
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
export function parsePuzzleDescription(
|
|
427
|
+
s: PuzzleDescriptionString,
|
|
428
|
+
): PuzzleDescription | null {
|
|
300
429
|
// parse a text description
|
|
301
430
|
const a = s.split(/ /).filter(Boolean);
|
|
302
431
|
if (a.length % 2 === 0) {
|
|
303
|
-
return
|
|
432
|
+
return null;
|
|
304
433
|
}
|
|
434
|
+
const shape = a[0];
|
|
305
435
|
if (
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
436
|
+
shape !== "o" &&
|
|
437
|
+
shape !== "c" &&
|
|
438
|
+
shape !== "i" &&
|
|
439
|
+
shape !== "d" &&
|
|
440
|
+
shape !== "t"
|
|
311
441
|
) {
|
|
312
|
-
return
|
|
442
|
+
return null;
|
|
313
443
|
}
|
|
314
|
-
const
|
|
444
|
+
const cuts: CutDescription[] = [];
|
|
315
445
|
for (let i = 1; i < a.length; i += 2) {
|
|
316
446
|
if (a[i] !== "f" && a[i] !== "v" && a[i] !== "e") {
|
|
317
|
-
return
|
|
447
|
+
return null;
|
|
318
448
|
}
|
|
319
|
-
|
|
449
|
+
cuts.push({ cutType: a[i], distance: parseFloat(a[i + 1]) });
|
|
320
450
|
}
|
|
321
|
-
return
|
|
451
|
+
return { shape, cuts };
|
|
322
452
|
}
|
|
323
453
|
|
|
324
454
|
export function getPuzzleGeometryByDesc(
|
|
325
455
|
desc: string,
|
|
326
|
-
options:
|
|
456
|
+
options: PuzzleGeometryOptions = {},
|
|
327
457
|
): PuzzleGeometry {
|
|
328
|
-
const
|
|
458
|
+
const parsed = parsePuzzleDescription(desc);
|
|
459
|
+
if (parsed === null) {
|
|
460
|
+
throw new Error("Could not parse the puzzle description");
|
|
461
|
+
}
|
|
329
462
|
const pg = new PuzzleGeometry(
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
["allmoves", "true"].concat(options),
|
|
463
|
+
parsed,
|
|
464
|
+
Object.assign({}, { allMoves: true } as PuzzleGeometryOptions, options),
|
|
333
465
|
);
|
|
334
466
|
pg.allstickers();
|
|
335
467
|
pg.genperms();
|
|
@@ -338,12 +470,16 @@ export function getPuzzleGeometryByDesc(
|
|
|
338
470
|
|
|
339
471
|
export function getPuzzleGeometryByName(
|
|
340
472
|
puzzleName: PuzzleName,
|
|
341
|
-
options
|
|
473
|
+
options?: PuzzleGeometryOptions,
|
|
342
474
|
): PuzzleGeometry {
|
|
343
475
|
return getPuzzleGeometryByDesc(PGPuzzles[puzzleName], options);
|
|
344
476
|
}
|
|
345
477
|
|
|
346
|
-
function getmovename(
|
|
478
|
+
function getmovename(
|
|
479
|
+
geo: any,
|
|
480
|
+
bits: number[],
|
|
481
|
+
slices: number,
|
|
482
|
+
): [string, boolean] {
|
|
347
483
|
// generate a move name based on bits, slice, and geo
|
|
348
484
|
// if the move name is from the opposite face, say so.
|
|
349
485
|
// find the face that's turned.
|
|
@@ -354,7 +490,7 @@ function getmovename(geo: any, bits: number[], slices: number): any {
|
|
|
354
490
|
bits = [slices - bits[1], slices - bits[0]];
|
|
355
491
|
inverted = true;
|
|
356
492
|
}
|
|
357
|
-
let movenameFamily = geo[0];
|
|
493
|
+
let movenameFamily = geo[0] as string;
|
|
358
494
|
let movenamePrefix = "";
|
|
359
495
|
if (bits[0] === 0 && bits[1] === slices) {
|
|
360
496
|
movenameFamily = movenameFamily + "v";
|
|
@@ -368,14 +504,14 @@ function getmovename(geo: any, bits: number[], slices: number): any {
|
|
|
368
504
|
movenamePrefix = String(bits[1] + 1);
|
|
369
505
|
}
|
|
370
506
|
} else {
|
|
371
|
-
throw
|
|
507
|
+
throw `We only support slice and outer block moves right now. ${bits}`;
|
|
372
508
|
}
|
|
373
509
|
return [movenamePrefix + movenameFamily, inverted];
|
|
374
510
|
}
|
|
375
511
|
|
|
376
512
|
// split a geometrical element into face names. Do greedy match.
|
|
377
513
|
// Permit underscores between names.
|
|
378
|
-
function splitByFaceNames(s: string, facenames:
|
|
514
|
+
function splitByFaceNames(s: string, facenames: [Quat[], string][]): string[] {
|
|
379
515
|
const r: string[] = [];
|
|
380
516
|
let at = 0;
|
|
381
517
|
while (at < s.length) {
|
|
@@ -383,12 +519,12 @@ function splitByFaceNames(s: string, facenames: any[]): string[] {
|
|
|
383
519
|
at++;
|
|
384
520
|
}
|
|
385
521
|
let currentMatch = "";
|
|
386
|
-
for (
|
|
522
|
+
for (const facename of facenames) {
|
|
387
523
|
if (
|
|
388
|
-
s.substr(at).startsWith(
|
|
389
|
-
|
|
524
|
+
s.substr(at).startsWith(facename[1]) &&
|
|
525
|
+
facename[1].length > currentMatch.length
|
|
390
526
|
) {
|
|
391
|
-
currentMatch =
|
|
527
|
+
currentMatch = facename[1];
|
|
392
528
|
}
|
|
393
529
|
}
|
|
394
530
|
if (currentMatch !== "") {
|
|
@@ -405,206 +541,98 @@ function toCoords(q: Quat, maxdist: number): number[] {
|
|
|
405
541
|
return [q.b / maxdist, -q.c / maxdist, q.d / maxdist];
|
|
406
542
|
}
|
|
407
543
|
|
|
408
|
-
function toFaceCoords(q:
|
|
544
|
+
function toFaceCoords(q: Face, maxdist: number): number[] {
|
|
409
545
|
const r = [];
|
|
410
546
|
const n = q.length;
|
|
411
547
|
for (let i = 0; i < n; i++) {
|
|
412
|
-
|
|
548
|
+
const pt = toCoords(q.get(n - i - 1), maxdist);
|
|
549
|
+
r[3 * i] = pt[0];
|
|
550
|
+
r[3 * i + 1] = pt[1];
|
|
551
|
+
r[3 * i + 2] = pt[2];
|
|
413
552
|
}
|
|
414
553
|
return r;
|
|
415
554
|
}
|
|
416
555
|
|
|
417
|
-
function trimEdges(face: Quat[], tr: number): Quat[] {
|
|
418
|
-
const r: Quat[] = [];
|
|
419
|
-
for (let iter = 1; iter < 10; iter++) {
|
|
420
|
-
for (let i = 0; i < face.length; i++) {
|
|
421
|
-
const pi = (i + face.length - 1) % face.length;
|
|
422
|
-
const ni = (i + 1) % face.length;
|
|
423
|
-
const A = face[pi].sub(face[i]).normalize();
|
|
424
|
-
const B = face[ni].sub(face[i]).normalize();
|
|
425
|
-
const d = A.dot(B);
|
|
426
|
-
const m = tr / Math.sqrt(1 - d * d);
|
|
427
|
-
r[i] = face[i].sum(A.sum(B).smul(m));
|
|
428
|
-
}
|
|
429
|
-
let good = true;
|
|
430
|
-
for (let i = 0; good && i < r.length; i++) {
|
|
431
|
-
const pi = (i + face.length - 1) % face.length;
|
|
432
|
-
const ni = (i + 1) % face.length;
|
|
433
|
-
if (r[pi].sub(r[i]).cross(r[ni].sub(r[i])).dot(r[i]) >= 0) {
|
|
434
|
-
good = false;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
if (good) {
|
|
438
|
-
return r;
|
|
439
|
-
}
|
|
440
|
-
tr /= 2;
|
|
441
|
-
}
|
|
442
|
-
return face;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
556
|
export class PuzzleGeometry {
|
|
446
|
-
|
|
447
|
-
public rotations: Quat[]; // all members of the rotation group
|
|
557
|
+
private rotations: Quat[]; // all members of the rotation group
|
|
448
558
|
public baseplanerot: Quat[]; // unique rotations of the baseplane
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
public moveplanesets:
|
|
458
|
-
|
|
459
|
-
public movesetorders:
|
|
460
|
-
public movesetgeos:
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
559
|
+
private baseplanes: Quat[]; // planes, corresponding to faces
|
|
560
|
+
private facenames: [Quat[], string][]; // face names
|
|
561
|
+
private faceplanes: [Quat, string][]; // face planes
|
|
562
|
+
private edgenames: [Quat, string][]; // edge names
|
|
563
|
+
private vertexnames: [Quat, string][]; // vertexnames
|
|
564
|
+
private geonormals: [Quat, string, string][]; // all geometric directions, with names and types
|
|
565
|
+
private moveplanes: Quat[]; // the planes that split moves
|
|
566
|
+
private moveplanes2: Quat[]; // the planes that split moves, filtered
|
|
567
|
+
public moveplanesets: Quat[][]; // the move planes, in parallel sets
|
|
568
|
+
private moveplanenormals: Quat[]; // one move plane
|
|
569
|
+
public movesetorders: number[]; // the order of rotations for each move set
|
|
570
|
+
public movesetgeos: [string, string, string, string, number][]; // geometric feature information for move sets
|
|
571
|
+
private basefaces: Face[]; // polytope faces before cuts
|
|
572
|
+
private faces: Face[]; // all the stickers
|
|
573
|
+
private facecentermass: Quat[]; // center of mass of all faces
|
|
574
|
+
private baseFaceCount: BaseFaceCount; // number of base faces
|
|
465
575
|
public stickersperface: number; // number of stickers per face
|
|
466
|
-
public
|
|
467
|
-
public cubies:
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
public orbitoris: number[]; // the orientation size of each orbit
|
|
482
|
-
public cubievaluemap: number[]; // the map for identical cubies
|
|
483
|
-
public cubiesetcubies: number[][]; // cubies in each cubie set
|
|
576
|
+
public shortedge: number; // number of stickers per face
|
|
577
|
+
public cubies: number[][]; // the cubies
|
|
578
|
+
private vertexdistance: number; // vertex distance
|
|
579
|
+
private edgedistance: number; // edge distance
|
|
580
|
+
private facetocubie: number[]; // map a face to a cubie index
|
|
581
|
+
private facetoord: number[]; // map a face to a cubie ord
|
|
582
|
+
private moverotations: Quat[][]; // move rotations
|
|
583
|
+
private facelisthash: Map<string, number[]>; // face list by key
|
|
584
|
+
private cubiesetnames: string[]; // cubie set names
|
|
585
|
+
private cubieords: number[]; // the size of each orbit
|
|
586
|
+
private cubiesetnums: number[];
|
|
587
|
+
private cubieordnums: number[];
|
|
588
|
+
private orbitoris: number[]; // the orientation size of each orbit
|
|
589
|
+
private cubievaluemap: number[]; // the map for identical cubies
|
|
590
|
+
private cubiesetcubies: number[][]; // cubies in each cubie set
|
|
484
591
|
public cmovesbyslice: number[][][] = []; // cmoves as perms by slice
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
public killorientation: boolean = false; // eliminate any orientations
|
|
503
|
-
public optimize: boolean = false; // optimize PermOri
|
|
504
|
-
public scramble: number = 0; // scramble?
|
|
505
|
-
public ksolvemovenames: string[]; // move names from ksolve
|
|
506
|
-
public fixPiece: string = ""; // fix a piece?
|
|
507
|
-
public orientCenters: boolean = false; // orient centers?
|
|
508
|
-
public duplicatedFaces: number[] = []; // which faces are duplicated
|
|
509
|
-
public duplicatedCubies: number[] = []; // which cubies are duplicated
|
|
510
|
-
public fixedCubie: number = -1; // fixed cubie, if any
|
|
511
|
-
public svggrips: any[]; // grips from svg generation by svg coordinate
|
|
512
|
-
public net: any = [];
|
|
513
|
-
public colors: any = [];
|
|
514
|
-
public faceorder: any = [];
|
|
515
|
-
public faceprecedence: number[] = [];
|
|
516
|
-
public swizzler: FaceNameSwizzler;
|
|
592
|
+
public parsedmovelist: [
|
|
593
|
+
string | undefined,
|
|
594
|
+
number,
|
|
595
|
+
number,
|
|
596
|
+
number,
|
|
597
|
+
boolean,
|
|
598
|
+
number,
|
|
599
|
+
][]; // parsed move list
|
|
600
|
+
|
|
601
|
+
private duplicatedFaces: number[] = []; // which faces are duplicated
|
|
602
|
+
private duplicatedCubies: number[] = []; // which cubies are duplicated
|
|
603
|
+
private fixedCubie: number = -1; // fixed cubie, if any
|
|
604
|
+
private net: string[][] = [];
|
|
605
|
+
private colors: any = [];
|
|
606
|
+
private faceorder: string[] = [];
|
|
607
|
+
private faceprecedence: number[] = [];
|
|
608
|
+
private swizzler: FaceNameSwizzler;
|
|
517
609
|
public notationMapper: NotationMapper = new NullMapper();
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
return false;
|
|
531
|
-
}
|
|
532
|
-
return true;
|
|
533
|
-
} else {
|
|
534
|
-
return v ? true : false;
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
if (optionlist !== undefined) {
|
|
538
|
-
if (optionlist.length % 2 !== 0) {
|
|
539
|
-
throw new Error("Odd length in option list?");
|
|
540
|
-
}
|
|
541
|
-
for (let i = 0; i < optionlist.length; i += 2) {
|
|
542
|
-
if (optionlist[i] === "verbose") {
|
|
543
|
-
this.verbose++;
|
|
544
|
-
} else if (optionlist[i] === "quiet") {
|
|
545
|
-
this.verbose = 0;
|
|
546
|
-
} else if (optionlist[i] === "allmoves") {
|
|
547
|
-
this.allmoves = asboolean(optionlist[i + 1]);
|
|
548
|
-
} else if (optionlist[i] === "outerblockmoves") {
|
|
549
|
-
this.outerblockmoves = asboolean(optionlist[i + 1]);
|
|
550
|
-
} else if (optionlist[i] === "vertexmoves") {
|
|
551
|
-
this.vertexmoves = asboolean(optionlist[i + 1]);
|
|
552
|
-
} else if (optionlist[i] === "rotations") {
|
|
553
|
-
this.addrotations = asboolean(optionlist[i + 1]);
|
|
554
|
-
} else if (optionlist[i] === "cornersets") {
|
|
555
|
-
this.cornersets = asboolean(optionlist[i + 1]);
|
|
556
|
-
} else if (optionlist[i] === "centersets") {
|
|
557
|
-
this.centersets = asboolean(optionlist[i + 1]);
|
|
558
|
-
} else if (optionlist[i] === "edgesets") {
|
|
559
|
-
this.edgesets = asboolean(optionlist[i + 1]);
|
|
560
|
-
} else if (optionlist[i] === "omit") {
|
|
561
|
-
this.omitsets = optionlist[i + 1];
|
|
562
|
-
} else if (optionlist[i] === "graycorners") {
|
|
563
|
-
this.graycorners = asboolean(optionlist[i + 1]);
|
|
564
|
-
} else if (optionlist[i] === "graycenters") {
|
|
565
|
-
this.graycenters = asboolean(optionlist[i + 1]);
|
|
566
|
-
} else if (optionlist[i] === "grayedges") {
|
|
567
|
-
this.grayedges = asboolean(optionlist[i + 1]);
|
|
568
|
-
} else if (optionlist[i] === "movelist") {
|
|
569
|
-
this.movelist = asstructured(optionlist[i + 1]);
|
|
570
|
-
} else if (optionlist[i] === "killorientation") {
|
|
571
|
-
this.killorientation = asboolean(optionlist[i + 1]);
|
|
572
|
-
} else if (optionlist[i] === "optimize") {
|
|
573
|
-
this.optimize = asboolean(optionlist[i + 1]);
|
|
574
|
-
} else if (optionlist[i] === "scramble") {
|
|
575
|
-
this.scramble = optionlist[i + 1];
|
|
576
|
-
} else if (optionlist[i] === "fix") {
|
|
577
|
-
this.fixPiece = optionlist[i + 1];
|
|
578
|
-
} else if (optionlist[i] === "orientcenters") {
|
|
579
|
-
this.orientCenters = asboolean(optionlist[i + 1]);
|
|
580
|
-
} else if (optionlist[i] === "puzzleorientation") {
|
|
581
|
-
this.puzzleOrientation = asstructured(optionlist[i + 1]);
|
|
582
|
-
} else if (optionlist[i] === "puzzleorientations") {
|
|
583
|
-
this.puzzleOrientations = asstructured(optionlist[i + 1]);
|
|
584
|
-
} else {
|
|
585
|
-
throw new Error(
|
|
586
|
-
"Bad option while processing option list " + optionlist[i],
|
|
587
|
-
);
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
this.args = shape + " " + cuts.map((_) => _.join(" ")).join(" ");
|
|
592
|
-
if (optionlist) {
|
|
593
|
-
this.args += " " + optionlist.join(" ");
|
|
594
|
-
}
|
|
595
|
-
if (this.verbose > 0) {
|
|
610
|
+
private addNotationMapper: string = "";
|
|
611
|
+
private setReidOrder: boolean = false;
|
|
612
|
+
|
|
613
|
+
private options: PuzzleGeometryFullOptions;
|
|
614
|
+
|
|
615
|
+
constructor(
|
|
616
|
+
puzzleDescription: PuzzleDescription,
|
|
617
|
+
options: PuzzleGeometryOptions,
|
|
618
|
+
) {
|
|
619
|
+
const t1 = tstart("genperms");
|
|
620
|
+
this.options = new PuzzleGeometryFullOptions(options);
|
|
621
|
+
if (this.options.verbosity > 0) {
|
|
596
622
|
console.log(this.header("# "));
|
|
597
623
|
}
|
|
598
|
-
this.create(
|
|
624
|
+
this.create(puzzleDescription);
|
|
625
|
+
tend(t1);
|
|
599
626
|
}
|
|
600
627
|
|
|
601
|
-
public create(
|
|
628
|
+
public create(puzzleDescription: PuzzleDescription): void {
|
|
629
|
+
const { shape, cuts } = puzzleDescription;
|
|
630
|
+
|
|
602
631
|
// create the shape, doing all the essential geometry
|
|
603
632
|
// create only goes far enough to figure out how many stickers per
|
|
604
633
|
// face, and what the short edge is. If the short edge is too short,
|
|
605
634
|
// we probably don't want to display or manipulate this one. How
|
|
606
635
|
// short is too short is hard to say.
|
|
607
|
-
// var that = this ; // TODO
|
|
608
636
|
this.moveplanes = [];
|
|
609
637
|
this.moveplanes2 = [];
|
|
610
638
|
this.faces = [];
|
|
@@ -630,47 +658,47 @@ export class PuzzleGeometry {
|
|
|
630
658
|
throw new Error("Bad shape argument: " + shape);
|
|
631
659
|
}
|
|
632
660
|
this.rotations = closure(g);
|
|
633
|
-
if (this.
|
|
661
|
+
if (this.options.verbosity) {
|
|
634
662
|
console.log("# Rotations: " + this.rotations.length);
|
|
635
663
|
}
|
|
636
664
|
const baseplane = g[0];
|
|
637
665
|
this.baseplanerot = uniqueplanes(baseplane, this.rotations);
|
|
638
666
|
const baseplanes = this.baseplanerot.map((_) => baseplane.rotateplane(_));
|
|
639
667
|
this.baseplanes = baseplanes;
|
|
640
|
-
this.
|
|
668
|
+
this.baseFaceCount = baseplanes.length as BaseFaceCount;
|
|
641
669
|
const net = defaultnets()[baseplanes.length];
|
|
642
670
|
this.net = net;
|
|
643
671
|
this.colors = defaultcolors()[baseplanes.length];
|
|
644
672
|
this.faceorder = defaultfaceorders()[baseplanes.length];
|
|
645
|
-
if (this.
|
|
673
|
+
if (this.options.verbosity > 0) {
|
|
646
674
|
console.log("# Base planes: " + baseplanes.length);
|
|
647
675
|
}
|
|
648
676
|
const baseface = getface(baseplanes);
|
|
649
677
|
const zero = new Quat(0, 0, 0, 0);
|
|
650
|
-
if (this.
|
|
678
|
+
if (this.options.verbosity > 0) {
|
|
651
679
|
console.log("# Face vertices: " + baseface.length);
|
|
652
680
|
}
|
|
653
681
|
const facenormal = baseplanes[0].makenormal();
|
|
654
682
|
const edgenormal = baseface[0].sum(baseface[1]).makenormal();
|
|
655
683
|
const vertexnormal = baseface[0].makenormal();
|
|
656
684
|
const boundary = new Quat(1, facenormal.b, facenormal.c, facenormal.d);
|
|
657
|
-
if (this.
|
|
685
|
+
if (this.options.verbosity > 0) {
|
|
658
686
|
console.log("# Boundary is " + boundary);
|
|
659
687
|
}
|
|
660
688
|
const planerot = uniqueplanes(boundary, this.rotations);
|
|
661
689
|
const planes = planerot.map((_) => boundary.rotateplane(_));
|
|
662
|
-
|
|
663
|
-
this.edgedistance =
|
|
664
|
-
this.vertexdistance =
|
|
690
|
+
const firstface = getface(planes);
|
|
691
|
+
this.edgedistance = firstface[0].sum(firstface[1]).smul(0.5).dist(zero);
|
|
692
|
+
this.vertexdistance = firstface[0].dist(zero);
|
|
665
693
|
const cutplanes = [];
|
|
666
694
|
const intersects = [];
|
|
667
695
|
let sawface = false; // what cuts did we see?
|
|
668
696
|
let sawedge = false;
|
|
669
697
|
let sawvertex = false;
|
|
670
|
-
for (
|
|
698
|
+
for (const cut of cuts) {
|
|
671
699
|
let normal = null;
|
|
672
700
|
let distance = 0;
|
|
673
|
-
switch (
|
|
701
|
+
switch (cut.cutType) {
|
|
674
702
|
case "f":
|
|
675
703
|
normal = facenormal;
|
|
676
704
|
distance = 1;
|
|
@@ -687,12 +715,12 @@ export class PuzzleGeometry {
|
|
|
687
715
|
sawedge = true;
|
|
688
716
|
break;
|
|
689
717
|
default:
|
|
690
|
-
throw new Error("Bad cut argument: " +
|
|
718
|
+
throw new Error("Bad cut argument: " + cut.cutType);
|
|
691
719
|
}
|
|
692
|
-
cutplanes.push(normal.makecut(
|
|
693
|
-
intersects.push(
|
|
720
|
+
cutplanes.push(normal.makecut(cut.distance));
|
|
721
|
+
intersects.push(cut.distance < distance);
|
|
694
722
|
}
|
|
695
|
-
if (this.
|
|
723
|
+
if (this.options.addRotations) {
|
|
696
724
|
if (!sawface) {
|
|
697
725
|
cutplanes.push(facenormal.makecut(10));
|
|
698
726
|
}
|
|
@@ -704,9 +732,9 @@ export class PuzzleGeometry {
|
|
|
704
732
|
}
|
|
705
733
|
}
|
|
706
734
|
this.basefaces = [];
|
|
707
|
-
for (
|
|
708
|
-
const face =
|
|
709
|
-
this.basefaces.push(face);
|
|
735
|
+
for (const baseplanerot of this.baseplanerot) {
|
|
736
|
+
const face = baseplanerot.rotateface(firstface);
|
|
737
|
+
this.basefaces.push(new Face(face));
|
|
710
738
|
}
|
|
711
739
|
//
|
|
712
740
|
// Determine names for edges, vertices, and planes. Planes are defined
|
|
@@ -716,22 +744,22 @@ export class PuzzleGeometry {
|
|
|
716
744
|
// n planes meet at a vertex. We arbitrarily choose the one that is
|
|
717
745
|
// alphabetically first (and we will probably want to change this).
|
|
718
746
|
//
|
|
719
|
-
const facenames:
|
|
720
|
-
const faceplanes = [];
|
|
747
|
+
const facenames: [Quat[], string][] = [];
|
|
748
|
+
const faceplanes: [Quat, string][] = [];
|
|
721
749
|
const vertexnames: any[] = [];
|
|
722
750
|
const edgenames: any[] = [];
|
|
723
|
-
const edgesperface =
|
|
751
|
+
const edgesperface = firstface.length;
|
|
724
752
|
function searchaddelement(a: any[], p: Quat, name: any): void {
|
|
725
|
-
for (
|
|
726
|
-
if (
|
|
727
|
-
|
|
753
|
+
for (const el of a) {
|
|
754
|
+
if (el[0].dist(p) < eps) {
|
|
755
|
+
el.push(name);
|
|
728
756
|
return;
|
|
729
757
|
}
|
|
730
758
|
}
|
|
731
759
|
a.push([p, name]);
|
|
732
760
|
}
|
|
733
761
|
for (let i = 0; i < this.baseplanerot.length; i++) {
|
|
734
|
-
const face = this.baseplanerot[i].rotateface(
|
|
762
|
+
const face = this.baseplanerot[i].rotateface(firstface);
|
|
735
763
|
for (let j = 0; j < face.length; j++) {
|
|
736
764
|
const jj = (j + 1) % face.length;
|
|
737
765
|
const midpoint = face[j].sum(face[jj]).smul(0.5);
|
|
@@ -740,7 +768,7 @@ export class PuzzleGeometry {
|
|
|
740
768
|
}
|
|
741
769
|
const otherfaces = [];
|
|
742
770
|
for (let i = 0; i < this.baseplanerot.length; i++) {
|
|
743
|
-
const face = this.baseplanerot[i].rotateface(
|
|
771
|
+
const face = this.baseplanerot[i].rotateface(firstface);
|
|
744
772
|
const facelist = [];
|
|
745
773
|
for (let j = 0; j < face.length; j++) {
|
|
746
774
|
const jj = (j + 1) % face.length;
|
|
@@ -757,13 +785,13 @@ export class PuzzleGeometry {
|
|
|
757
785
|
otherfaces.push(facelist);
|
|
758
786
|
}
|
|
759
787
|
const facenametoindex: any = {};
|
|
760
|
-
const faceindextoname:
|
|
788
|
+
const faceindextoname: string[] = [];
|
|
761
789
|
faceindextoname.push(net[0][0]);
|
|
762
790
|
facenametoindex[net[0][0]] = 0;
|
|
763
791
|
faceindextoname[otherfaces[0][0]] = net[0][1];
|
|
764
792
|
facenametoindex[net[0][1]] = otherfaces[0][0];
|
|
765
|
-
for (
|
|
766
|
-
const f0 =
|
|
793
|
+
for (const neti of net) {
|
|
794
|
+
const f0 = neti[0];
|
|
767
795
|
const fi = facenametoindex[f0];
|
|
768
796
|
if (fi === undefined) {
|
|
769
797
|
throw new Error("Bad edge description; first edge not connected");
|
|
@@ -771,7 +799,7 @@ export class PuzzleGeometry {
|
|
|
771
799
|
let ii = -1;
|
|
772
800
|
for (let j = 0; j < otherfaces[fi].length; j++) {
|
|
773
801
|
const fn2 = faceindextoname[otherfaces[fi][j]];
|
|
774
|
-
if (fn2 !== undefined && fn2 ===
|
|
802
|
+
if (fn2 !== undefined && fn2 === neti[1]) {
|
|
775
803
|
ii = j;
|
|
776
804
|
break;
|
|
777
805
|
}
|
|
@@ -779,17 +807,17 @@ export class PuzzleGeometry {
|
|
|
779
807
|
if (ii < 0) {
|
|
780
808
|
throw new Error("First element of a net not known");
|
|
781
809
|
}
|
|
782
|
-
for (let j = 2; j <
|
|
783
|
-
if (
|
|
810
|
+
for (let j = 2; j < neti.length; j++) {
|
|
811
|
+
if (neti[j] === "") {
|
|
784
812
|
continue;
|
|
785
813
|
}
|
|
786
814
|
const of = otherfaces[fi][(j + ii - 1) % edgesperface];
|
|
787
815
|
const fn2 = faceindextoname[of];
|
|
788
|
-
if (fn2 !== undefined && fn2 !==
|
|
816
|
+
if (fn2 !== undefined && fn2 !== neti[j]) {
|
|
789
817
|
throw new Error("Face mismatch in net");
|
|
790
818
|
}
|
|
791
|
-
faceindextoname[of] =
|
|
792
|
-
facenametoindex[
|
|
819
|
+
faceindextoname[of] = neti[j];
|
|
820
|
+
facenametoindex[neti[j]] = of;
|
|
793
821
|
}
|
|
794
822
|
}
|
|
795
823
|
for (let i = 0; i < faceindextoname.length; i++) {
|
|
@@ -811,14 +839,14 @@ export class PuzzleGeometry {
|
|
|
811
839
|
}
|
|
812
840
|
}
|
|
813
841
|
for (let i = 0; i < this.baseplanerot.length; i++) {
|
|
814
|
-
const face = this.baseplanerot[i].rotateface(
|
|
842
|
+
const face = this.baseplanerot[i].rotateface(firstface);
|
|
815
843
|
const faceplane = boundary.rotateplane(this.baseplanerot[i]);
|
|
816
844
|
const facename = faceindextoname[i];
|
|
817
845
|
facenames.push([face, facename]);
|
|
818
846
|
faceplanes.push([faceplane, facename]);
|
|
819
847
|
}
|
|
820
848
|
for (let i = 0; i < this.baseplanerot.length; i++) {
|
|
821
|
-
const face = this.baseplanerot[i].rotateface(
|
|
849
|
+
const face = this.baseplanerot[i].rotateface(firstface);
|
|
822
850
|
const facename = faceindextoname[i];
|
|
823
851
|
for (let j = 0; j < face.length; j++) {
|
|
824
852
|
const jj = (j + 1) % face.length;
|
|
@@ -830,7 +858,7 @@ export class PuzzleGeometry {
|
|
|
830
858
|
searchaddelement(vertexnames, face[jj], [facename, e2, e1]);
|
|
831
859
|
}
|
|
832
860
|
}
|
|
833
|
-
this.swizzler = new FaceNameSwizzler(facenames.map((_
|
|
861
|
+
this.swizzler = new FaceNameSwizzler(facenames.map((_) => _[1]));
|
|
834
862
|
const sep = this.swizzler.prefixFree ? "" : "_";
|
|
835
863
|
// fix the edge names; use face precedence order
|
|
836
864
|
for (let i = 0; i < edgenames.length; i++) {
|
|
@@ -850,7 +878,6 @@ export class PuzzleGeometry {
|
|
|
850
878
|
edgenames[i] = [edgenames[i][0], c1];
|
|
851
879
|
}
|
|
852
880
|
// fix the vertex names; counterclockwise rotations; low face first.
|
|
853
|
-
this.cornerfaces = vertexnames[0].length - 1;
|
|
854
881
|
for (let i = 0; i < vertexnames.length; i++) {
|
|
855
882
|
if (vertexnames[i].length < 4) {
|
|
856
883
|
throw new Error("Bad length in vertex names");
|
|
@@ -880,32 +907,34 @@ export class PuzzleGeometry {
|
|
|
880
907
|
}
|
|
881
908
|
vertexnames[i] = [vertexnames[i][0], r];
|
|
882
909
|
}
|
|
883
|
-
if (this.
|
|
910
|
+
if (this.options.verbosity > 1) {
|
|
884
911
|
console.log("# Face precedence list: " + this.faceorder.join(" "));
|
|
885
|
-
console.log("# Face names: " + facenames.map((_
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
912
|
+
console.log("# Face names: " + facenames.map((_) => _[1]).join(" "));
|
|
913
|
+
// TODO
|
|
914
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
915
|
+
console.log("# Edge names: " + edgenames.map((_) => _[1]).join(" "));
|
|
916
|
+
// TODO
|
|
917
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
918
|
+
console.log("# Vertex names: " + vertexnames.map((_) => _[1]).join(" "));
|
|
890
919
|
}
|
|
891
|
-
const geonormals = [];
|
|
892
|
-
for (
|
|
893
|
-
geonormals.push([
|
|
920
|
+
const geonormals: [Quat, string, string][] = [];
|
|
921
|
+
for (const faceplane of faceplanes) {
|
|
922
|
+
geonormals.push([faceplane[0].makenormal(), faceplane[1], "f"]);
|
|
894
923
|
}
|
|
895
|
-
for (
|
|
896
|
-
geonormals.push([
|
|
924
|
+
for (const edgename of edgenames) {
|
|
925
|
+
geonormals.push([edgename[0].makenormal(), edgename[1], "e"]);
|
|
897
926
|
}
|
|
898
|
-
for (
|
|
899
|
-
geonormals.push([
|
|
927
|
+
for (const vertexname of vertexnames) {
|
|
928
|
+
geonormals.push([vertexname[0].makenormal(), vertexname[1], "v"]);
|
|
900
929
|
}
|
|
901
930
|
this.facenames = facenames;
|
|
902
931
|
this.faceplanes = faceplanes;
|
|
903
932
|
this.edgenames = edgenames;
|
|
904
933
|
this.vertexnames = vertexnames;
|
|
905
934
|
this.geonormals = geonormals;
|
|
906
|
-
const geonormalnames = geonormals.map((_
|
|
935
|
+
const geonormalnames = geonormals.map((_) => _[1]);
|
|
907
936
|
this.swizzler.setGripNames(geonormalnames);
|
|
908
|
-
if (this.
|
|
937
|
+
if (this.options.verbosity > 0) {
|
|
909
938
|
console.log(
|
|
910
939
|
"# Distances: face " +
|
|
911
940
|
1 +
|
|
@@ -917,11 +946,11 @@ export class PuzzleGeometry {
|
|
|
917
946
|
}
|
|
918
947
|
// expand cutplanes by rotations. We only work with one face here.
|
|
919
948
|
for (let c = 0; c < cutplanes.length; c++) {
|
|
920
|
-
for (
|
|
921
|
-
const q = cutplanes[c].rotateplane(
|
|
949
|
+
for (const rotation of this.rotations) {
|
|
950
|
+
const q = cutplanes[c].rotateplane(rotation);
|
|
922
951
|
let wasseen = false;
|
|
923
|
-
for (
|
|
924
|
-
if (q.sameplane(
|
|
952
|
+
for (const moveplane of this.moveplanes) {
|
|
953
|
+
if (q.sameplane(moveplane)) {
|
|
925
954
|
wasseen = true;
|
|
926
955
|
break;
|
|
927
956
|
}
|
|
@@ -934,7 +963,7 @@ export class PuzzleGeometry {
|
|
|
934
963
|
}
|
|
935
964
|
}
|
|
936
965
|
}
|
|
937
|
-
let ft = new FaceTree(
|
|
966
|
+
let ft = new FaceTree(firstface);
|
|
938
967
|
const tar = this.moveplanes2.slice();
|
|
939
968
|
// we want to use Math.random() here but we can't, because when
|
|
940
969
|
// we call multiple times we'll get different orbits/layouts.
|
|
@@ -948,27 +977,66 @@ export class PuzzleGeometry {
|
|
|
948
977
|
tar[j] = tar[i];
|
|
949
978
|
rval = (rval * 1657 + 101) % 65536;
|
|
950
979
|
}
|
|
951
|
-
faces = ft.collect([], true);
|
|
980
|
+
const faces = ft.collect([], true);
|
|
952
981
|
this.faces = faces;
|
|
953
|
-
if (this.
|
|
982
|
+
if (this.options.verbosity > 0) {
|
|
954
983
|
console.log("# Faces is now " + faces.length);
|
|
955
984
|
}
|
|
956
985
|
this.stickersperface = faces.length;
|
|
986
|
+
// the faces when rotated don't preserve the vertex order at this
|
|
987
|
+
// point. to improve 3d rendering speed, we would like to preserve
|
|
988
|
+
// vertex order on rotation. First, let's see what rotations preserve
|
|
989
|
+
// the base face; these are the ones we want to work with.
|
|
990
|
+
const simplerot: Quat[] = [];
|
|
991
|
+
const cm = centermassface(firstface);
|
|
992
|
+
for (const rotation of this.rotations) {
|
|
993
|
+
const f = rotation.rotateface(firstface);
|
|
994
|
+
if (cm.dist(centermassface(f)) < eps) {
|
|
995
|
+
simplerot.push(rotation);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
const finished = new Array<boolean>(faces.length);
|
|
999
|
+
const sortme: [number, Quat, number][] = [];
|
|
1000
|
+
for (let i = 0; i < faces.length; i++) {
|
|
1001
|
+
const cm2 = faces[i].centermass();
|
|
1002
|
+
sortme.push([cm.dist(cm2), cm2, i]);
|
|
1003
|
+
}
|
|
1004
|
+
sortme.sort((a, b) => a[0] - b[0]);
|
|
1005
|
+
for (let ii = 0; ii < faces.length; ii++) {
|
|
1006
|
+
const i = sortme[ii][2];
|
|
1007
|
+
if (!finished[i]) {
|
|
1008
|
+
finished[i] = true;
|
|
1009
|
+
for (const rot of simplerot) {
|
|
1010
|
+
const f2 = faces[i].rotate(rot);
|
|
1011
|
+
const cm = f2.centermass();
|
|
1012
|
+
for (let kk = ii + 1; kk < faces.length; kk++) {
|
|
1013
|
+
if (sortme[kk][0] - sortme[ii][0] > eps) {
|
|
1014
|
+
break;
|
|
1015
|
+
}
|
|
1016
|
+
const k = sortme[kk][2];
|
|
1017
|
+
if (!finished[k] && cm.dist(sortme[kk][1]) < eps) {
|
|
1018
|
+
finished[k] = true;
|
|
1019
|
+
faces[k] = f2;
|
|
1020
|
+
break;
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
957
1026
|
// Find and report the shortest edge in any of the faces. If this
|
|
958
1027
|
// is small the puzzle is probably not practical or displayable.
|
|
959
|
-
|
|
960
|
-
for (
|
|
961
|
-
for (let j = 0; j <
|
|
962
|
-
const k = (j + 1) %
|
|
963
|
-
const t =
|
|
964
|
-
if (t < shortedge) {
|
|
965
|
-
shortedge = t;
|
|
1028
|
+
this.shortedge = 1e99;
|
|
1029
|
+
for (const face of faces) {
|
|
1030
|
+
for (let j = 0; j < face.length; j++) {
|
|
1031
|
+
const k = (j + 1) % face.length;
|
|
1032
|
+
const t = face.get(j).dist(face.get(k));
|
|
1033
|
+
if (t < this.shortedge) {
|
|
1034
|
+
this.shortedge = t;
|
|
966
1035
|
}
|
|
967
1036
|
}
|
|
968
1037
|
}
|
|
969
|
-
this.
|
|
970
|
-
|
|
971
|
-
console.log("# Short edge is " + shortedge);
|
|
1038
|
+
if (this.options.verbosity > 0) {
|
|
1039
|
+
console.log("# Short edge is " + this.shortedge);
|
|
972
1040
|
}
|
|
973
1041
|
// add nxnxn cube notation if it has cube face moves
|
|
974
1042
|
if (shape === "c" && sawface && !sawedge && !sawvertex) {
|
|
@@ -984,7 +1052,7 @@ export class PuzzleGeometry {
|
|
|
984
1052
|
if (shape === "t" && (sawvertex || sawface) && !sawedge) {
|
|
985
1053
|
this.addNotationMapper = "PyraminxOrTetraminxMapper";
|
|
986
1054
|
}
|
|
987
|
-
if (shape === "o" && sawface
|
|
1055
|
+
if (shape === "o" && sawface) {
|
|
988
1056
|
this.notationMapper = new FaceRenamingMapper(
|
|
989
1057
|
this.swizzler,
|
|
990
1058
|
new FaceNameSwizzler(["F", "D", "L", "BL", "R", "U", "BR", "B"]),
|
|
@@ -993,7 +1061,7 @@ export class PuzzleGeometry {
|
|
|
993
1061
|
this.addNotationMapper = "FTOMapper";
|
|
994
1062
|
}
|
|
995
1063
|
}
|
|
996
|
-
if (shape === "d" && sawface
|
|
1064
|
+
if (shape === "d" && sawface) {
|
|
997
1065
|
this.addNotationMapper = "MegaminxMapper";
|
|
998
1066
|
this.notationMapper = new FaceRenamingMapper(
|
|
999
1067
|
this.swizzler,
|
|
@@ -1015,67 +1083,78 @@ export class PuzzleGeometry {
|
|
|
1015
1083
|
}
|
|
1016
1084
|
}
|
|
1017
1085
|
|
|
1018
|
-
|
|
1019
|
-
return this.keyface2(
|
|
1086
|
+
private keyface(face: Face): string {
|
|
1087
|
+
return this.keyface2(face.centermass());
|
|
1020
1088
|
}
|
|
1021
1089
|
|
|
1022
|
-
|
|
1090
|
+
private keyface2(cm: Quat): string {
|
|
1023
1091
|
// take a face and figure out the sides of each move plane
|
|
1024
1092
|
let s = "";
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1093
|
+
const sfcc = String.fromCharCode;
|
|
1094
|
+
for (const moveplaneset of this.moveplanesets) {
|
|
1095
|
+
if (moveplaneset.length > 0) {
|
|
1096
|
+
const dv = cm.dot(moveplaneset[0]);
|
|
1028
1097
|
let t = 0;
|
|
1029
1098
|
let b = 1;
|
|
1030
|
-
while (b * 2 <=
|
|
1099
|
+
while (b * 2 <= moveplaneset.length) {
|
|
1031
1100
|
b *= 2;
|
|
1032
1101
|
}
|
|
1033
1102
|
for (; b > 0; b >>= 1) {
|
|
1034
|
-
if (
|
|
1035
|
-
t + b <= this.moveplanesets[i].length &&
|
|
1036
|
-
dv > this.moveplanesets[i][t + b - 1].a
|
|
1037
|
-
) {
|
|
1103
|
+
if (t + b <= moveplaneset.length && dv > moveplaneset[t + b - 1].a) {
|
|
1038
1104
|
t += b;
|
|
1039
1105
|
}
|
|
1040
1106
|
}
|
|
1041
|
-
if (t
|
|
1042
|
-
s = s +
|
|
1043
|
-
} else {
|
|
1107
|
+
if (t < 47) {
|
|
1108
|
+
s = s + sfcc(33 + t);
|
|
1109
|
+
} else if (t < 47 + 47 * 47) {
|
|
1110
|
+
s = s + sfcc(33 + 47 + Math.floor(t / 47) - 1) + sfcc(33 + (t % 47));
|
|
1111
|
+
} else if (t < 47 + 47 * 47 + 47 * 47 * 47) {
|
|
1044
1112
|
s =
|
|
1045
1113
|
s +
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1114
|
+
sfcc(33 + 47 + Math.floor((t - 47) / (47 * 47) - 1)) +
|
|
1115
|
+
sfcc(33 + 47 + (Math.floor((t - 47) / 47) % 47)) +
|
|
1116
|
+
sfcc(33 + (t % 47));
|
|
1117
|
+
} else {
|
|
1118
|
+
throw Error("Too many slices for cubie encoding");
|
|
1049
1119
|
}
|
|
1050
1120
|
}
|
|
1051
1121
|
}
|
|
1052
1122
|
return s;
|
|
1053
1123
|
}
|
|
1054
1124
|
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
const
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1125
|
+
// same as above, but instead of returning an encoded string, return
|
|
1126
|
+
// an array with offsets.
|
|
1127
|
+
private keyface3(face: Face): number[] {
|
|
1128
|
+
const cm = face.centermass();
|
|
1129
|
+
// take a face and figure out the sides of each move plane
|
|
1130
|
+
const r = [];
|
|
1131
|
+
for (const moveplaneset of this.moveplanesets) {
|
|
1132
|
+
if (moveplaneset.length > 0) {
|
|
1133
|
+
const dv = cm.dot(moveplaneset[0]);
|
|
1134
|
+
let t = 0;
|
|
1135
|
+
let b = 1;
|
|
1136
|
+
while (b * 2 <= moveplaneset.length) {
|
|
1137
|
+
b *= 2;
|
|
1138
|
+
}
|
|
1139
|
+
for (; b > 0; b >>= 1) {
|
|
1140
|
+
if (t + b <= moveplaneset.length && dv > moveplaneset[t + b - 1].a) {
|
|
1141
|
+
t += b;
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
r.push(t);
|
|
1066
1145
|
}
|
|
1067
1146
|
}
|
|
1068
|
-
return
|
|
1147
|
+
return r;
|
|
1069
1148
|
}
|
|
1070
1149
|
|
|
1071
|
-
|
|
1150
|
+
private findface(cm: Quat): number {
|
|
1072
1151
|
const key = this.keyface2(cm);
|
|
1073
|
-
const arr = this.facelisthash
|
|
1152
|
+
const arr = this.facelisthash.get(key)!;
|
|
1074
1153
|
if (arr.length === 1) {
|
|
1075
1154
|
return arr[0];
|
|
1076
1155
|
}
|
|
1077
1156
|
for (let i = 0; i + 1 < arr.length; i++) {
|
|
1078
|
-
const face2 = this.facelisthash
|
|
1157
|
+
const face2 = this.facelisthash.get(key)![i];
|
|
1079
1158
|
if (Math.abs(cm.dist(this.facecentermass[face2])) < eps) {
|
|
1080
1159
|
return face2;
|
|
1081
1160
|
}
|
|
@@ -1083,7 +1162,11 @@ export class PuzzleGeometry {
|
|
|
1083
1162
|
return arr[arr.length - 1];
|
|
1084
1163
|
}
|
|
1085
1164
|
|
|
1086
|
-
|
|
1165
|
+
private project2d(
|
|
1166
|
+
facen: number,
|
|
1167
|
+
edgen: number,
|
|
1168
|
+
targvec: Quat[],
|
|
1169
|
+
): [Quat, Quat, Quat] {
|
|
1087
1170
|
// calculate geometry to map a particular edge of a particular
|
|
1088
1171
|
// face to a given 2D vector. The face is given as an index into the
|
|
1089
1172
|
// facenames/baseplane arrays, and the edge is given as an offset into
|
|
@@ -1112,28 +1195,28 @@ export class PuzzleGeometry {
|
|
|
1112
1195
|
}
|
|
1113
1196
|
|
|
1114
1197
|
public allstickers(): void {
|
|
1198
|
+
const t1 = tstart("allstickers");
|
|
1115
1199
|
// next step is to calculate all the stickers and orbits
|
|
1116
1200
|
// We do enough work here to display the cube on the screen.
|
|
1117
1201
|
// take our newly split base face and expand it by the rotation matrix.
|
|
1118
1202
|
// this generates our full set of "stickers".
|
|
1119
1203
|
this.faces = expandfaces(this.baseplanerot, this.faces);
|
|
1120
|
-
if (this.
|
|
1204
|
+
if (this.options.verbosity > 0) {
|
|
1121
1205
|
console.log("# Total stickers is now " + this.faces.length);
|
|
1122
1206
|
}
|
|
1123
1207
|
this.facecentermass = new Array(this.faces.length);
|
|
1124
1208
|
for (let i = 0; i < this.faces.length; i++) {
|
|
1125
|
-
this.facecentermass[i] =
|
|
1209
|
+
this.facecentermass[i] = this.faces[i].centermass();
|
|
1126
1210
|
}
|
|
1127
1211
|
// Split moveplanes into a list of parallel planes.
|
|
1128
1212
|
const moveplanesets: Quat[][] = [];
|
|
1129
1213
|
const moveplanenormals: Quat[] = [];
|
|
1130
1214
|
// get the normals, first, from unfiltered moveplanes.
|
|
1131
|
-
for (
|
|
1132
|
-
const q = this.moveplanes[i];
|
|
1215
|
+
for (const q of this.moveplanes) {
|
|
1133
1216
|
const qnormal = q.makenormal();
|
|
1134
1217
|
let wasseen = false;
|
|
1135
|
-
for (
|
|
1136
|
-
if (qnormal.sameplane(
|
|
1218
|
+
for (const moveplanenormal of moveplanenormals) {
|
|
1219
|
+
if (qnormal.sameplane(moveplanenormal.makenormal())) {
|
|
1137
1220
|
wasseen = true;
|
|
1138
1221
|
}
|
|
1139
1222
|
}
|
|
@@ -1142,8 +1225,7 @@ export class PuzzleGeometry {
|
|
|
1142
1225
|
moveplanesets.push([]);
|
|
1143
1226
|
}
|
|
1144
1227
|
}
|
|
1145
|
-
for (
|
|
1146
|
-
const q = this.moveplanes2[i];
|
|
1228
|
+
for (const q of this.moveplanes2) {
|
|
1147
1229
|
const qnormal = q.makenormal();
|
|
1148
1230
|
for (let j = 0; j < moveplanenormals.length; j++) {
|
|
1149
1231
|
if (qnormal.sameplane(moveplanenormals[j])) {
|
|
@@ -1167,7 +1249,7 @@ export class PuzzleGeometry {
|
|
|
1167
1249
|
this.moveplanesets = moveplanesets;
|
|
1168
1250
|
this.moveplanenormals = moveplanenormals;
|
|
1169
1251
|
const sizes = moveplanesets.map((_) => _.length);
|
|
1170
|
-
if (this.
|
|
1252
|
+
if (this.options.verbosity > 0) {
|
|
1171
1253
|
console.log("# Move plane sets: " + sizes);
|
|
1172
1254
|
}
|
|
1173
1255
|
// for each of the move planes, find the rotations that are relevant
|
|
@@ -1175,8 +1257,7 @@ export class PuzzleGeometry {
|
|
|
1175
1257
|
for (let i = 0; i < moveplanesets.length; i++) {
|
|
1176
1258
|
moverotations.push([]);
|
|
1177
1259
|
}
|
|
1178
|
-
for (
|
|
1179
|
-
const q: Quat = this.rotations[i];
|
|
1260
|
+
for (const q of this.rotations) {
|
|
1180
1261
|
if (Math.abs(Math.abs(q.a) - 1) < eps) {
|
|
1181
1262
|
continue;
|
|
1182
1263
|
}
|
|
@@ -1207,20 +1288,20 @@ export class PuzzleGeometry {
|
|
|
1207
1288
|
}
|
|
1208
1289
|
const sizes2 = moverotations.map((_) => 1 + _.length);
|
|
1209
1290
|
this.movesetorders = sizes2;
|
|
1210
|
-
const movesetgeos = [];
|
|
1291
|
+
const movesetgeos: [string, string, string, string, number][] = [];
|
|
1211
1292
|
let gtype = "?";
|
|
1212
1293
|
for (let i = 0; i < moveplanesets.length; i++) {
|
|
1213
1294
|
const p0 = moveplanenormals[i];
|
|
1214
1295
|
let neg = null;
|
|
1215
1296
|
let pos = null;
|
|
1216
|
-
for (
|
|
1217
|
-
const d = p0.dot(
|
|
1297
|
+
for (const geonormal of this.geonormals) {
|
|
1298
|
+
const d = p0.dot(geonormal[0]);
|
|
1218
1299
|
if (Math.abs(d - 1) < eps) {
|
|
1219
|
-
pos = [
|
|
1220
|
-
gtype =
|
|
1300
|
+
pos = [geonormal[1], geonormal[2]];
|
|
1301
|
+
gtype = geonormal[2];
|
|
1221
1302
|
} else if (Math.abs(d + 1) < eps) {
|
|
1222
|
-
neg = [
|
|
1223
|
-
gtype =
|
|
1303
|
+
neg = [geonormal[1], geonormal[2]];
|
|
1304
|
+
gtype = geonormal[2];
|
|
1224
1305
|
}
|
|
1225
1306
|
}
|
|
1226
1307
|
if (pos === null || neg === null) {
|
|
@@ -1283,128 +1364,100 @@ export class PuzzleGeometry {
|
|
|
1283
1364
|
// This also works for faces; no face should ever lie on a move
|
|
1284
1365
|
// plane. This allows us to take a set of stickers and break
|
|
1285
1366
|
// them up into cubie sets.
|
|
1286
|
-
const
|
|
1287
|
-
const facelisthash: any = {};
|
|
1288
|
-
const cubiekey: any = {};
|
|
1289
|
-
const cubiekeys = [];
|
|
1290
|
-
const cubies: Quat[][][] = [];
|
|
1367
|
+
const facelisthash = new Map();
|
|
1291
1368
|
const faces = this.faces;
|
|
1292
1369
|
for (let i = 0; i < faces.length; i++) {
|
|
1293
1370
|
const face = faces[i];
|
|
1294
1371
|
const s = this.keyface(face);
|
|
1295
|
-
if (!
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
cubies
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
const s2 = s + " " + suff;
|
|
1313
|
-
facelisthash[s2] = [facelisthash[s][suff]];
|
|
1314
|
-
cubiehash[s2] = [cubiehash[s][suff]];
|
|
1315
|
-
cubiekeys.push(s2);
|
|
1316
|
-
cubiekey[s2] = cubies.length;
|
|
1317
|
-
cubies.push(cubiehash[s2]);
|
|
1318
|
-
}
|
|
1319
|
-
cubiehash[s] = [];
|
|
1320
|
-
cubies[cubiekey[s]] = [];
|
|
1321
|
-
}
|
|
1322
|
-
}
|
|
1323
|
-
this.cubiekey = cubiekey;
|
|
1324
|
-
this.facelisthash = facelisthash;
|
|
1325
|
-
this.cubiekeys = cubiekeys;
|
|
1326
|
-
if (this.verbose) {
|
|
1327
|
-
console.log("# Cubies: " + Object.keys(cubiehash).length);
|
|
1328
|
-
}
|
|
1329
|
-
// Sort the faces around each corner so they are counterclockwise. Only
|
|
1330
|
-
// relevant for cubies that actually are corners (three or more
|
|
1331
|
-
// faces). In general cubies might have many faces; for icosohedrons
|
|
1332
|
-
// there are five faces on the corner cubies.
|
|
1333
|
-
this.cubies = cubies;
|
|
1334
|
-
for (let k = 0; k < cubies.length; k++) {
|
|
1335
|
-
const cubie = cubies[k];
|
|
1336
|
-
if (cubie.length < 2) {
|
|
1337
|
-
continue;
|
|
1372
|
+
if (!facelisthash.get(s)) {
|
|
1373
|
+
facelisthash.set(s, [i]);
|
|
1374
|
+
} else {
|
|
1375
|
+
const arr = facelisthash.get(s)!;
|
|
1376
|
+
arr.push(i);
|
|
1377
|
+
// If we find a core cubie, split it up into multiple cubies,
|
|
1378
|
+
// because ksolve doesn't handle orientations that are not
|
|
1379
|
+
// cyclic, and the rotation group of the core is not cyclic.
|
|
1380
|
+
if (arr.length === this.baseFaceCount) {
|
|
1381
|
+
if (this.options.verbosity > 0) {
|
|
1382
|
+
console.log("# Splitting core.");
|
|
1383
|
+
}
|
|
1384
|
+
for (let suff = 0; suff < arr.length; suff++) {
|
|
1385
|
+
const s2 = s + " " + suff;
|
|
1386
|
+
facelisthash.set(s2, [arr[suff]]);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1338
1389
|
}
|
|
1339
|
-
|
|
1340
|
-
|
|
1390
|
+
}
|
|
1391
|
+
this.facelisthash = facelisthash;
|
|
1392
|
+
if (this.options.verbosity > 0) {
|
|
1393
|
+
console.log("# Cubies: " + facelisthash.size);
|
|
1394
|
+
}
|
|
1395
|
+
const cubies: number[][] = [];
|
|
1396
|
+
const facetocubie = [];
|
|
1397
|
+
const facetoord = [];
|
|
1398
|
+
for (const facelist of facelisthash.values()) {
|
|
1399
|
+
if (facelist.length === this.baseFaceCount) {
|
|
1400
|
+
// this is the original "cubie" of a split core; we ignore it.
|
|
1341
1401
|
continue;
|
|
1342
1402
|
}
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1403
|
+
// Sort the faces around each corner so they are counterclockwise. Only
|
|
1404
|
+
// relevant for cubies that actually are corners (three or more
|
|
1405
|
+
// faces). In general cubies might have many faces; for icosohedrons
|
|
1406
|
+
// there are five faces on the corner cubies.
|
|
1407
|
+
if (facelist.length > 1) {
|
|
1408
|
+
const cm = facelist.map((_: number) => faces[_].centermass());
|
|
1409
|
+
const cmall = centermassface(cm);
|
|
1410
|
+
for (let looplimit = 0; facelist.length > 2; looplimit++) {
|
|
1411
|
+
let changed = false;
|
|
1412
|
+
for (let i = 0; i < facelist.length; i++) {
|
|
1413
|
+
const j = (i + 1) % facelist.length;
|
|
1414
|
+
// var ttt = cmall.dot(cm[i].cross(cm[j])) ; // TODO
|
|
1415
|
+
if (cmall.dot(cm[i].cross(cm[j])) < 0) {
|
|
1416
|
+
const u = cm[i];
|
|
1417
|
+
cm[i] = cm[j];
|
|
1418
|
+
cm[j] = u;
|
|
1419
|
+
const v = facelist[i];
|
|
1420
|
+
facelist[i] = facelist[j];
|
|
1421
|
+
facelist[j] = v;
|
|
1422
|
+
changed = true;
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
if (!changed) {
|
|
1426
|
+
break;
|
|
1427
|
+
}
|
|
1428
|
+
if (looplimit > 1000) {
|
|
1429
|
+
throw new Error("Bad epsilon math; too close to border");
|
|
1368
1430
|
}
|
|
1369
1431
|
}
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
if (
|
|
1382
|
-
this.faceprecedence[this.getfaceindex(temp)] <
|
|
1383
|
-
this.faceprecedence[this.getfaceindex(minf)]
|
|
1384
|
-
) {
|
|
1385
|
-
mini = i;
|
|
1386
|
-
minf = temp;
|
|
1432
|
+
let mini = 0;
|
|
1433
|
+
let minf = facelist[mini];
|
|
1434
|
+
for (let i = 1; i < facelist.length; i++) {
|
|
1435
|
+
const temp = facelist[i];
|
|
1436
|
+
if (
|
|
1437
|
+
this.faceprecedence[this.getfaceindex(temp)] <
|
|
1438
|
+
this.faceprecedence[this.getfaceindex(minf)]
|
|
1439
|
+
) {
|
|
1440
|
+
mini = i;
|
|
1441
|
+
minf = temp;
|
|
1442
|
+
}
|
|
1387
1443
|
}
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
cubie[i] = ocubie[(mini + i) % cubie.length];
|
|
1394
|
-
facelist[i] = ofacelist[(mini + i) % cubie.length];
|
|
1444
|
+
if (mini !== 0) {
|
|
1445
|
+
const ofacelist = facelist.slice();
|
|
1446
|
+
for (let i = 0; i < facelist.length; i++) {
|
|
1447
|
+
facelist[i] = ofacelist[(mini + i) % facelist.length];
|
|
1448
|
+
}
|
|
1395
1449
|
}
|
|
1396
1450
|
}
|
|
1397
|
-
}
|
|
1398
|
-
// Build an array that takes each face to a cubie ordinal and a
|
|
1399
|
-
// face number.
|
|
1400
|
-
const facetocubies = [];
|
|
1401
|
-
for (let i = 0; i < cubies.length; i++) {
|
|
1402
|
-
const facelist = facelisthash[cubiekeys[i]];
|
|
1403
1451
|
for (let j = 0; j < facelist.length; j++) {
|
|
1404
|
-
|
|
1452
|
+
const k = facelist[j];
|
|
1453
|
+
facetocubie[k] = cubies.length;
|
|
1454
|
+
facetoord[k] = j;
|
|
1405
1455
|
}
|
|
1456
|
+
cubies.push(facelist);
|
|
1406
1457
|
}
|
|
1407
|
-
this.
|
|
1458
|
+
this.cubies = cubies;
|
|
1459
|
+
this.facetocubie = facetocubie;
|
|
1460
|
+
this.facetoord = facetoord;
|
|
1408
1461
|
// Calculate the orbits of each cubie. Assumes we do all moves.
|
|
1409
1462
|
// Also calculates which cubies are identical.
|
|
1410
1463
|
const typenames = ["?", "CENTERS", "EDGES", "CORNERS", "C4RNER", "C5RNER"];
|
|
@@ -1416,14 +1469,11 @@ export class PuzzleGeometry {
|
|
|
1416
1469
|
const cubiesetnums = [];
|
|
1417
1470
|
const cubieordnums = [];
|
|
1418
1471
|
const cubieords = [];
|
|
1419
|
-
// var cubiesetnumhash = {} ; // TODO
|
|
1420
1472
|
const cubievaluemap = [];
|
|
1421
1473
|
// Later we will make this smarter to use a get color for face function
|
|
1422
1474
|
// so we support puzzles with multiple faces the same color
|
|
1423
1475
|
const getcolorkey = (cubienum: number): string => {
|
|
1424
|
-
return cubies[cubienum]
|
|
1425
|
-
.map((_) => this.getfaceindex(this.findface(_)))
|
|
1426
|
-
.join(" ");
|
|
1476
|
+
return cubies[cubienum].map((_) => this.getfaceindex(_)).join(" ");
|
|
1427
1477
|
};
|
|
1428
1478
|
const cubiesetcubies: any = [];
|
|
1429
1479
|
for (let i = 0; i < cubies.length; i++) {
|
|
@@ -1441,7 +1491,7 @@ export class PuzzleGeometry {
|
|
|
1441
1491
|
const facecnt = cubie.length;
|
|
1442
1492
|
const typectr = cubietypecounts[facecnt]++;
|
|
1443
1493
|
let typename = typenames[facecnt];
|
|
1444
|
-
if (typename === undefined || facecnt === this.
|
|
1494
|
+
if (typename === undefined || facecnt === this.baseFaceCount) {
|
|
1445
1495
|
typename = "CORE";
|
|
1446
1496
|
}
|
|
1447
1497
|
typename = typename + (typectr === 0 ? "" : typectr + 1);
|
|
@@ -1461,12 +1511,10 @@ export class PuzzleGeometry {
|
|
|
1461
1511
|
cubiesetcubies[cubiesetnum].push(cind);
|
|
1462
1512
|
cubieordnums[cind] = cubieords[cubiesetnum]++;
|
|
1463
1513
|
if (queue.length < this.rotations.length) {
|
|
1464
|
-
const cm =
|
|
1465
|
-
for (
|
|
1514
|
+
const cm = this.facecentermass[cubies[cind][0]];
|
|
1515
|
+
for (const moverotation of moverotations) {
|
|
1466
1516
|
const tq =
|
|
1467
|
-
this.
|
|
1468
|
-
this.findface2(cm.rotatepoint(moverotations[j][0]))
|
|
1469
|
-
][0];
|
|
1517
|
+
this.facetocubie[this.findface(cm.rotatepoint(moverotation[0]))];
|
|
1470
1518
|
if (!seen[tq]) {
|
|
1471
1519
|
queue.push(tq);
|
|
1472
1520
|
seen[tq] = true;
|
|
@@ -1474,21 +1522,6 @@ export class PuzzleGeometry {
|
|
|
1474
1522
|
}
|
|
1475
1523
|
}
|
|
1476
1524
|
}
|
|
1477
|
-
const that = this;
|
|
1478
|
-
queue.sort(function (a: number, b: number): number {
|
|
1479
|
-
if (that.cubiekeys[a] < that.cubiekeys[b]) {
|
|
1480
|
-
return 1;
|
|
1481
|
-
} else if (that.cubiekeys[a] > that.cubiekeys[b]) {
|
|
1482
|
-
return -1;
|
|
1483
|
-
} else {
|
|
1484
|
-
return 0;
|
|
1485
|
-
}
|
|
1486
|
-
});
|
|
1487
|
-
for (let i = 0; i < queue.length; i++) {
|
|
1488
|
-
if (i > 1000000) {
|
|
1489
|
-
cubieordnums[queue[i]] = i;
|
|
1490
|
-
}
|
|
1491
|
-
}
|
|
1492
1525
|
cubiesetnum++;
|
|
1493
1526
|
}
|
|
1494
1527
|
if (
|
|
@@ -1515,32 +1548,27 @@ export class PuzzleGeometry {
|
|
|
1515
1548
|
["U", "L", "F", "R", "B", "D"],
|
|
1516
1549
|
];
|
|
1517
1550
|
const reidmap: { [key: number]: number } = {};
|
|
1518
|
-
for (
|
|
1519
|
-
for (let j = 0; j <
|
|
1551
|
+
for (const cubie of reidorder) {
|
|
1552
|
+
for (let j = 0; j < cubie.length; j++) {
|
|
1520
1553
|
let mask = 0;
|
|
1521
|
-
for (let k = 0; k <
|
|
1522
|
-
mask |= 1 << (
|
|
1554
|
+
for (let k = 0; k < cubie[j].length; k++) {
|
|
1555
|
+
mask |= 1 << (cubie[j].charCodeAt(k) - 65);
|
|
1523
1556
|
}
|
|
1524
1557
|
reidmap[mask] = j;
|
|
1525
1558
|
}
|
|
1526
1559
|
}
|
|
1527
|
-
for (
|
|
1528
|
-
for (
|
|
1529
|
-
const cubienum = cubiesetcubies[i][j];
|
|
1560
|
+
for (const cubieset of cubiesetcubies) {
|
|
1561
|
+
for (const cubienum of cubieset) {
|
|
1530
1562
|
let mask = 0;
|
|
1531
|
-
for (
|
|
1563
|
+
for (const cubie of cubies[cubienum]) {
|
|
1532
1564
|
mask |=
|
|
1533
1565
|
1 <<
|
|
1534
|
-
(this.facenames[
|
|
1535
|
-
this.getfaceindex(this.findface(cubies[cubienum][k]))
|
|
1536
|
-
][1].charCodeAt(0) -
|
|
1537
|
-
65);
|
|
1566
|
+
(this.facenames[this.getfaceindex(cubie)][1].charCodeAt(0) - 65);
|
|
1538
1567
|
}
|
|
1539
1568
|
cubieordnums[cubienum] = reidmap[mask];
|
|
1540
1569
|
}
|
|
1541
1570
|
}
|
|
1542
1571
|
}
|
|
1543
|
-
this.orbits = cubieords.length;
|
|
1544
1572
|
this.cubiesetnums = cubiesetnums;
|
|
1545
1573
|
this.cubieordnums = cubieordnums;
|
|
1546
1574
|
this.cubiesetnames = cubiesetnames;
|
|
@@ -1549,12 +1577,12 @@ export class PuzzleGeometry {
|
|
|
1549
1577
|
this.cubievaluemap = cubievaluemap;
|
|
1550
1578
|
this.cubiesetcubies = cubiesetcubies;
|
|
1551
1579
|
// if we fix a cubie, find a cubie to fix
|
|
1552
|
-
if (this.
|
|
1580
|
+
if (this.options.fixedPieceType !== null) {
|
|
1553
1581
|
for (let i = 0; i < cubies.length; i++) {
|
|
1554
1582
|
if (
|
|
1555
|
-
(this.
|
|
1556
|
-
(this.
|
|
1557
|
-
(this.
|
|
1583
|
+
(this.options.fixedPieceType === "v" && cubies[i].length > 2) ||
|
|
1584
|
+
(this.options.fixedPieceType === "e" && cubies[i].length === 2) ||
|
|
1585
|
+
(this.options.fixedPieceType === "f" && cubies[i].length === 1)
|
|
1558
1586
|
) {
|
|
1559
1587
|
this.fixedCubie = i;
|
|
1560
1588
|
break;
|
|
@@ -1562,14 +1590,17 @@ export class PuzzleGeometry {
|
|
|
1562
1590
|
}
|
|
1563
1591
|
if (this.fixedCubie < 0) {
|
|
1564
1592
|
throw new Error(
|
|
1565
|
-
"Could not find a cubie of type " +
|
|
1593
|
+
"Could not find a cubie of type " +
|
|
1594
|
+
this.options.fixedPieceType +
|
|
1595
|
+
" to fix.",
|
|
1566
1596
|
);
|
|
1567
1597
|
}
|
|
1568
1598
|
}
|
|
1569
1599
|
// show the orbits
|
|
1570
|
-
if (this.
|
|
1600
|
+
if (this.options.verbosity > 0) {
|
|
1571
1601
|
console.log("# Cubie orbit sizes " + cubieords);
|
|
1572
1602
|
}
|
|
1603
|
+
tend(t1);
|
|
1573
1604
|
}
|
|
1574
1605
|
|
|
1575
1606
|
public unswizzle(mv: Move): string {
|
|
@@ -1582,7 +1613,7 @@ export class PuzzleGeometry {
|
|
|
1582
1613
|
|
|
1583
1614
|
// We use an extremely permissive parse here; any character but
|
|
1584
1615
|
// digits are allowed in a family name.
|
|
1585
|
-
|
|
1616
|
+
private stringToBlockMove(mv: string): Move {
|
|
1586
1617
|
// parse a move from the command line
|
|
1587
1618
|
const re = RegExp("^(([0-9]+)-)?([0-9]+)?([^0-9]+)([0-9]+'?)?$");
|
|
1588
1619
|
const p = mv.match(re);
|
|
@@ -1613,7 +1644,9 @@ export class PuzzleGeometry {
|
|
|
1613
1644
|
return new Move(new QuantumMove(grip, hislice, loslice), amount);
|
|
1614
1645
|
}
|
|
1615
1646
|
|
|
1616
|
-
public parseMove(
|
|
1647
|
+
public parseMove(
|
|
1648
|
+
move: Move,
|
|
1649
|
+
): [string | undefined, number, number, number, boolean, number] {
|
|
1617
1650
|
const bm = this.notationMapper.notationToInternal(move); // pluggable notation
|
|
1618
1651
|
if (bm === null) {
|
|
1619
1652
|
throw new Error("Bad move " + move.family);
|
|
@@ -1707,17 +1740,19 @@ export class PuzzleGeometry {
|
|
|
1707
1740
|
"! full puzzle rotations must be specified with v suffix.",
|
|
1708
1741
|
);
|
|
1709
1742
|
}
|
|
1710
|
-
|
|
1711
|
-
return r;
|
|
1743
|
+
return [undefined, msi, loslice, hislice, firstgrip, move.amount];
|
|
1712
1744
|
}
|
|
1713
1745
|
|
|
1714
|
-
|
|
1746
|
+
private parsemove(
|
|
1747
|
+
mv: string,
|
|
1748
|
+
): [string | undefined, number, number, number, boolean, number] {
|
|
1715
1749
|
const r = this.parseMove(this.stringToBlockMove(mv));
|
|
1716
1750
|
r[0] = mv;
|
|
1717
1751
|
return r;
|
|
1718
1752
|
}
|
|
1719
1753
|
|
|
1720
1754
|
public genperms(): void {
|
|
1755
|
+
const t1 = tstart("genperms");
|
|
1721
1756
|
// generate permutations for moves
|
|
1722
1757
|
if (this.cmovesbyslice.length > 0) {
|
|
1723
1758
|
// did this already?
|
|
@@ -1727,18 +1762,17 @@ export class PuzzleGeometry {
|
|
|
1727
1762
|
// if orientCenters is set, we find all cubies that have only one
|
|
1728
1763
|
// sticker and that sticker is in the center of a face, and we
|
|
1729
1764
|
// introduce duplicate stickers so we can orient them properly.
|
|
1730
|
-
if (this.orientCenters) {
|
|
1765
|
+
if (this.options.orientCenters) {
|
|
1731
1766
|
for (let k = 0; k < this.cubies.length; k++) {
|
|
1732
1767
|
if (this.cubies[k].length === 1) {
|
|
1733
|
-
const kk = this.
|
|
1768
|
+
const kk = this.cubies[k][0];
|
|
1734
1769
|
const i = this.getfaceindex(kk);
|
|
1735
1770
|
if (
|
|
1736
|
-
|
|
1737
|
-
eps
|
|
1771
|
+
this.basefaces[i].centermass().dist(this.facecentermass[kk]) < eps
|
|
1738
1772
|
) {
|
|
1739
1773
|
const o = this.basefaces[i].length;
|
|
1740
|
-
for (let m =
|
|
1741
|
-
this.cubies[k].push(this.cubies[k][
|
|
1774
|
+
for (let m = 1; m < o; m++) {
|
|
1775
|
+
this.cubies[k].push(this.cubies[k][m - 1]);
|
|
1742
1776
|
}
|
|
1743
1777
|
this.duplicatedFaces[kk] = o;
|
|
1744
1778
|
this.duplicatedCubies[k] = o;
|
|
@@ -1784,7 +1818,7 @@ export class PuzzleGeometry {
|
|
|
1784
1818
|
if (slicenum[i] < 0) {
|
|
1785
1819
|
continue;
|
|
1786
1820
|
}
|
|
1787
|
-
const b = this.
|
|
1821
|
+
const b = [this.facetocubie[i], this.facetoord[i]];
|
|
1788
1822
|
let cm = this.facecentermass[i];
|
|
1789
1823
|
const ocm = cm;
|
|
1790
1824
|
let fi2 = i;
|
|
@@ -1795,9 +1829,8 @@ export class PuzzleGeometry {
|
|
|
1795
1829
|
if (cm2.dist(ocm) < eps) {
|
|
1796
1830
|
break;
|
|
1797
1831
|
}
|
|
1798
|
-
fi2 = this.
|
|
1799
|
-
|
|
1800
|
-
b.push(c[0], c[1]);
|
|
1832
|
+
fi2 = this.findface(cm2);
|
|
1833
|
+
b.push(this.facetocubie[fi2], this.facetoord[fi2]);
|
|
1801
1834
|
cm = cm2;
|
|
1802
1835
|
}
|
|
1803
1836
|
// If an oriented center is moving, we need to figure out
|
|
@@ -1822,23 +1855,22 @@ export class PuzzleGeometry {
|
|
|
1822
1855
|
// center itself.
|
|
1823
1856
|
if (
|
|
1824
1857
|
b.length > 2 &&
|
|
1825
|
-
this.orientCenters &&
|
|
1826
|
-
(this.cubies[b[0]].length === 1 ||
|
|
1827
|
-
this.cubies[b[0]][0] === this.cubies[b[0]][1])
|
|
1858
|
+
this.options.orientCenters &&
|
|
1859
|
+
(this.cubies[b[0]].length === 1 || this.duplicatedCubies[b[0]] > 1)
|
|
1828
1860
|
) {
|
|
1829
1861
|
// is this a real center cubie, around an axis?
|
|
1830
1862
|
if (
|
|
1831
1863
|
this.facecentermass[i].dist(
|
|
1832
|
-
|
|
1864
|
+
this.basefaces[this.getfaceindex(i)].centermass(),
|
|
1833
1865
|
) < eps
|
|
1834
1866
|
) {
|
|
1835
1867
|
// how does remapping of the face/point set map to the original?
|
|
1836
|
-
let face1 = this.cubies[b[0]][0];
|
|
1868
|
+
let face1 = this.faces[this.cubies[b[0]][0]];
|
|
1837
1869
|
for (let ii = 0; ii < b.length; ii += 2) {
|
|
1838
|
-
const face0 = this.cubies[b[ii]][0];
|
|
1870
|
+
const face0 = this.faces[this.cubies[b[ii]][0]];
|
|
1839
1871
|
let o = -1;
|
|
1840
1872
|
for (let jj = 0; jj < face1.length; jj++) {
|
|
1841
|
-
if (face0
|
|
1873
|
+
if (face0.get(jj).dist(face1.get(0)) < eps) {
|
|
1842
1874
|
o = jj;
|
|
1843
1875
|
break;
|
|
1844
1876
|
}
|
|
@@ -1849,7 +1881,7 @@ export class PuzzleGeometry {
|
|
|
1849
1881
|
);
|
|
1850
1882
|
} else {
|
|
1851
1883
|
b[ii + 1] = o;
|
|
1852
|
-
face1 = this.moverotations[k][0]
|
|
1884
|
+
face1 = face1.rotate(this.moverotations[k][0]);
|
|
1853
1885
|
}
|
|
1854
1886
|
}
|
|
1855
1887
|
}
|
|
@@ -1857,7 +1889,7 @@ export class PuzzleGeometry {
|
|
|
1857
1889
|
// b.length == 2 means a sticker is spinning in place.
|
|
1858
1890
|
// in this case we add duplicate stickers
|
|
1859
1891
|
// so that we can make it animate properly in a 3D world.
|
|
1860
|
-
if (b.length === 2 && this.orientCenters) {
|
|
1892
|
+
if (b.length === 2 && this.options.orientCenters) {
|
|
1861
1893
|
for (let ii = 1; ii < this.movesetorders[k]; ii++) {
|
|
1862
1894
|
if (sc === 0) {
|
|
1863
1895
|
b.push(b[0], ii);
|
|
@@ -1873,38 +1905,41 @@ export class PuzzleGeometry {
|
|
|
1873
1905
|
if (b.length !== 2 * this.movesetorders[k]) {
|
|
1874
1906
|
throw new Error("Bad length in perm gen");
|
|
1875
1907
|
}
|
|
1876
|
-
for (
|
|
1877
|
-
axiscmoves[sc].push(
|
|
1908
|
+
for (const v of b) {
|
|
1909
|
+
axiscmoves[sc].push(v);
|
|
1878
1910
|
}
|
|
1879
1911
|
}
|
|
1880
1912
|
for (let j = 0; j < b.length; j += 2) {
|
|
1881
1913
|
cubiedone[b[j]] = true;
|
|
1882
1914
|
}
|
|
1883
1915
|
}
|
|
1916
|
+
for (let kk = 0; kk < axiscmoves.length; kk++) {
|
|
1917
|
+
axiscmoves[kk] = axiscmoves[kk].slice();
|
|
1918
|
+
}
|
|
1884
1919
|
cmovesbyslice.push(axiscmoves);
|
|
1885
1920
|
}
|
|
1886
1921
|
this.cmovesbyslice = cmovesbyslice;
|
|
1887
|
-
if (this.
|
|
1888
|
-
const parsedmovelist:
|
|
1922
|
+
if (this.options.moveList) {
|
|
1923
|
+
const parsedmovelist: [
|
|
1924
|
+
string | undefined,
|
|
1925
|
+
number,
|
|
1926
|
+
number,
|
|
1927
|
+
number,
|
|
1928
|
+
boolean,
|
|
1929
|
+
number,
|
|
1930
|
+
][] = [];
|
|
1889
1931
|
// make sure the movelist makes sense based on the geos.
|
|
1890
|
-
for (
|
|
1891
|
-
parsedmovelist.push(this.parsemove(
|
|
1932
|
+
for (const moveString of this.options.moveList) {
|
|
1933
|
+
parsedmovelist.push(this.parsemove(moveString));
|
|
1892
1934
|
}
|
|
1893
1935
|
this.parsedmovelist = parsedmovelist;
|
|
1894
1936
|
}
|
|
1895
|
-
this.facelisthash
|
|
1937
|
+
this.facelisthash.clear();
|
|
1896
1938
|
this.facecentermass = [];
|
|
1897
|
-
|
|
1939
|
+
tend(t1);
|
|
1898
1940
|
}
|
|
1899
1941
|
|
|
1900
|
-
|
|
1901
|
-
// get the faces for 3d.
|
|
1902
|
-
return this.faces.map((_) => {
|
|
1903
|
-
return _.map((__) => [__.b, __.c, __.d]);
|
|
1904
|
-
});
|
|
1905
|
-
}
|
|
1906
|
-
|
|
1907
|
-
public getboundarygeometry(): any {
|
|
1942
|
+
private getboundarygeometry(): any {
|
|
1908
1943
|
// get the boundary geometry
|
|
1909
1944
|
return {
|
|
1910
1945
|
baseplanes: this.baseplanes,
|
|
@@ -1916,16 +1951,15 @@ export class PuzzleGeometry {
|
|
|
1916
1951
|
};
|
|
1917
1952
|
}
|
|
1918
1953
|
|
|
1919
|
-
|
|
1954
|
+
private getmovesets(k: number): any {
|
|
1920
1955
|
// get the move sets we support based on slices
|
|
1921
1956
|
// for even values we omit the middle "slice". This isn't perfect
|
|
1922
1957
|
// but it is what we do for now.
|
|
1923
1958
|
// if there was a move list specified, pull values from that
|
|
1924
1959
|
const slices = this.moveplanesets[k].length;
|
|
1925
|
-
let r = [];
|
|
1960
|
+
let r: any[] = [];
|
|
1926
1961
|
if (this.parsedmovelist !== undefined) {
|
|
1927
|
-
for (
|
|
1928
|
-
const parsedmove = this.parsedmovelist[i];
|
|
1962
|
+
for (const parsedmove of this.parsedmovelist) {
|
|
1929
1963
|
if (parsedmove[1] !== k) {
|
|
1930
1964
|
continue;
|
|
1931
1965
|
}
|
|
@@ -1936,19 +1970,19 @@ export class PuzzleGeometry {
|
|
|
1936
1970
|
}
|
|
1937
1971
|
r.push(parsedmove[5]);
|
|
1938
1972
|
}
|
|
1939
|
-
} else if (this.
|
|
1973
|
+
} else if (this.options.vertexMoves && !this.options.allMoves) {
|
|
1940
1974
|
const msg = this.movesetgeos[k];
|
|
1941
1975
|
if (msg[1] !== msg[3]) {
|
|
1942
1976
|
for (let i = 0; i < slices; i++) {
|
|
1943
1977
|
if (msg[1] !== "v") {
|
|
1944
|
-
if (this.
|
|
1978
|
+
if (this.options.outerBlockMoves) {
|
|
1945
1979
|
r.push([i + 1, slices]);
|
|
1946
1980
|
} else {
|
|
1947
1981
|
r.push([i + 1]);
|
|
1948
1982
|
}
|
|
1949
1983
|
r.push(1);
|
|
1950
1984
|
} else {
|
|
1951
|
-
if (this.
|
|
1985
|
+
if (this.options.outerBlockMoves) {
|
|
1952
1986
|
r.push([0, i]);
|
|
1953
1987
|
} else {
|
|
1954
1988
|
r.push([i, i]);
|
|
@@ -1959,10 +1993,10 @@ export class PuzzleGeometry {
|
|
|
1959
1993
|
}
|
|
1960
1994
|
} else {
|
|
1961
1995
|
for (let i = 0; i <= slices; i++) {
|
|
1962
|
-
if (!this.
|
|
1996
|
+
if (!this.options.allMoves && i + i === slices) {
|
|
1963
1997
|
continue;
|
|
1964
1998
|
}
|
|
1965
|
-
if (this.
|
|
1999
|
+
if (this.options.outerBlockMoves) {
|
|
1966
2000
|
if (i + i > slices) {
|
|
1967
2001
|
r.push([i, slices]);
|
|
1968
2002
|
} else {
|
|
@@ -1975,7 +2009,7 @@ export class PuzzleGeometry {
|
|
|
1975
2009
|
}
|
|
1976
2010
|
}
|
|
1977
2011
|
if (this.fixedCubie >= 0) {
|
|
1978
|
-
const dep =
|
|
2012
|
+
const dep = this.keyface3(this.faces[this.cubies[this.fixedCubie][0]])[k];
|
|
1979
2013
|
const newr = [];
|
|
1980
2014
|
for (let i = 0; i < r.length; i += 2) {
|
|
1981
2015
|
let o = r[i];
|
|
@@ -2006,47 +2040,44 @@ export class PuzzleGeometry {
|
|
|
2006
2040
|
}
|
|
2007
2041
|
r = newr;
|
|
2008
2042
|
}
|
|
2043
|
+
// TODO
|
|
2044
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
2009
2045
|
return r;
|
|
2010
2046
|
}
|
|
2011
2047
|
|
|
2012
|
-
|
|
2048
|
+
private graybyori(cubie: number): boolean {
|
|
2013
2049
|
let ori = this.cubies[cubie].length;
|
|
2014
2050
|
if (this.duplicatedCubies[cubie]) {
|
|
2015
2051
|
ori = 1;
|
|
2016
2052
|
}
|
|
2017
2053
|
return (
|
|
2018
|
-
(ori === 1 &&
|
|
2019
|
-
|
|
2020
|
-
(ori
|
|
2054
|
+
(ori === 1 &&
|
|
2055
|
+
(this.options.grayCenters || !this.options.includeCenterOrbits)) ||
|
|
2056
|
+
(ori === 2 &&
|
|
2057
|
+
(this.options.grayEdges || !this.options.includeEdgeOrbits)) ||
|
|
2058
|
+
(ori > 2 &&
|
|
2059
|
+
(this.options.grayCorners || !this.options.includeCornerOrbits))
|
|
2021
2060
|
);
|
|
2022
2061
|
}
|
|
2023
2062
|
|
|
2024
|
-
|
|
2063
|
+
private skipbyori(cubie: number): boolean {
|
|
2025
2064
|
let ori = this.cubies[cubie].length;
|
|
2026
2065
|
if (this.duplicatedCubies[cubie]) {
|
|
2027
2066
|
ori = 1;
|
|
2028
2067
|
}
|
|
2029
2068
|
return (
|
|
2030
|
-
(ori === 1 && !this.
|
|
2031
|
-
(ori === 2 && !this.
|
|
2032
|
-
(ori > 2 && !this.
|
|
2069
|
+
(ori === 1 && !this.options.includeCenterOrbits) ||
|
|
2070
|
+
(ori === 2 && !this.options.includeEdgeOrbits) ||
|
|
2071
|
+
(ori > 2 && !this.options.includeCornerOrbits)
|
|
2033
2072
|
);
|
|
2034
2073
|
}
|
|
2035
2074
|
|
|
2036
|
-
|
|
2075
|
+
private skipcubie(fi: number): boolean {
|
|
2037
2076
|
return this.skipbyori(fi);
|
|
2038
2077
|
}
|
|
2039
2078
|
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
return true;
|
|
2043
|
-
}
|
|
2044
|
-
const fi = set[0];
|
|
2045
|
-
return this.skipbyori(this.facetocubies[fi][0]);
|
|
2046
|
-
}
|
|
2047
|
-
|
|
2048
|
-
public header(comment: string): string {
|
|
2049
|
-
return comment + copyright + "\n" + comment + this.args + "\n";
|
|
2079
|
+
private header(comment: string): string {
|
|
2080
|
+
return comment + copyright + "\n" + comment + "\n";
|
|
2050
2081
|
}
|
|
2051
2082
|
|
|
2052
2083
|
public writegap(): string {
|
|
@@ -2078,6 +2109,8 @@ export class PuzzleGeometry {
|
|
|
2078
2109
|
ip.map((_) => "[" + _.map((__) => __ + 1).join(",") + "]").join(",") +
|
|
2079
2110
|
"];",
|
|
2080
2111
|
);
|
|
2112
|
+
r.push("# Size(Group(Gen));");
|
|
2113
|
+
r.push("# Size(Stabilizer(Group(Gen), ip, OnTuplesSets));");
|
|
2081
2114
|
r.push("");
|
|
2082
2115
|
return this.header("# ") + r.join("\n");
|
|
2083
2116
|
}
|
|
@@ -2089,9 +2122,15 @@ export class PuzzleGeometry {
|
|
|
2089
2122
|
);
|
|
2090
2123
|
}
|
|
2091
2124
|
|
|
2092
|
-
public writekpuzzle(
|
|
2093
|
-
|
|
2094
|
-
|
|
2125
|
+
public writekpuzzle(
|
|
2126
|
+
fortwisty: boolean = true,
|
|
2127
|
+
includemoves: boolean = true,
|
|
2128
|
+
): KPuzzleDefinition {
|
|
2129
|
+
const od = this.getOrbitsDef(fortwisty, includemoves);
|
|
2130
|
+
const r = od.toKPuzzle(includemoves);
|
|
2131
|
+
if (!r) {
|
|
2132
|
+
throw new Error("Missing definition!");
|
|
2133
|
+
}
|
|
2095
2134
|
r.moveNotation = new PGNotation(this, od);
|
|
2096
2135
|
return r;
|
|
2097
2136
|
}
|
|
@@ -2103,13 +2142,13 @@ export class PuzzleGeometry {
|
|
|
2103
2142
|
axiscmoves: number[][],
|
|
2104
2143
|
setmoves: number[] | undefined,
|
|
2105
2144
|
movesetorder: number,
|
|
2106
|
-
):
|
|
2107
|
-
const moveorbits:
|
|
2145
|
+
): PGTransform {
|
|
2146
|
+
const moveorbits: PGOrbit[] = [];
|
|
2108
2147
|
const perms = [];
|
|
2109
2148
|
const oris = [];
|
|
2110
|
-
for (
|
|
2111
|
-
perms.push(iota(
|
|
2112
|
-
oris.push(zeros(
|
|
2149
|
+
for (const len of this.cubieords) {
|
|
2150
|
+
perms.push(iota(len));
|
|
2151
|
+
oris.push(zeros(len));
|
|
2113
2152
|
}
|
|
2114
2153
|
for (let m = moverange[0]; m <= moverange[1]; m++) {
|
|
2115
2154
|
const slicecmoves = axiscmoves[m];
|
|
@@ -2127,13 +2166,13 @@ export class PuzzleGeometry {
|
|
|
2127
2166
|
}
|
|
2128
2167
|
if (perms[setnum] === iota(this.cubieords[setnum])) {
|
|
2129
2168
|
perms[setnum] = perms[setnum].slice();
|
|
2130
|
-
if (this.orbitoris[setnum] > 1 && !this.
|
|
2169
|
+
if (this.orbitoris[setnum] > 1 && !this.options.fixedOrientation) {
|
|
2131
2170
|
oris[setnum] = oris[setnum].slice();
|
|
2132
2171
|
}
|
|
2133
2172
|
}
|
|
2134
2173
|
for (let ii = 0; ii < mperm.length; ii += 2) {
|
|
2135
2174
|
perms[setnum][mperm[(ii + inc) % mperm.length]] = mperm[ii];
|
|
2136
|
-
if (this.orbitoris[setnum] > 1 && !this.
|
|
2175
|
+
if (this.orbitoris[setnum] > 1 && !this.options.fixedOrientation) {
|
|
2137
2176
|
oris[setnum][mperm[ii]] =
|
|
2138
2177
|
(mperm[(ii + oinc) % mperm.length] -
|
|
2139
2178
|
mperm[(ii + 1) % mperm.length] +
|
|
@@ -2143,19 +2182,19 @@ export class PuzzleGeometry {
|
|
|
2143
2182
|
}
|
|
2144
2183
|
}
|
|
2145
2184
|
}
|
|
2146
|
-
let lastId = new
|
|
2185
|
+
let lastId = new PGOrbit(iota(24), zeros(24), 1);
|
|
2147
2186
|
for (let ii = 0; ii < this.cubiesetnames.length; ii++) {
|
|
2148
2187
|
if (setmoves && !setmoves[ii]) {
|
|
2149
2188
|
continue;
|
|
2150
2189
|
}
|
|
2151
|
-
if (this.orbitoris[ii] === 1 || this.
|
|
2190
|
+
if (this.orbitoris[ii] === 1 || this.options.fixedOrientation) {
|
|
2152
2191
|
if (perms[ii] === iota(lastId.perm.length)) {
|
|
2153
2192
|
if (perms[ii] !== lastId.perm) {
|
|
2154
|
-
lastId = new
|
|
2193
|
+
lastId = new PGOrbit(perms[ii], oris[ii], 1);
|
|
2155
2194
|
}
|
|
2156
2195
|
moveorbits.push(lastId);
|
|
2157
2196
|
} else {
|
|
2158
|
-
moveorbits.push(new
|
|
2197
|
+
moveorbits.push(new PGOrbit(perms[ii], oris[ii], 1));
|
|
2159
2198
|
}
|
|
2160
2199
|
} else {
|
|
2161
2200
|
const no = new Array<number>(oris[ii].length);
|
|
@@ -2163,26 +2202,26 @@ export class PuzzleGeometry {
|
|
|
2163
2202
|
for (let jj = 0; jj < perms[ii].length; jj++) {
|
|
2164
2203
|
no[jj] = oris[ii][perms[ii][jj]];
|
|
2165
2204
|
}
|
|
2166
|
-
moveorbits.push(new
|
|
2205
|
+
moveorbits.push(new PGOrbit(perms[ii], no, this.orbitoris[ii]));
|
|
2167
2206
|
}
|
|
2168
2207
|
}
|
|
2169
|
-
let mv = new
|
|
2208
|
+
let mv = new PGTransform(moveorbits);
|
|
2170
2209
|
if (amount !== 1) {
|
|
2171
2210
|
mv = mv.mulScalar(amount);
|
|
2172
2211
|
}
|
|
2173
2212
|
return mv;
|
|
2174
2213
|
}
|
|
2175
2214
|
|
|
2176
|
-
|
|
2177
|
-
for (
|
|
2178
|
-
if (
|
|
2215
|
+
private omitSet(name: string): boolean {
|
|
2216
|
+
for (const excludedSet of this.options.excludeOrbits) {
|
|
2217
|
+
if (excludedSet === name) {
|
|
2179
2218
|
return true;
|
|
2180
2219
|
}
|
|
2181
2220
|
}
|
|
2182
2221
|
return false;
|
|
2183
2222
|
}
|
|
2184
2223
|
|
|
2185
|
-
|
|
2224
|
+
private diffmvsets(a: any[], b: any[], slices: number, neg: boolean) {
|
|
2186
2225
|
for (let i = 0; i < a.length; i += 2) {
|
|
2187
2226
|
let found = false;
|
|
2188
2227
|
for (let j = 0; !found && j < b.length; j += 2) {
|
|
@@ -2211,7 +2250,11 @@ export class PuzzleGeometry {
|
|
|
2211
2250
|
return false;
|
|
2212
2251
|
}
|
|
2213
2252
|
|
|
2214
|
-
|
|
2253
|
+
// TODO: This is only public for testing; can we make it private again?
|
|
2254
|
+
public getOrbitsDef(
|
|
2255
|
+
fortwisty: boolean,
|
|
2256
|
+
includemoves: boolean = true,
|
|
2257
|
+
): PGOrbitsDef {
|
|
2215
2258
|
// generate a representation of the puzzle
|
|
2216
2259
|
const setmoves = [];
|
|
2217
2260
|
if (fortwisty) {
|
|
@@ -2220,7 +2263,7 @@ export class PuzzleGeometry {
|
|
|
2220
2263
|
}
|
|
2221
2264
|
}
|
|
2222
2265
|
const setnames: string[] = [];
|
|
2223
|
-
const setdefs:
|
|
2266
|
+
const setdefs: PGOrbitDef[] = [];
|
|
2224
2267
|
// if both a movelist and rotations are needed, eliminate rotations
|
|
2225
2268
|
// that do not preserve the movelist.
|
|
2226
2269
|
const mps = [];
|
|
@@ -2228,13 +2271,13 @@ export class PuzzleGeometry {
|
|
|
2228
2271
|
for (let k = 0; k < this.moveplanesets.length; k++) {
|
|
2229
2272
|
const moveset = this.getmovesets(k);
|
|
2230
2273
|
mps.push(moveset);
|
|
2231
|
-
if (this.
|
|
2274
|
+
if (this.options.addRotations) {
|
|
2232
2275
|
addrot.push(1);
|
|
2233
2276
|
} else {
|
|
2234
2277
|
addrot.push(0);
|
|
2235
2278
|
}
|
|
2236
2279
|
}
|
|
2237
|
-
if (this.
|
|
2280
|
+
if (this.options.moveList && this.options.addRotations) {
|
|
2238
2281
|
for (let i = 0; i < this.moverotations.length; i++) {
|
|
2239
2282
|
addrot[i] = 0;
|
|
2240
2283
|
}
|
|
@@ -2249,22 +2292,20 @@ export class PuzzleGeometry {
|
|
|
2249
2292
|
}
|
|
2250
2293
|
let found = -1;
|
|
2251
2294
|
let neg = false;
|
|
2252
|
-
for (
|
|
2253
|
-
let j = 0;
|
|
2254
|
-
found < 0 && j < this.moveplanenormals.length;
|
|
2255
|
-
j++
|
|
2256
|
-
) {
|
|
2295
|
+
for (let j = 0; j < this.moveplanenormals.length; j++) {
|
|
2257
2296
|
if (nn.dist(this.moveplanenormals[j]) < eps) {
|
|
2258
2297
|
found = j;
|
|
2298
|
+
break;
|
|
2259
2299
|
} else if (nn.dist(this.moveplanenormals[j].smul(-1)) < eps) {
|
|
2260
2300
|
found = j;
|
|
2261
2301
|
neg = true;
|
|
2302
|
+
break;
|
|
2262
2303
|
}
|
|
2263
2304
|
}
|
|
2264
2305
|
if (found < 0) {
|
|
2265
2306
|
throw new Error("Could not find rotation");
|
|
2266
2307
|
}
|
|
2267
|
-
|
|
2308
|
+
const cmp = mps[found];
|
|
2268
2309
|
if (
|
|
2269
2310
|
cmp.length !== mps[k].length ||
|
|
2270
2311
|
this.moveplanesets[k].length !==
|
|
@@ -2345,13 +2386,13 @@ export class PuzzleGeometry {
|
|
|
2345
2386
|
}
|
|
2346
2387
|
setnames.push(this.cubiesetnames[i]);
|
|
2347
2388
|
setdefs.push(
|
|
2348
|
-
new
|
|
2389
|
+
new PGOrbitDef(
|
|
2349
2390
|
this.cubieords[i],
|
|
2350
|
-
this.
|
|
2391
|
+
this.options.fixedOrientation ? 1 : this.orbitoris[i],
|
|
2351
2392
|
),
|
|
2352
2393
|
);
|
|
2353
2394
|
}
|
|
2354
|
-
const solved:
|
|
2395
|
+
const solved: PGOrbit[] = [];
|
|
2355
2396
|
for (let i = 0; i < this.cubiesetnames.length; i++) {
|
|
2356
2397
|
if (!setmoves[i]) {
|
|
2357
2398
|
continue;
|
|
@@ -2371,58 +2412,61 @@ export class PuzzleGeometry {
|
|
|
2371
2412
|
o.push(0);
|
|
2372
2413
|
}
|
|
2373
2414
|
solved.push(
|
|
2374
|
-
new
|
|
2415
|
+
new PGOrbit(
|
|
2416
|
+
p,
|
|
2417
|
+
o,
|
|
2418
|
+
this.options.fixedOrientation ? 1 : this.orbitoris[i],
|
|
2419
|
+
),
|
|
2375
2420
|
);
|
|
2376
2421
|
}
|
|
2377
2422
|
const movenames: string[] = [];
|
|
2378
|
-
const moves:
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2423
|
+
const moves: PGTransform[] = [];
|
|
2424
|
+
if (includemoves) {
|
|
2425
|
+
for (let k = 0; k < this.moveplanesets.length; k++) {
|
|
2426
|
+
const moveplaneset = this.moveplanesets[k];
|
|
2427
|
+
const slices = moveplaneset.length;
|
|
2428
|
+
const moveset = mps[k];
|
|
2429
|
+
const movesetgeo = this.movesetgeos[k];
|
|
2430
|
+
for (let i = 0; i < moveset.length; i += 2) {
|
|
2431
|
+
const movebits = moveset[i];
|
|
2432
|
+
const mna = getmovename(movesetgeo, movebits, slices);
|
|
2433
|
+
const movename = mna[0];
|
|
2434
|
+
const inverted = mna[1];
|
|
2435
|
+
if (moveset[i + 1] === 1) {
|
|
2436
|
+
movenames.push(movename);
|
|
2437
|
+
} else {
|
|
2438
|
+
movenames.push(movename + moveset[i + 1]);
|
|
2439
|
+
}
|
|
2440
|
+
const mv = this.getMoveFromBits(
|
|
2441
|
+
movebits,
|
|
2442
|
+
moveset[i + 1],
|
|
2443
|
+
inverted,
|
|
2444
|
+
this.cmovesbyslice[k],
|
|
2445
|
+
setmoves,
|
|
2446
|
+
this.movesetorders[k],
|
|
2447
|
+
);
|
|
2448
|
+
moves.push(mv);
|
|
2449
|
+
}
|
|
2403
2450
|
}
|
|
2404
2451
|
}
|
|
2405
|
-
|
|
2406
|
-
let r = new OrbitsDef(
|
|
2452
|
+
let r = new PGOrbitsDef(
|
|
2407
2453
|
setnames,
|
|
2408
2454
|
setdefs,
|
|
2409
2455
|
new VisibleState(solved),
|
|
2410
2456
|
movenames,
|
|
2411
2457
|
moves,
|
|
2412
2458
|
);
|
|
2413
|
-
if (this.
|
|
2459
|
+
if (this.options.optimizeOrbits) {
|
|
2414
2460
|
r = r.optimize();
|
|
2415
2461
|
}
|
|
2416
|
-
if (this.
|
|
2417
|
-
r.scramble(this.
|
|
2462
|
+
if (this.options.scrambleAmount !== 0) {
|
|
2463
|
+
r.scramble(this.options.scrambleAmount);
|
|
2418
2464
|
}
|
|
2419
2465
|
return r;
|
|
2420
2466
|
}
|
|
2421
2467
|
|
|
2422
2468
|
public getMovesAsPerms(): Perm[] {
|
|
2423
|
-
return this.getOrbitsDef(false).moveops.map((_
|
|
2424
|
-
_.toPerm(),
|
|
2425
|
-
);
|
|
2469
|
+
return this.getOrbitsDef(false).moveops.map((_) => _.toPerm());
|
|
2426
2470
|
}
|
|
2427
2471
|
|
|
2428
2472
|
public showcanon(disp: (s: string) => void): void {
|
|
@@ -2433,7 +2477,7 @@ export class PuzzleGeometry {
|
|
|
2433
2477
|
public getsolved(): Perm {
|
|
2434
2478
|
// get a solved position
|
|
2435
2479
|
const r = [];
|
|
2436
|
-
for (let i = 0; i < this.
|
|
2480
|
+
for (let i = 0; i < this.baseFaceCount; i++) {
|
|
2437
2481
|
for (let j = 0; j < this.stickersperface; j++) {
|
|
2438
2482
|
r.push(i);
|
|
2439
2483
|
}
|
|
@@ -2445,21 +2489,12 @@ export class PuzzleGeometry {
|
|
|
2445
2489
|
// with a given vector, and then as much as possible feature2
|
|
2446
2490
|
// with another given vector, return a Quaternion that
|
|
2447
2491
|
// performs this rotation.
|
|
2448
|
-
|
|
2449
|
-
const feature1name = desiredRotation[0];
|
|
2450
|
-
const direction1 = new Quat(
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
desiredRotation[1][2],
|
|
2455
|
-
);
|
|
2456
|
-
const feature2name = desiredRotation[2];
|
|
2457
|
-
const direction2 = new Quat(
|
|
2458
|
-
0,
|
|
2459
|
-
desiredRotation[3][0],
|
|
2460
|
-
-desiredRotation[3][1],
|
|
2461
|
-
desiredRotation[3][2],
|
|
2462
|
-
);
|
|
2492
|
+
private getOrientationRotation(desiredRotation: any[]): Quat {
|
|
2493
|
+
const [feature1name, [x1, y1, z1]] = desiredRotation[0];
|
|
2494
|
+
const direction1 = new Quat(0, x1, -y1, z1);
|
|
2495
|
+
|
|
2496
|
+
const [feature2name, [x2, y2, z2]] = desiredRotation[1];
|
|
2497
|
+
const direction2 = new Quat(0, x2, -y2, z2);
|
|
2463
2498
|
let feature1: Quat | null = null;
|
|
2464
2499
|
let feature2: Quat | null = null;
|
|
2465
2500
|
const feature1geoname = this.swizzler.unswizzle(feature1name);
|
|
@@ -2486,32 +2521,33 @@ export class PuzzleGeometry {
|
|
|
2486
2521
|
return r2.mul(r1);
|
|
2487
2522
|
}
|
|
2488
2523
|
|
|
2489
|
-
|
|
2490
|
-
const basefacecount = this.
|
|
2491
|
-
let
|
|
2492
|
-
if (this.puzzleOrientation) {
|
|
2493
|
-
|
|
2494
|
-
} else if (this.puzzleOrientations) {
|
|
2495
|
-
|
|
2524
|
+
private getInitial3DRotation(): Quat {
|
|
2525
|
+
const basefacecount = this.baseFaceCount;
|
|
2526
|
+
let orientationDescription: FaceBasedOrientationDescription | null = null;
|
|
2527
|
+
if (this.options.puzzleOrientation) {
|
|
2528
|
+
orientationDescription = this.options.puzzleOrientation;
|
|
2529
|
+
} else if (this.options.puzzleOrientations) {
|
|
2530
|
+
orientationDescription = this.options.puzzleOrientations[basefacecount];
|
|
2496
2531
|
}
|
|
2497
2532
|
// either no option specified or no matching key in
|
|
2498
2533
|
// puzzleOrientations.
|
|
2499
|
-
if (!
|
|
2500
|
-
|
|
2534
|
+
if (!orientationDescription) {
|
|
2535
|
+
orientationDescription = defaultOrientations()[basefacecount];
|
|
2501
2536
|
}
|
|
2502
|
-
if (!
|
|
2537
|
+
if (!orientationDescription) {
|
|
2503
2538
|
throw new Error("No default orientation?");
|
|
2504
2539
|
}
|
|
2505
|
-
return this.getOrientationRotation(
|
|
2540
|
+
return this.getOrientationRotation(orientationDescription);
|
|
2506
2541
|
}
|
|
2507
2542
|
|
|
2508
|
-
|
|
2543
|
+
private generate2dmapping(
|
|
2509
2544
|
w: number = 800,
|
|
2510
2545
|
h: number = 500,
|
|
2511
2546
|
trim: number = 10,
|
|
2512
2547
|
threed: boolean = false,
|
|
2513
|
-
|
|
2514
|
-
|
|
2548
|
+
twodshrink: number = 0.92,
|
|
2549
|
+
): (fn: number, q: Quat) => number[] {
|
|
2550
|
+
// generate a mapping to use for 2D for textures, svg
|
|
2515
2551
|
w -= 2 * trim;
|
|
2516
2552
|
h -= 2 * trim;
|
|
2517
2553
|
function extendedges(a: number[][], n: number): void {
|
|
@@ -2527,40 +2563,6 @@ export class PuzzleGeometry {
|
|
|
2527
2563
|
a.push([a[i - 1][0] + dx, a[i - 1][1] + dy]);
|
|
2528
2564
|
}
|
|
2529
2565
|
}
|
|
2530
|
-
// if we don't add this noise to coordinate values, then Safari
|
|
2531
|
-
// doesn't render our polygons correctly. What a hack.
|
|
2532
|
-
function noise(c: number): number {
|
|
2533
|
-
return c + 0 * (Math.random() - 0.5);
|
|
2534
|
-
}
|
|
2535
|
-
function drawedges(id: string, pts: number[][], color: string): string {
|
|
2536
|
-
return (
|
|
2537
|
-
'<polygon id="' +
|
|
2538
|
-
id +
|
|
2539
|
-
'" class="sticker" style="fill: ' +
|
|
2540
|
-
color +
|
|
2541
|
-
'" points="' +
|
|
2542
|
-
pts.map((p) => noise(p[0]) + " " + noise(p[1])).join(" ") +
|
|
2543
|
-
'"/>\n'
|
|
2544
|
-
);
|
|
2545
|
-
}
|
|
2546
|
-
// What grips do we need? if rotations, add all grips.
|
|
2547
|
-
let needvertexgrips = this.addrotations;
|
|
2548
|
-
let neededgegrips = this.addrotations;
|
|
2549
|
-
let needfacegrips = this.addrotations;
|
|
2550
|
-
for (let i = 0; i < this.movesetgeos.length; i++) {
|
|
2551
|
-
const msg = this.movesetgeos[i];
|
|
2552
|
-
for (let j = 1; j <= 3; j += 2) {
|
|
2553
|
-
if (msg[j] === "v") {
|
|
2554
|
-
needvertexgrips = true;
|
|
2555
|
-
}
|
|
2556
|
-
if (msg[j] === "f") {
|
|
2557
|
-
needfacegrips = true;
|
|
2558
|
-
}
|
|
2559
|
-
if (msg[j] === "e") {
|
|
2560
|
-
neededgegrips = true;
|
|
2561
|
-
}
|
|
2562
|
-
}
|
|
2563
|
-
}
|
|
2564
2566
|
// Find a net from a given face count. Walk it, assuming we locate
|
|
2565
2567
|
// the first edge from (0,0) to (1,1) and compute the minimum and
|
|
2566
2568
|
// maximum vertex locations from this. Then do a second walk, and
|
|
@@ -2583,13 +2585,13 @@ export class PuzzleGeometry {
|
|
|
2583
2585
|
[0, 0],
|
|
2584
2586
|
];
|
|
2585
2587
|
extendedges(edges[net[0][0]], polyn);
|
|
2586
|
-
for (
|
|
2587
|
-
const f0 =
|
|
2588
|
+
for (const neti of net) {
|
|
2589
|
+
const f0 = neti[0];
|
|
2588
2590
|
if (!edges[f0]) {
|
|
2589
2591
|
throw new Error("Bad edge description; first edge not connected.");
|
|
2590
2592
|
}
|
|
2591
|
-
for (let j = 1; j <
|
|
2592
|
-
const f1 =
|
|
2593
|
+
for (let j = 1; j < neti.length; j++) {
|
|
2594
|
+
const f1 = neti[j];
|
|
2593
2595
|
if (f1 === "" || edges[f1]) {
|
|
2594
2596
|
continue;
|
|
2595
2597
|
}
|
|
@@ -2599,17 +2601,17 @@ export class PuzzleGeometry {
|
|
|
2599
2601
|
}
|
|
2600
2602
|
for (const f in edges) {
|
|
2601
2603
|
const es = edges[f];
|
|
2602
|
-
for (
|
|
2603
|
-
minx = Math.min(minx,
|
|
2604
|
-
maxx = Math.max(maxx,
|
|
2605
|
-
miny = Math.min(miny,
|
|
2606
|
-
maxy = Math.max(maxy,
|
|
2604
|
+
for (const esi of es) {
|
|
2605
|
+
minx = Math.min(minx, esi[0]);
|
|
2606
|
+
maxx = Math.max(maxx, esi[0]);
|
|
2607
|
+
miny = Math.min(miny, esi[1]);
|
|
2608
|
+
maxy = Math.max(maxy, esi[1]);
|
|
2607
2609
|
}
|
|
2608
2610
|
}
|
|
2609
2611
|
const sc = Math.min(w / (maxx - minx), h / (maxy - miny));
|
|
2610
2612
|
const xoff = 0.5 * (w - sc * (maxx + minx));
|
|
2611
2613
|
const yoff = 0.5 * (h - sc * (maxy + miny));
|
|
2612
|
-
const geos:
|
|
2614
|
+
const geos: Record<string, Quat[]> = {};
|
|
2613
2615
|
const bg = this.getboundarygeometry();
|
|
2614
2616
|
const edges2: any = {};
|
|
2615
2617
|
const initv = [
|
|
@@ -2624,8 +2626,8 @@ export class PuzzleGeometry {
|
|
|
2624
2626
|
]);
|
|
2625
2627
|
const connectat = [];
|
|
2626
2628
|
connectat[0] = 0;
|
|
2627
|
-
for (
|
|
2628
|
-
const f0 =
|
|
2629
|
+
for (const neti of net) {
|
|
2630
|
+
const f0 = neti[0];
|
|
2629
2631
|
if (!edges2[f0]) {
|
|
2630
2632
|
throw new Error("Bad edge description; first edge not connected.");
|
|
2631
2633
|
}
|
|
@@ -2640,8 +2642,8 @@ export class PuzzleGeometry {
|
|
|
2640
2642
|
throw new Error("Could not find first face name " + f0);
|
|
2641
2643
|
}
|
|
2642
2644
|
const thisface = bg.facenames[gfi][0];
|
|
2643
|
-
for (let j = 1; j <
|
|
2644
|
-
const f1 =
|
|
2645
|
+
for (let j = 1; j < neti.length; j++) {
|
|
2646
|
+
const f1 = neti[j];
|
|
2645
2647
|
if (f1 === "" || edges2[f1]) {
|
|
2646
2648
|
continue;
|
|
2647
2649
|
}
|
|
@@ -2685,30 +2687,22 @@ export class PuzzleGeometry {
|
|
|
2685
2687
|
}
|
|
2686
2688
|
}
|
|
2687
2689
|
}
|
|
2688
|
-
// Let's build arrays for faster rendering. We want to map from geo
|
|
2689
|
-
// base face number to color, and we want to map from geo face number
|
|
2690
|
-
// to 2D geometry. These can be reused as long as the puzzle overall
|
|
2691
|
-
// orientation and canvas size remains unchanged.
|
|
2692
|
-
const pos = this.getsolved();
|
|
2693
|
-
const colormap = [];
|
|
2694
|
-
const facegeo = [];
|
|
2695
|
-
for (let i = 0; i < this.basefacecount; i++) {
|
|
2696
|
-
colormap[i] = this.colors[this.facenames[i][1]];
|
|
2697
|
-
}
|
|
2698
2690
|
let hix = 0;
|
|
2699
2691
|
let hiy = 0;
|
|
2700
2692
|
const rot = this.getInitial3DRotation();
|
|
2701
|
-
for (let
|
|
2702
|
-
|
|
2703
|
-
|
|
2693
|
+
for (let face of this.faces) {
|
|
2694
|
+
if (threed) {
|
|
2695
|
+
face = face.rotate(rot);
|
|
2696
|
+
}
|
|
2704
2697
|
for (let j = 0; j < face.length; j++) {
|
|
2705
|
-
hix = Math.max(hix, Math.abs(face
|
|
2706
|
-
hiy = Math.max(hiy, Math.abs(face
|
|
2698
|
+
hix = Math.max(hix, Math.abs(face.get(j).b));
|
|
2699
|
+
hiy = Math.max(hiy, Math.abs(face.get(j).c));
|
|
2707
2700
|
}
|
|
2708
2701
|
}
|
|
2709
2702
|
const sc2 = Math.min(h / hiy / 2, (w - trim) / hix / 4);
|
|
2710
2703
|
const mappt2d = (fn: number, q: Quat): number[] => {
|
|
2711
2704
|
if (threed) {
|
|
2705
|
+
q = q.rotatepoint(rot);
|
|
2712
2706
|
const xoff2 = 0.5 * trim + 0.25 * w;
|
|
2713
2707
|
const xmul = this.baseplanes[fn].rotateplane(rot).d < 0 ? 1 : -1;
|
|
2714
2708
|
return [
|
|
@@ -2717,26 +2711,61 @@ export class PuzzleGeometry {
|
|
|
2717
2711
|
];
|
|
2718
2712
|
} else {
|
|
2719
2713
|
const g = geos[this.facenames[fn][1]];
|
|
2720
|
-
return [
|
|
2714
|
+
return [
|
|
2715
|
+
trim + twodshrink * q.dot(g[0]) + g[2].b,
|
|
2716
|
+
trim + h - twodshrink * q.dot(g[1]) - g[2].c,
|
|
2717
|
+
];
|
|
2721
2718
|
}
|
|
2722
2719
|
};
|
|
2720
|
+
return mappt2d;
|
|
2721
|
+
}
|
|
2722
|
+
|
|
2723
|
+
public generatesvg(
|
|
2724
|
+
w: number = 800,
|
|
2725
|
+
h: number = 500,
|
|
2726
|
+
trim: number = 10,
|
|
2727
|
+
threed: boolean = false,
|
|
2728
|
+
): string {
|
|
2729
|
+
const mappt2d = this.generate2dmapping(w, h, trim, threed);
|
|
2730
|
+
function drawedges(id: string, pts: number[][], color: string): string {
|
|
2731
|
+
return (
|
|
2732
|
+
'<polygon id="' +
|
|
2733
|
+
id +
|
|
2734
|
+
'" class="sticker" style="fill: ' +
|
|
2735
|
+
color +
|
|
2736
|
+
'" points="' +
|
|
2737
|
+
pts.map((p) => p[0] + " " + p[1]).join(" ") +
|
|
2738
|
+
'"/>\n'
|
|
2739
|
+
);
|
|
2740
|
+
}
|
|
2741
|
+
// Let's build arrays for faster rendering. We want to map from geo
|
|
2742
|
+
// base face number to color, and we want to map from geo face number
|
|
2743
|
+
// to 2D geometry. These can be reused as long as the puzzle overall
|
|
2744
|
+
// orientation and canvas size remains unchanged.
|
|
2745
|
+
const pos = this.getsolved();
|
|
2746
|
+
const colormap = [];
|
|
2747
|
+
const facegeo = [];
|
|
2748
|
+
for (let i = 0; i < this.baseFaceCount; i++) {
|
|
2749
|
+
colormap[i] = this.colors[this.facenames[i][1]];
|
|
2750
|
+
}
|
|
2723
2751
|
for (let i = 0; i < this.faces.length; i++) {
|
|
2724
|
-
|
|
2752
|
+
const face = this.faces[i];
|
|
2725
2753
|
const facenum = Math.floor(i / this.stickersperface);
|
|
2726
|
-
|
|
2727
|
-
|
|
2754
|
+
const fg = [];
|
|
2755
|
+
for (let j = 0; j < face.length; j++) {
|
|
2756
|
+
fg.push(mappt2d(facenum, face.get(j)));
|
|
2728
2757
|
}
|
|
2729
|
-
facegeo.push(
|
|
2758
|
+
facegeo.push(fg);
|
|
2730
2759
|
}
|
|
2731
2760
|
const svg = [];
|
|
2732
2761
|
// group each base face so we can add a hover element
|
|
2733
|
-
for (let j = 0; j < this.
|
|
2762
|
+
for (let j = 0; j < this.baseFaceCount; j++) {
|
|
2734
2763
|
svg.push("<g>");
|
|
2735
2764
|
svg.push("<title>" + this.facenames[j][1] + "</title>\n");
|
|
2736
2765
|
for (let ii = 0; ii < this.stickersperface; ii++) {
|
|
2737
2766
|
const i = j * this.stickersperface + ii;
|
|
2738
|
-
const cubie = this.
|
|
2739
|
-
const cubieori = this.
|
|
2767
|
+
const cubie = this.facetocubie[i];
|
|
2768
|
+
const cubieori = this.facetoord[i];
|
|
2740
2769
|
const cubiesetnum = this.cubiesetnums[cubie];
|
|
2741
2770
|
const cubieord = this.cubieordnums[cubie];
|
|
2742
2771
|
const color = this.graybyori(cubie) ? "#808080" : colormap[pos.p[i]];
|
|
@@ -2752,53 +2781,6 @@ export class PuzzleGeometry {
|
|
|
2752
2781
|
}
|
|
2753
2782
|
svg.push("</g>");
|
|
2754
2783
|
}
|
|
2755
|
-
const svggrips: any[] = [];
|
|
2756
|
-
function addgrip(
|
|
2757
|
-
onface: number,
|
|
2758
|
-
name: string,
|
|
2759
|
-
pt: Quat,
|
|
2760
|
-
order: number,
|
|
2761
|
-
): void {
|
|
2762
|
-
const pt2 = mappt2d(onface, pt);
|
|
2763
|
-
for (let i = 0; i < svggrips.length; i++) {
|
|
2764
|
-
if (
|
|
2765
|
-
Math.hypot(pt2[0] - svggrips[i][0], pt2[1] - svggrips[i][1]) < eps
|
|
2766
|
-
) {
|
|
2767
|
-
return;
|
|
2768
|
-
}
|
|
2769
|
-
}
|
|
2770
|
-
svggrips.push([pt2[0], pt2[1], name, order]);
|
|
2771
|
-
}
|
|
2772
|
-
for (let i = 0; i < this.faceplanes.length; i++) {
|
|
2773
|
-
const baseface = this.facenames[i][0];
|
|
2774
|
-
let facecoords = baseface;
|
|
2775
|
-
if (threed) {
|
|
2776
|
-
facecoords = rot.rotateface(facecoords);
|
|
2777
|
-
}
|
|
2778
|
-
if (needfacegrips) {
|
|
2779
|
-
let pt = this.faceplanes[i][0];
|
|
2780
|
-
if (threed) {
|
|
2781
|
-
pt = pt.rotatepoint(rot);
|
|
2782
|
-
}
|
|
2783
|
-
addgrip(i, this.faceplanes[i][1], pt, polyn);
|
|
2784
|
-
}
|
|
2785
|
-
for (let j = 0; j < baseface.length; j++) {
|
|
2786
|
-
if (neededgegrips) {
|
|
2787
|
-
const mp = baseface[j]
|
|
2788
|
-
.sum(baseface[(j + 1) % baseface.length])
|
|
2789
|
-
.smul(0.5);
|
|
2790
|
-
const ep = findelement(this.edgenames, mp);
|
|
2791
|
-
const mpc = facecoords[j]
|
|
2792
|
-
.sum(facecoords[(j + 1) % baseface.length])
|
|
2793
|
-
.smul(0.5);
|
|
2794
|
-
addgrip(i, this.edgenames[ep][1], mpc, 2);
|
|
2795
|
-
}
|
|
2796
|
-
if (needvertexgrips) {
|
|
2797
|
-
const vp = findelement(this.vertexnames, baseface[j]);
|
|
2798
|
-
addgrip(i, this.vertexnames[vp][1], facecoords[j], this.cornerfaces);
|
|
2799
|
-
}
|
|
2800
|
-
}
|
|
2801
|
-
}
|
|
2802
2784
|
const html =
|
|
2803
2785
|
'<svg id="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 800 500">\n' +
|
|
2804
2786
|
'<style type="text/css"><![CDATA[' +
|
|
@@ -2806,58 +2788,27 @@ export class PuzzleGeometry {
|
|
|
2806
2788
|
"]]></style>\n" +
|
|
2807
2789
|
svg.join("") +
|
|
2808
2790
|
"</svg>";
|
|
2809
|
-
this.svggrips = svggrips;
|
|
2810
2791
|
return html;
|
|
2811
2792
|
}
|
|
2812
2793
|
|
|
2813
|
-
public dist(a: number[], b: number[]): number {
|
|
2814
|
-
return Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]);
|
|
2815
|
-
}
|
|
2816
|
-
|
|
2817
|
-
public triarea(a: number[], b: number[], c: number[]): number {
|
|
2818
|
-
const ab = this.dist(a, b);
|
|
2819
|
-
const bc = this.dist(b, c);
|
|
2820
|
-
const ac = this.dist(a, c);
|
|
2821
|
-
const p = (ab + bc + ac) / 2;
|
|
2822
|
-
return Math.sqrt(p * (p - ab) * (p - bc) * (p - ac));
|
|
2823
|
-
}
|
|
2824
|
-
|
|
2825
|
-
public polyarea(coords: number[][]): number {
|
|
2826
|
-
let sum = 0;
|
|
2827
|
-
for (let i = 2; i < coords.length; i++) {
|
|
2828
|
-
sum += this.triarea(coords[0], coords[1], coords[i]);
|
|
2829
|
-
}
|
|
2830
|
-
return sum;
|
|
2831
|
-
}
|
|
2832
|
-
|
|
2833
2794
|
// The colorfrac parameter says how much of the face should be
|
|
2834
2795
|
// colored (vs dividing lines); we default to 0.77 which seems
|
|
2835
2796
|
// to work pretty well. It should be a number between probably
|
|
2836
2797
|
// 0.4 and 0.9.
|
|
2837
|
-
public get3d(
|
|
2838
|
-
|
|
2839
|
-
options?: {
|
|
2840
|
-
stickerColors?: string[];
|
|
2841
|
-
},
|
|
2842
|
-
): StickerDat {
|
|
2843
|
-
const stickers: any = [];
|
|
2844
|
-
const foundations: any = [];
|
|
2798
|
+
public get3d(options?: { stickerColors?: string[] }): StickerDat {
|
|
2799
|
+
const stickers = [];
|
|
2845
2800
|
const rot = this.getInitial3DRotation();
|
|
2846
|
-
const faces
|
|
2847
|
-
const maxdist: number = 0.52 * this.basefaces[0]
|
|
2848
|
-
let avgstickerarea = 0;
|
|
2801
|
+
const faces = [];
|
|
2802
|
+
const maxdist: number = 0.52 * this.basefaces[0].get(0).len();
|
|
2849
2803
|
for (let i = 0; i < this.basefaces.length; i++) {
|
|
2850
|
-
const coords =
|
|
2804
|
+
const coords = this.basefaces[i].rotate(rot);
|
|
2851
2805
|
const name = this.facenames[i][1];
|
|
2852
2806
|
faces.push({ coords: toFaceCoords(coords, maxdist), name });
|
|
2853
|
-
avgstickerarea += this.polyarea(faces[i].coords);
|
|
2854
2807
|
}
|
|
2855
|
-
avgstickerarea /= this.faces.length;
|
|
2856
|
-
const trim = (Math.sqrt(avgstickerarea) * (1 - Math.sqrt(colorfrac))) / 2;
|
|
2857
2808
|
for (let i = 0; i < this.faces.length; i++) {
|
|
2858
2809
|
const facenum = Math.floor(i / this.stickersperface);
|
|
2859
|
-
const cubie = this.
|
|
2860
|
-
const cubieori = this.
|
|
2810
|
+
const cubie = this.facetocubie[i];
|
|
2811
|
+
const cubieori = this.facetoord[i];
|
|
2861
2812
|
const cubiesetnum = this.cubiesetnums[cubie];
|
|
2862
2813
|
const cubieord = this.cubieordnums[cubie];
|
|
2863
2814
|
let color = this.graybyori(cubie)
|
|
@@ -2866,40 +2817,30 @@ export class PuzzleGeometry {
|
|
|
2866
2817
|
if (options?.stickerColors) {
|
|
2867
2818
|
color = options.stickerColors[i];
|
|
2868
2819
|
}
|
|
2869
|
-
|
|
2870
|
-
foundations.push({
|
|
2871
|
-
coords: toFaceCoords(coords, maxdist),
|
|
2872
|
-
color,
|
|
2873
|
-
orbit: this.cubiesetnames[cubiesetnum],
|
|
2874
|
-
ord: cubieord,
|
|
2875
|
-
ori: cubieori,
|
|
2876
|
-
});
|
|
2877
|
-
const fcoords = coords;
|
|
2878
|
-
if (trim && trim > 0) {
|
|
2879
|
-
coords = trimEdges(coords, trim);
|
|
2880
|
-
}
|
|
2820
|
+
const coords = this.faces[i].rotate(rot);
|
|
2881
2821
|
stickers.push({
|
|
2882
2822
|
coords: toFaceCoords(coords, maxdist),
|
|
2883
2823
|
color,
|
|
2884
2824
|
orbit: this.cubiesetnames[cubiesetnum],
|
|
2885
2825
|
ord: cubieord,
|
|
2886
2826
|
ori: cubieori,
|
|
2827
|
+
face: facenum,
|
|
2887
2828
|
});
|
|
2829
|
+
let fcoords = coords;
|
|
2888
2830
|
if (this.duplicatedFaces[i]) {
|
|
2831
|
+
const rotdist = fcoords.length / this.duplicatedFaces[i];
|
|
2889
2832
|
for (let jj = 1; jj < this.duplicatedFaces[i]; jj++) {
|
|
2833
|
+
for (let k = 0; k < rotdist; k++) {
|
|
2834
|
+
fcoords = fcoords.rotateforward();
|
|
2835
|
+
}
|
|
2890
2836
|
stickers.push({
|
|
2891
|
-
coords: toFaceCoords(coords, maxdist),
|
|
2892
|
-
color,
|
|
2893
|
-
orbit: this.cubiesetnames[cubiesetnum],
|
|
2894
|
-
ord: cubieord,
|
|
2895
|
-
ori: jj,
|
|
2896
|
-
});
|
|
2897
|
-
foundations.push({
|
|
2898
2837
|
coords: toFaceCoords(fcoords, maxdist),
|
|
2899
2838
|
color,
|
|
2900
2839
|
orbit: this.cubiesetnames[cubiesetnum],
|
|
2901
2840
|
ord: cubieord,
|
|
2902
2841
|
ori: jj,
|
|
2842
|
+
face: facenum,
|
|
2843
|
+
isDup: true,
|
|
2903
2844
|
});
|
|
2904
2845
|
}
|
|
2905
2846
|
}
|
|
@@ -2908,8 +2849,7 @@ export class PuzzleGeometry {
|
|
|
2908
2849
|
for (let i = 0; i < this.movesetgeos.length; i++) {
|
|
2909
2850
|
const msg = this.movesetgeos[i];
|
|
2910
2851
|
const order = this.movesetorders[i];
|
|
2911
|
-
for (
|
|
2912
|
-
const gn = this.geonormals[j];
|
|
2852
|
+
for (const gn of this.geonormals) {
|
|
2913
2853
|
if (msg[0] === gn[1] && msg[1] === gn[2]) {
|
|
2914
2854
|
grips.push([toCoords(gn[0].rotatepoint(rot), 1), msg[0], order]);
|
|
2915
2855
|
grips.push([
|
|
@@ -2920,18 +2860,30 @@ export class PuzzleGeometry {
|
|
|
2920
2860
|
}
|
|
2921
2861
|
}
|
|
2922
2862
|
}
|
|
2923
|
-
const
|
|
2924
|
-
|
|
2925
|
-
|
|
2863
|
+
const twodmapper = this.generate2dmapping(2880, 2160, 0, false, 1.0);
|
|
2864
|
+
const g = (function () {
|
|
2865
|
+
const irot = rot.invrot();
|
|
2866
|
+
return function (facenum: number, coords: number[]): number[] {
|
|
2867
|
+
let q = new Quat(
|
|
2868
|
+
0,
|
|
2869
|
+
coords[0] * maxdist,
|
|
2870
|
+
-coords[1] * maxdist,
|
|
2871
|
+
coords[2] * maxdist,
|
|
2872
|
+
);
|
|
2873
|
+
q = q.rotatepoint(irot);
|
|
2874
|
+
const x = twodmapper(facenum, q);
|
|
2875
|
+
x[0] /= 2880;
|
|
2876
|
+
x[1] = 1 - x[1] / 2160;
|
|
2877
|
+
return x;
|
|
2926
2878
|
};
|
|
2927
2879
|
})().bind(this);
|
|
2928
2880
|
return {
|
|
2929
2881
|
stickers,
|
|
2930
|
-
foundations,
|
|
2931
2882
|
faces,
|
|
2932
2883
|
axis: grips,
|
|
2933
|
-
unswizzle:
|
|
2884
|
+
unswizzle: this.unswizzle.bind(this),
|
|
2934
2885
|
notationMapper: this.notationMapper,
|
|
2886
|
+
textureMapper: { getuv: g },
|
|
2935
2887
|
};
|
|
2936
2888
|
}
|
|
2937
2889
|
|
|
@@ -2943,8 +2895,7 @@ export class PuzzleGeometry {
|
|
|
2943
2895
|
public getGeoNormal(geoname: string): number[] | undefined {
|
|
2944
2896
|
const rot = this.getInitial3DRotation();
|
|
2945
2897
|
const grip = this.swizzler.unswizzle(geoname);
|
|
2946
|
-
for (
|
|
2947
|
-
const gn = this.geonormals[j];
|
|
2898
|
+
for (const gn of this.geonormals) {
|
|
2948
2899
|
if (grip === gn[1]) {
|
|
2949
2900
|
const r = toCoords(gn[0].rotatepoint(rot), 1);
|
|
2950
2901
|
// This routine is intended to use for the camera location.
|
|
@@ -2967,12 +2918,30 @@ export class PuzzleGeometry {
|
|
|
2967
2918
|
const divid = this.stickersperface;
|
|
2968
2919
|
return Math.floor(facenum / divid);
|
|
2969
2920
|
}
|
|
2921
|
+
|
|
2922
|
+
public textForTwizzleExplorer(): string {
|
|
2923
|
+
return `Faces ${this.baseplanerot.length}
|
|
2924
|
+
Stickers per face ${this.stickersperface}
|
|
2925
|
+
Short edge ${this.shortedge}
|
|
2926
|
+
Cubies ${this.cubies.length}
|
|
2927
|
+
Edge distance ${this.edgedistance}
|
|
2928
|
+
Vertex distance ${this.vertexdistance}`;
|
|
2929
|
+
}
|
|
2930
|
+
|
|
2931
|
+
writeSchreierSims(tw: (s: string) => void) {
|
|
2932
|
+
const os = this.getOrbitsDef(false);
|
|
2933
|
+
const as = os.reassemblySize();
|
|
2934
|
+
tw(`Reassembly size is ${as}`);
|
|
2935
|
+
const ss = schreierSims(this.getMovesAsPerms(), tw);
|
|
2936
|
+
const r = as / ss;
|
|
2937
|
+
tw(`Ratio is ${r}`);
|
|
2938
|
+
}
|
|
2970
2939
|
}
|
|
2971
2940
|
|
|
2972
2941
|
class PGNotation implements MoveNotation {
|
|
2973
2942
|
private cache: { [key: string]: KTransformation } = {};
|
|
2974
|
-
|
|
2975
|
-
constructor(
|
|
2943
|
+
private orbitNames: string[];
|
|
2944
|
+
constructor(private pg: PuzzleGeometry, od: PGOrbitsDef) {
|
|
2976
2945
|
this.orbitNames = od.orbitnames;
|
|
2977
2946
|
}
|
|
2978
2947
|
|
|
@@ -2985,12 +2954,12 @@ class PGNotation implements MoveNotation {
|
|
|
2985
2954
|
// if a move list subset is defined, don't return moves outside the subset.
|
|
2986
2955
|
if (this.pg.parsedmovelist) {
|
|
2987
2956
|
let found = false;
|
|
2988
|
-
for (
|
|
2957
|
+
for (const parsedmove of this.pg.parsedmovelist) {
|
|
2989
2958
|
if (
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2959
|
+
parsedmove[1] === mv[1] &&
|
|
2960
|
+
parsedmove[2] === mv[2] &&
|
|
2961
|
+
parsedmove[3] === mv[3] &&
|
|
2962
|
+
parsedmove[4] === mv[4]
|
|
2994
2963
|
) {
|
|
2995
2964
|
found = true;
|
|
2996
2965
|
}
|
|
@@ -3012,7 +2981,7 @@ class PGNotation implements MoveNotation {
|
|
|
3012
2981
|
undefined,
|
|
3013
2982
|
this.pg.movesetorders[mv[1]],
|
|
3014
2983
|
);
|
|
3015
|
-
const r =
|
|
2984
|
+
const r = PGOrbitsDef.transformToKPuzzle(this.orbitNames, pgmv);
|
|
3016
2985
|
this.cache[key] = r;
|
|
3017
2986
|
return r;
|
|
3018
2987
|
}
|