diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 885f95273..48ac20405 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,3 +1,7 @@ +name: Haskell CI +on: + - push + jobs: build: runs-on: ubuntu-latest @@ -18,16 +22,147 @@ jobs: fi - name: freeze run: cabal freeze - - uses: "actions/cache@v2" + - name: Restore build artifacts + id: build-hslice-restore + uses: "actions/cache/restore@v4" with: key: "${{ runner.os }}-${{ matrix.ghc }}-cabal-${{ hashFiles('cabal.project.freeze') }}" - path: "${{ steps.setup-haskell-cabal.outputs.cabal-store }} dist-newstyle" + path: | + "${{ steps.setup-haskell-cabal.outputs.cabal-store }}" + ~/.cabal/packages + ~/.cabal/store + ~/.cabal/bin + dist-newstyle + ~/.local/bin - name: Install dependencies run: cabal build all --enable-tests --enable-benchmarks --only-dependencies - name: build all run: cabal build all --enable-tests --enable-benchmarks + - name: Save build artifacts + uses: "actions/cache/save@v4" + with: + key: "${{ runner.os }}-${{ matrix.ghc }}-cabal-${{ hashFiles('cabal.project.freeze') }}" + path: | + "${{ steps.setup-haskell-cabal.outputs.cabal-store }}" + ~/.cabal/packages + ~/.cabal/store + ~/.cabal/bin + dist-newstyle + ~/.local/bin + strategy: + matrix: + cabal: + - '3.10' + ghc: + - '9.4.6' + - '9.2.8' + - '9.0.2' + - '8.10.7' + test: + needs: build + runs-on: ubuntu-latest + steps: + - uses: "actions/checkout@v3" + - id: setup-haskell-cabal + uses: "haskell-actions/setup@v2" + with: + cabal-version: "${{ matrix.cabal }}" + enable-stack: false + ghc-version: "${{ matrix.ghc }}" + - name: Update Hackage repository + run: cabal update + - name: cabal.project.local.ci + run: | + if [ -e cabal.project.local.ci ]; then + cp cabal.project.local.ci cabal.project.local + fi + - name: freeze + run: cabal freeze + - name: Restore build artifacts + uses: "actions/cache/restore@v4" + id: build-hslice-restore + with: + key: "${{ runner.os }}-${{ matrix.ghc }}-cabal-${{ hashFiles('cabal.project.freeze') }}" + path: | + "${{ steps.setup-haskell-cabal.outputs.cabal-store }}" + ~/.cabal/packages + ~/.cabal/store + ~/.cabal/bin + dist-newstyle + ~/.local/bin + - name: Install dependencies + run: cabal build all --enable-tests --enable-benchmarks --only-dependencies + - name: build all + run: cabal build all --enable-tests --enable-benchmarks + - name: Save build artifacts + uses: "actions/cache/save@v4" + with: + key: "${{ runner.os }}-${{ matrix.ghc }}-cabal-${{ hashFiles('cabal.project.freeze') }}" + path: | + "${{ steps.setup-haskell-cabal.outputs.cabal-store }}" + ~/.cabal/packages + ~/.cabal/store + ~/.cabal/bin + dist-newstyle + ~/.local/bin - name: test all run: cabal test test-hslice --enable-tests + strategy: + matrix: + cabal: + - '3.10' + ghc: + - '9.4.6' + - '9.2.8' + - '9.0.2' + - '8.10.7' + haddock: + needs: build + runs-on: ubuntu-latest + steps: + - uses: "actions/checkout@v3" + - id: setup-haskell-cabal + uses: "haskell-actions/setup@v2" + with: + cabal-version: "${{ matrix.cabal }}" + enable-stack: false + ghc-version: "${{ matrix.ghc }}" + - name: Update Hackage repository + run: cabal update + - name: cabal.project.local.ci + run: | + if [ -e cabal.project.local.ci ]; then + cp cabal.project.local.ci cabal.project.local + fi + - name: freeze + run: cabal freeze + - name: Restore build artifacts + uses: "actions/cache/restore@v4" + id: build-hslice-restore + with: + key: "${{ runner.os }}-${{ matrix.ghc }}-cabal-${{ hashFiles('cabal.project.freeze') }}" + path: | + "${{ steps.setup-haskell-cabal.outputs.cabal-store }}" + ~/.cabal/packages + ~/.cabal/store + ~/.cabal/bin + dist-newstyle + ~/.local/bin + - name: Install dependencies + run: cabal build all --enable-tests --enable-benchmarks --only-dependencies + - name: build all + run: cabal build all --enable-tests --enable-benchmarks + - name: Save build artifacts + uses: "actions/cache/save@v4" + with: + key: "${{ runner.os }}-${{ matrix.ghc }}-cabal-${{ hashFiles('cabal.project.freeze') }}" + path: | + "${{ steps.setup-haskell-cabal.outputs.cabal-store }}" + ~/.cabal/packages + ~/.cabal/store + ~/.cabal/bin + dist-newstyle + ~/.local/bin - name: haddock all run: cabal haddock all strategy: @@ -39,8 +174,3 @@ jobs: - '9.2.8' - '9.0.2' - '8.10.7' - - '8.8.4' -name: Haskell CI -on: - - push - - pull_request diff --git a/.github/workflows/ormolu.yaml b/.github/workflows/ormolu.yaml index 387855918..77a9125e4 100644 --- a/.github/workflows/ormolu.yaml +++ b/.github/workflows/ormolu.yaml @@ -8,18 +8,26 @@ jobs: ormolu: runs-on: ubuntu-latest steps: - - uses: "actions/checkout@v1" + - uses: "actions/checkout@v3" - - uses: "haskell/actions/setup@v1" + - uses: "haskell-actions/setup@v2" with: cabal-version: "${{ matrix.cabal }}" enable-stack: false ghc-version: "${{ matrix.ghc }}" - + - name: Update Hackage repository + run: cabal update + - name: cabal.project.local.ci + run: | + if [ -e cabal.project.local.ci ]; then + cp cabal.project.local.ci cabal.project.local + fi + - name: freeze + run: cabal freeze - uses: "actions/cache@v2" name: Cache with: - key: "${{ runner.os }}" + key: "${{ runner.os }}-${{ matrix.ghc }}-cabal-${{ hashFiles('cabal.project.freeze') }}" path: | "${{ steps.setup-haskell-cabal.outputs.cabal-store }}" ~/.cabal/packages @@ -32,11 +40,11 @@ jobs: run: | export PATH=$PATH:$HOME/.cabal/bin:$HOME/.local/bin export ORMOLU_VERSION=$(cat ./layout/ormolu.version) - (ormolu -v 2>/dev/null | grep -q $ORMOLU_VERSION) || (cabal update && cabal install ormolu --constraint="ormolu ==$ORMOLU_VERSION") + (ormolu -v 2>/dev/null | grep -q $ORMOLU_VERSION) || (cabal install ormolu --constraint="ormolu ==$ORMOLU_VERSION") test -e $HOME/.local/bin/yq || pip3 install yq shell: bash - - name: Ormolu + - name: Run Ormolu run: | export PATH=$PATH:$HOME/.cabal/bin:$HOME/.local/bin ./layout/ormolu.sh -c @@ -45,6 +53,6 @@ jobs: strategy: matrix: cabal: - - '3.6.2.0' + - '3.10.2.1' ghc: - - '8.8.1' + - '9.4.6' diff --git a/Graphics/Slicer/Math/Arcs.hs b/Graphics/Slicer/Math/Arcs.hs index df5e62f1a..f43c14e51 100644 --- a/Graphics/Slicer/Math/Arcs.hs +++ b/Graphics/Slicer/Math/Arcs.hs @@ -24,6 +24,8 @@ module Graphics.Slicer.Math.Arcs (getFirstArc, getInsideArc, getOutsideArc, towa import Prelude (Bool, ($), (<>), (==), (>), (<=), (&&), (||), error, mempty, otherwise, show) +import Data.Maybe (isNothing) + import Graphics.Slicer.Math.Definitions (Point2, addPoints, distance, makeLineSeg, scalePoint) import Graphics.Slicer.Math.GeometricAlgebra (addVecPairWithErr, ulpVal) @@ -32,6 +34,8 @@ import Graphics.Slicer.Math.Intersections (intersectionOf, isAntiCollinear, isCo import Graphics.Slicer.Math.PGA (PLine2Err(PLine2Err), PPoint2Err, ProjectiveLine(PLine2), ProjectiveLine2, ProjectivePoint2, angleBetween2PL, distance2PP, eToPL, flipL, join2PP, normalizeL, vecOfL) +import Graphics.Slicer.Math.PGAPrimitives (canonicalizedIntersectionOf2PL) + -- | Get a Projective Line in the direction of the inside of a contour. Generates a line bisecting the angle of the intersection between a line constructed from the first two points, and another line constrected from the last two points. getFirstArc :: Point2 -> Point2 -> Point2 -> (ProjectiveLine, PLine2Err) getFirstArc a b c = (res, resErr) @@ -60,6 +64,8 @@ getAcuteArcFromPoints p1 p2 p3 -- | Get a projective line along the angle bisector of the intersection of the two given lines, pointing in the 'acute' direction. -- A wrapper of getAcuteAngleBisectorFromLines, dropping the returning of normalization error of the inputs. +-- Warning: assumes one PLine is toward the point of intersection, and the other is away from the point of intersection +-- FIXME: Precision Loss getInsideArc :: (ProjectiveLine2 a, ProjectiveLine2 b) => (a, PLine2Err) -> (b, PLine2Err) -> (ProjectiveLine, PLine2Err) getInsideArc line1 line2 = (res, resErr) where @@ -70,11 +76,15 @@ getInsideArc line1 line2 = (res, resErr) {-# INLINABLE getAcuteAngleBisectorFromLines #-} getAcuteAngleBisectorFromLines :: (ProjectiveLine2 a, ProjectiveLine2 b) => (a, PLine2Err) -> (b, PLine2Err) -> (ProjectiveLine, (PLine2Err, PLine2Err, PLine2Err)) getAcuteAngleBisectorFromLines line1@(pl1, _) line2@(pl2, _) - | isCollinear line1 line2 = error "Asked to find the acute bisector of two colinear lines!" - | isAntiCollinear line1 line2 = error "Asked to find the acute bisector of two anti-colinear lines!" - | noIntersection line1 line2 = error $ "No intersection between line " <> show line1 <> " and line " <> show line2 <> ".\n" + -- something is wrong? throw an error. + | isNothing (canonicalizedIntersectionOf2PL pl1 pl2) = makeError | otherwise = (PLine2 addVecRes, (npline1Err, npline2Err, PLine2Err addVecErrs mempty mempty mempty mempty mempty)) where + makeError + | isCollinear line1 line2 = error $ "Asked to find the acute bisector of two colinear lines!\n" <> show pl1 <> "\n" <> show pl2 <> "\n" + | isAntiCollinear line1 line2 = error $ "Asked to find the acute bisector of two anti-colinear lines!\n" <> show pl1 <> "\n" <> show pl2 <> "\n" + | noIntersection line1 line2 = error $ "No intersection between line " <> show pl1 <> " and line " <> show pl2 <> ".\n" + | otherwise = error "no error. just seeing how you're doing." (addVecRes, addVecErrs) = addVecPairWithErr lv1 lv2 lv1 = vecOfL $ flipL npline1 lv2 = vecOfL npline2 diff --git a/Graphics/Slicer/Math/PGA.hs b/Graphics/Slicer/Math/PGA.hs index 53074671b..515e77226 100644 --- a/Graphics/Slicer/Math/PGA.hs +++ b/Graphics/Slicer/Math/PGA.hs @@ -299,6 +299,7 @@ class (Show a) => Arcable a where -- | If there is an output arc, return it, along with it's error quotent. outAndErrOf :: (Arcable a) => a -> (ProjectiveLine, PLine2Err) +{-# INLINABLE outAndErrOf #-} outAndErrOf a | hasArc a = (outOf a, errOfOut a) | otherwise = error $ "Asked for out and err of Arcable with no out!\n" <> show a <> "\n" diff --git a/Graphics/Slicer/Math/Skeleton/Cells.hs b/Graphics/Slicer/Math/Skeleton/Cells.hs index 56fe75c65..109fd7ee1 100644 --- a/Graphics/Slicer/Math/Skeleton/Cells.hs +++ b/Graphics/Slicer/Math/Skeleton/Cells.hs @@ -563,7 +563,7 @@ matchDirectionOfSegments firstSegOfNodeTree lastSegOfNodeTree (CellDivide (Divid | lastSegOfNodeTree == outSeg = LastFirst | otherwise = NoMatch --- adjust the last output of the NodeTree so that it goes through the line it's supposed to. +-- | Adjust the last inode of the NodeTree's output so that it goes through the line it's supposed to. redirectLastOut :: NodeTree -> (ProjectiveLine, PLine2Err) -> NodeTree redirectLastOut inNodeTree@(NodeTree eNodes maybeINodeSet) myCrossoverLine | isJust maybeINodeSet = @@ -645,12 +645,12 @@ nodeTreeFromDivision cellDivision@(CellDivide motorcycles target) crossoverIn cr -- Note: If we are using the motorcycle as an out, we use nothing as an out, and use the motorcycle as an in. iNodeOfENodeDivision :: CellDivide -> (ProjectiveLine, PLine2Err) -> (ProjectiveLine, PLine2Err) -> INodeDirection -> MaybeMatch -> ENode -> INode iNodeOfENodeDivision cellDivision crossoverIn crossoverOut iNodeDirection matchDirection eNode + -- FIXME: we don't care about match direction here? flipping the order causes fun. maybe call a sort instead of hand building this? + | iNodeDirection == TowardMotorcycle = makeINode [eNodeOut, crossoverIn, motorcycle, crossoverOut] Nothing | iNodeDirection == TowardOut && matchDirection == LastFirst = makeINode [motorcycle, crossoverIn, eNodeOut] (Just crossoverOut) | iNodeDirection == TowardOut && matchDirection == FirstLast = makeINode [eNodeOut, crossoverIn, motorcycle] (Just crossoverOut) | iNodeDirection == TowardIn && matchDirection == LastFirst = makeINode [motorcycle, crossoverOut, eNodeOut] (Just crossoverIn) | iNodeDirection == TowardIn && matchDirection == FirstLast = makeINode [eNodeOut, crossoverOut, motorcycle] (Just crossoverIn) - | iNodeDirection == TowardMotorcycle && matchDirection == LastFirst = makeINode [crossoverOut, motorcycle, crossoverIn, eNodeOut] Nothing - | iNodeDirection == TowardMotorcycle && matchDirection == FirstLast = makeINode [eNodeOut, crossoverIn, motorcycle, crossoverOut] Nothing | matchDirection == NoMatch = error "no match!" | otherwise = error "wtf!" where @@ -662,12 +662,12 @@ iNodeOfENodeDivision cellDivision crossoverIn crossoverOut iNodeDirection matchD -- Note: If we are using the motorcycle as an out, we use nothing as an out, and use the motorcycle as an in. iNodeOfPlainDivision :: CellDivide -> (ProjectiveLine, PLine2Err) -> (ProjectiveLine, PLine2Err) -> INodeDirection -> MaybeMatch -> INode iNodeOfPlainDivision cellDivision crossoverIn crossoverOut iNodeDirection matchDirection + -- FIXME: we don't care about match direction here? flipping the order causes fun. maybe call a sort instead of hand building this? + | iNodeDirection == TowardMotorcycle = makeINode [crossoverIn, motorcycle, crossoverOut] Nothing | iNodeDirection == TowardOut && matchDirection == LastFirst = makeINode [motorcycle, crossoverIn] (Just crossoverOut) | iNodeDirection == TowardOut && matchDirection == FirstLast = makeINode [crossoverIn, motorcycle] (Just crossoverOut) | iNodeDirection == TowardIn && matchDirection == LastFirst = makeINode [motorcycle, crossoverOut] (Just crossoverIn) | iNodeDirection == TowardIn && matchDirection == FirstLast = makeINode [crossoverOut, motorcycle] (Just crossoverIn) - | iNodeDirection == TowardMotorcycle && matchDirection == LastFirst = makeINode [crossoverOut, motorcycle, crossoverIn] Nothing - | iNodeDirection == TowardMotorcycle && matchDirection == FirstLast = makeINode [crossoverIn, motorcycle, crossoverOut] Nothing | matchDirection == NoMatch = error "no match!" | otherwise = error "wtf!" where diff --git a/Graphics/Slicer/Math/Skeleton/Concave.hs b/Graphics/Slicer/Math/Skeleton/Concave.hs index a0de525fd..ed00eb1e2 100644 --- a/Graphics/Slicer/Math/Skeleton/Concave.hs +++ b/Graphics/Slicer/Math/Skeleton/Concave.hs @@ -70,7 +70,7 @@ import Graphics.Slicer.Math.Lossy (distanceBetweenPPointsWithErr) import Graphics.Slicer.Math.PGA (Arcable(hasArc, outOf), Pointable(canPoint), ProjectiveLine, PLine2Err, cPPointAndErrOf, cPPointOf, distance2PP, flipL, join2PP, outAndErrOf, pLineIsLeft) -import Graphics.Slicer.Math.Skeleton.Definitions (ENode, ENodeSet(ENodeSet), INode(INode), INodeSet(INodeSet), NodeTree(NodeTree), concaveLines, finalINodeOf, finalOutOf, firstInOf, getFirstLineSeg, getLastLineSeg, getPairs, indexPLinesTo, insOf, isLoop, linePairs, loopOfSegSets, makeENode, makeENodes, makeInitialGeneration, makeINode, makeSide, sortedPLines, sortPLinePair) +import Graphics.Slicer.Math.Skeleton.Definitions (ENode, ENodeSet(ENodeSet), INode(INode), INodeSet(INodeSet), NodeTree(NodeTree), concaveLines, finalINodeOf, finalOutOf, firstInOf, getFirstLineSeg, getLastLineSeg, getPairs, insOf, isLoop, linePairs, loopOfSegSets, makeENode, makeENodes, makeInitialGeneration, makeINode, makeSide, sortPLinePair, sortPLinesByReferenceSafe) import Graphics.Slicer.Math.Skeleton.NodeTrees (makeNodeTree, findENodeByOutput, findINodeByOutput) @@ -524,14 +524,14 @@ sortINodesByENodes loop eNodes inSegSets inINodeSet@(INodeSet inChildGenerations withoutPLine :: (ProjectiveLine, PLine2Err) -> [(ProjectiveLine, PLine2Err)] -> [(ProjectiveLine, PLine2Err)] withoutPLine myPLine = filter (\a -> fst a /= fst myPLine) - -- Order the input nodes of an INode. + -- Order the inputs of an INode. orderInsByENodes :: INode -> INode orderInsByENodes inode@(INode _ _ _ out) | isJust out = outRes | otherwise = noOutRes where - outRes = makeINode (indexPLinesTo flippedOut $ sortedPLines $ insOf inode) out - noOutRes = makeINode (indexPLinesTo firstPLine $ sortedPLines $ indexPLinesTo firstPLine $ insOf inode) Nothing + outRes = makeINode (sortPLinesByReferenceSafe flippedOut $ insOf inode) out + noOutRes = makeINode (sortPLinesByReferenceSafe firstPLine $ insOf inode) Nothing flippedOut = case out of (Just (outPLine, outPLineErr)) -> (flipL outPLine, outPLineErr) Nothing -> error "tried to evaluate flippedOut when out was Nothing." diff --git a/Graphics/Slicer/Math/Skeleton/Definitions.hs b/Graphics/Slicer/Math/Skeleton/Definitions.hs index 5a9ae0f9c..0ced757ac 100644 --- a/Graphics/Slicer/Math/Skeleton/Definitions.hs +++ b/Graphics/Slicer/Math/Skeleton/Definitions.hs @@ -56,7 +56,6 @@ module Graphics.Slicer.Math.Skeleton.Definitions ( getFirstLineSeg, getLastLineSeg, getPairs, - indexPLinesTo, iNodeHasIn, insOf, isLoop, @@ -70,16 +69,19 @@ module Graphics.Slicer.Math.Skeleton.Definitions ( makeINode, makeSide, oneSideOf, - sortedPLines, sortPLinePair, - sortPLinesByReference + sortPLinesByReference, + sortPLinesByReferenceSafe, + sortPLinesWithoutReference ) where -import Prelude (Eq, Show, Bool(True, False), Ordering(EQ, LT,GT), any, concatMap, elem, not, otherwise, (.), ($), (<), (<$>), (==), (/=), (<=), error, (&&), fst, (<>), show, snd, mempty) +import Prelude (Eq, Int, Show, Bool(True, False), Ordering(EQ, LT,GT), any, elem, not, null, otherwise, (.), ($), (<), (+), (<$>), (==), (/=), (<=), error, (&&), fst, (<>), show, snd, mempty) -import qualified Prelude as PL (head, last) +import Data.Bifunctor (first) -import Data.List (filter, length, sortBy) +import Data.List (concatMap, filter, length, sortBy) + +import qualified Data.List as DL (head, last) import Data.List.NonEmpty (NonEmpty) @@ -93,13 +95,13 @@ import qualified Slist as SL (last, head, init) import Slist.Type (Slist(Slist)) -import Graphics.Slicer.Math.Arcs (getFirstArc) +import Graphics.Slicer.Math.Arcs (getFirstArc, getInsideArc) import Graphics.Slicer.Math.Definitions (Contour, LineSeg(LineSeg), Point2, endPoint, lineSegsOfContour, makeLineSeg, mapWithFollower, startPoint) import Graphics.Slicer.Math.GeometricAlgebra (addVecPair, ulpVal) -import Graphics.Slicer.Math.Intersections (intersectionsAtSamePoint, noIntersection, isAntiCollinear) +import Graphics.Slicer.Math.Intersections (intersectionsAtSamePoint, noIntersection, isAntiCollinear, isCollinear) import Graphics.Slicer.Math.Lossy (eToPLine2) @@ -178,7 +180,7 @@ cPPointAndErrOfINode :: INode -> (ProjectivePoint, PPoint2Err) cPPointAndErrOfINode iNode | allPointsSame = case results of [] -> error $ "cannot get a PPoint of this iNode: " <> show iNode <> "/n" - l -> PL.head l + l -> DL.head l -- Allow the pebbles to vote. | otherwise = case safeLast (slist $ count_ results) of Nothing -> error $ "cannot get a PPoint of this iNode: " <> show iNode <> "/n" @@ -295,7 +297,7 @@ oneSideOf (ENodeSet sides) = SL.head sides -- | get the ENodes that a side is composed of. eNodesOfSide :: Side -> [ENode] -eNodesOfSide (Side (first,Slist more _)) = first : more +eNodesOfSide (Side (firstSide,Slist more _)) = firstSide : more -- | A set of Interior nodes that are intersections of ENodes or other INodes. -- nodes are divided into 'generations', where each generation is a set of nodes that (may) result in the next set of nodes. the last generation always contains just one node. @@ -335,15 +337,15 @@ getPairs (x:xs) = ((x,) <$> xs) <> getPairs xs -- | Determine if the given line segment set contains just one loop. isLoop :: Slist [LineSeg] -> Bool isLoop inSegSets@(Slist rawSegSets _) - | len inSegSets == 1 && length (PL.head rawSegSets) == 1 = False + | len inSegSets == 1 && length (DL.head rawSegSets) == 1 = False | startPoint firstSeg == endPoint lastSeg = True | otherwise = gapDistance <= ulpVal gapDistanceErr where (gapDistance, (_,_, gapDistanceErr)) = distance2PP (eToPP $ endPoint lastSeg, mempty) (eToPP $ startPoint firstSeg, mempty) (lastSeg, firstSeg) = case inSegSets of (Slist [] _) -> error "no segments!" - oneOrMoreSets@(Slist ((_:_:_):_) _) -> (PL.last $ SL.last oneOrMoreSets, PL.head $ SL.head oneOrMoreSets) - oneOrMoreSets@(Slist (_:_:_) _) -> (PL.last $ SL.last oneOrMoreSets, PL.head $ SL.head oneOrMoreSets) + oneOrMoreSets@(Slist ((_:_:_):_) _) -> (DL.last $ SL.last oneOrMoreSets, DL.head $ SL.head oneOrMoreSets) + oneOrMoreSets@(Slist (_:_:_) _) -> (DL.last $ SL.last oneOrMoreSets, DL.head $ SL.head oneOrMoreSets) (Slist _ _) -> error "just one segment?" -- | Get the first line segment of an ENode. @@ -362,8 +364,8 @@ linePairs c = mapWithFollower (,) $ lineSegsOfContour c linePairs contour = rotateRight $ mapWithNeighbors (\a b c -> (handleLineSegError $ lineSegFromEndpoints a b, handleLineSegError $ lineSegFromEndpoints b c)) $ pointsOfContour contour where - rotateLeft a = PL.last a : PL.init a - rotateRight a = PL.init a <> [PL.last a] + rotateLeft a = DL.last a : DL.init a + rotateRight a = DL.init a <> [DL.last a] -} -- | A smart constructor for INodes. @@ -371,8 +373,8 @@ makeINode :: [(ProjectiveLine, PLine2Err)] -> Maybe (ProjectiveLine,PLine2Err) - makeINode pLines maybeOut = case pLines of [] -> error "tried to construct an INode with no inputs" [onePLine] -> error $ "tried to construct an INode from one input: " <> show onePLine <> "\n" - [first,second] -> INode first second (slist []) maybeOut - (first:second:more) -> INode first second (slist more) maybeOut + [firstPLine,secondPLine] -> INode firstPLine secondPLine (slist []) maybeOut + (firstPLine:secondPLine:more) -> INode firstPLine secondPLine (slist more) maybeOut -- | Get the output of the given nodetree. fails if the nodetree has no output. finalPLine :: NodeTree -> (ProjectiveLine, PLine2Err) @@ -442,21 +444,9 @@ concaveLines seg1 seg2 pv1 = vecOfL $ eToPLine2 seg1 pv2 = vecOfL $ flipL $ eToPLine2 seg2 --- | Sort a set of PLines in counterclockwise order, to match the counterclockwise order of contours. --- NOTE: when given the same PLines in a different list, may chose a different head / tail. -{-# INLINABLE sortedPLines #-} -sortedPLines :: (ProjectiveLine2 a) => [(a, PLine2Err)] -> [(a, PLine2Err)] -sortedPLines pLines - -- we cannot sort two or less PLines. - | length pLines < 3 = pLines - | otherwise = sortBy sortFun pLines - where - sortFun (pLine1,_) (pLine2,_) = case pLine2 `pLineIsLeft` pLine1 of - Just True -> LT - _ -> GT - -- | Sort a set of PLines in counterclockwise order, starting with the PLine clesest to the reference PLine. --- Assumes all PLines meet in a point? +-- Assumes all PLines meet in a point. +-- May fail, if multiple input PLines are (anti)collinear to the reference PLine. {-# INLINABLE sortPLinesByReference #-} sortPLinesByReference :: (ProjectiveLine2 a) => (a, PLine2Err) -> [(a, PLine2Err)] -> [(a, PLine2Err)] sortPLinesByReference refPLine@(rawRefPLine, _) pLines @@ -476,9 +466,97 @@ sortPLinesByReference refPLine@(rawRefPLine, _) pLines <> "pLines: " <> show (fst . normalizeL . fst <$> pLines) <> "\n" (Just a) -> a +-- | Sort a set of PLines in counterclockwise order, starting with the PLine clesest to the reference PLine. +-- Assumes all PLines meet in a point. +-- Contains regereration logic, to create a new non-colinear reference line, if the reference line is colinear to an input line. +sortPLinesByReferenceSafe :: (ProjectiveLine, PLine2Err) -> [(ProjectiveLine, PLine2Err)] -> [(ProjectiveLine, PLine2Err)] +sortPLinesByReferenceSafe inReference pLines + | length pLines < 2 = pLines + | not $ null (filter (`isCollinear` inReference) pLines) = if DL.head res == inReference + then res + else error $ "we sorted wrong?\n" + <> "inReference: " <> show (fst inReference) <> "\n" + <> "head of PLines: " <> show (fst $ DL.head res) <> "\n" + <> "foundReference: " <> show (fst foundReference) <> "\n" + <> "Result: " <> show (fst <$> res) <> "\n" + | otherwise = res + where + res = sortPLinesByReference foundReference pLines + -- either use the reference given, or create a new one, to the right of the given reference. + foundReference = reference' inReference 0 + where + reference' :: (ProjectiveLine, PLine2Err) -> Int -> (ProjectiveLine, PLine2Err) + reference' maybeReference count + | count == 50 = whoops + | null colinearPLines && null antiColinearPLines = maybeReference + -- A usable substitute for the given reference pLine has no colinear, or anticolinear PLines, and all of the right side PLines are still on the right side. + | not (null remainingColinearPLines) = loop + | not (null remainingAntiColinearPLines) = loop + | filter (\a -> fst a `pLineIsLeft` (fst maybeReference) == Just False) rightPLines /= rightPLines = loop + | otherwise = maybeReference + where + whoops = error $ "whoops!\n" + <> "count: " <> show count <> "\n" + <> "pLines: " <> show (fst . normalizeL . fst <$> pLines) <> "\n" + <> "inReference: " <> show (fst . normalizeL $ fst inReference) <> "\n" + <> "maybeReference: " <> show (fst . normalizeL $ fst maybeReference) <> "\n" + <> "colinearPLines: " <> show ( fst . normalizeL . fst <$> colinearPLines) <> "\n" + <> "remainingColinearPLines: " <> show ( fst . normalizeL . fst <$> remainingColinearPLines) <> "\n" + <> "antiColinearPLines: " <> show (fst . normalizeL . fst <$> antiColinearPLines) <> "\n" + <> "remainingAntiColinearPLines: " <> show (fst . normalizeL . fst <$> remainingAntiColinearPLines) <> "\n" + <> "leftPLines: " <> show (fst . normalizeL . fst <$> leftPLines) <> "\n" + <> "rightPLines: " <> show (fst . normalizeL . fst <$> rightPLines) <> "\n" + <> "maybeReference `pLineIsLeft` inReference: " <> show (fst maybeReference `pLineIsLeft` fst inReference) <> "\n" + loop = reference' newPLine (count+1) + leftPLines = filter (\b -> (fst b) `pLineIsLeft` (fst inReference) == Just True) pLines + rightPLines = filter (\b -> (fst b) `pLineIsLeft` (fst inReference) == Just False) pLines + colinearPLines = filter (\b -> (fst b) `pLineIsLeft` (fst inReference) == Nothing && isCollinear inReference b) pLines + antiColinearPLines = filter (\b -> (fst b) `pLineIsLeft` (fst inReference) == Nothing && isAntiCollinear inReference b) pLines + remainingColinearPLines = filter (\b -> (fst b) `pLineIsLeft` (fst maybeReference) == Nothing && isCollinear maybeReference b) pLines + remainingAntiColinearPLines = filter (\b -> (fst b) `pLineIsLeft` (fst maybeReference) == Nothing && isAntiCollinear maybeReference b) pLines + newPLine + | maybeReference /= inReference = getInsideArc (first flipL maybeReference) inReference + | not (null goodRightRes) = DL.head goodRightRes + | not (null goodLeftRes) = DL.head goodLeftRes + | otherwise = whoops + where + goodRightRes = filter filterFun $ getInsideArc (first flipL maybeReference) <$> rightPLines + goodLeftRes = filter filterFun $ first flipL . getInsideArc maybeReference <$> leftPLines + -- FIXME: sometimes we end up with an insideArc that is Just True. filter it out. + filterFun v = case fst v `pLineIsLeft` fst inReference of + Just False -> True +-- Just True -> error "went backwards" + _ -> False + +-- | Sort a set of PLines in counterclockwise order, starting with the PLine closest to the reference PLine. +-- Assumes all PLines meet in a common single point. +-- Contains logic to select a new PLine from the PLine set to sort by. +sortPLinesWithoutReference :: [(ProjectiveLine, PLine2Err)] -> [(ProjectiveLine, PLine2Err)] +sortPLinesWithoutReference pLines + | length pLines < 3 = pLines + | otherwise = sortPLinesByReferenceSafe foundReference pLines + where + foundReference = reference' pLines [] + where + reference' :: [(ProjectiveLine, PLine2Err)] -> [(ProjectiveLine, PLine2Err)] -> (ProjectiveLine, PLine2Err) + reference' inPLines checkedPLines = + case inPLines of + [] -> error "impossible" + [a] -> a + [a,b] -> if any (\x -> (fst a) `pLineIsLeft` (fst x) == Nothing) $ b:checkedPLines + then if any (\x -> (fst b) `pLineIsLeft` (fst x) == Nothing) $ a:checkedPLines + then reference' [newPLine,a,b] checkedPLines + else b + else a + where + newPLine = getInsideArc a b + (a:xs) -> if any (\x -> (fst a) `pLineIsLeft` (fst x) == Nothing) $ xs <> checkedPLines + then reference' xs (a:checkedPLines) + else a + -- | sort two PLines against the reference PLine, flipped. -- Returns the two PLines in a counterclockwise order, from the perspective of our reference PLine after flipping. -sortPLinePair :: (ProjectiveLine, PLine2Err) -> (ProjectiveLine, PLine2Err) -> (ProjectiveLine, PLine2Err) -> [(ProjectiveLine, PLine2Err)] +sortPLinePair :: (ProjectiveLine2 a) => (a, PLine2Err) -> (a, PLine2Err) -> (a, PLine2Err) -> [(a, PLine2Err)] {-# INLINABLE sortPLinePair #-} sortPLinePair pLine1@(rawPLine1,_) pLine2@(rawPLine2,_) (rawRefPLine, rawRefPLineErr) | refPLineFlipped == rawPLine2 = error "here." @@ -522,15 +600,6 @@ pLineOrderCCW pLine1@(rawPLine1,_) pLine2@(rawPLine2,_) refPLine@(rawRefPLine, _ LT -> Just GT _ -> error "wat" --- | Take a sorted list of PLines, and make sure the list starts with the pline closest to (but not left of) the given PLine. --- Does not require the input PLine to be in the set. -{-# INLINABLE indexPLinesTo #-} -indexPLinesTo :: (ProjectiveLine2 a) => (a, PLine2Err) -> [(a, PLine2Err)] -> [(a,PLine2Err)] -indexPLinesTo firstPLine pLines = pLinesBeforeIndex firstPLine pLines <> pLinesAfterIndex firstPLine pLines - where - pLinesBeforeIndex myFirstPLine = filter (\a -> fst a `pLineIsLeft` fst myFirstPLine /= Just False) - pLinesAfterIndex myFirstPLine = filter (\a -> fst a `pLineIsLeft` fst myFirstPLine == Just False) - -- | Find the last PLine of an INode. lastInOf :: INode -> (ProjectiveLine, PLine2Err) lastInOf (INode _ secondPLine morePLines _) @@ -572,7 +641,7 @@ makeENodes segs = case segs of loopOfSegSets :: Slist [LineSeg] -> ENode loopOfSegSets inSegSets = case inSegSets of (Slist [] _) -> error "no" - oneOrMoreSets@(Slist ((_:_:_):_) _) -> makeENode (startPoint $ PL.last $ SL.last oneOrMoreSets) (startPoint $ PL.head $ SL.head oneOrMoreSets) (endPoint $ PL.head $ SL.head oneOrMoreSets) - oneOrMoreSets@(Slist (_:_:_) _) -> makeENode (startPoint $ PL.last $ SL.last oneOrMoreSets) (startPoint $ PL.head $ SL.head oneOrMoreSets) (endPoint $ PL.head $ SL.head oneOrMoreSets) + oneOrMoreSets@(Slist ((_:_:_):_) _) -> makeENode (startPoint $ DL.last $ SL.last oneOrMoreSets) (startPoint $ DL.head $ SL.head oneOrMoreSets) (endPoint $ DL.head $ SL.head oneOrMoreSets) + oneOrMoreSets@(Slist (_:_:_) _) -> makeENode (startPoint $ DL.last $ SL.last oneOrMoreSets) (startPoint $ DL.head $ SL.head oneOrMoreSets) (endPoint $ DL.head $ SL.head oneOrMoreSets) (Slist _ _) -> error "yes" diff --git a/Graphics/Slicer/Math/Skeleton/Face.hs b/Graphics/Slicer/Math/Skeleton/Face.hs index 4f4dd2767..6c6dbd14a 100644 --- a/Graphics/Slicer/Math/Skeleton/Face.hs +++ b/Graphics/Slicer/Math/Skeleton/Face.hs @@ -22,14 +22,12 @@ -- | This file contains code for creating a series of Faces, covering a straight skeleton. module Graphics.Slicer.Math.Skeleton.Face (Face(Face), orderedFacesOf, facesOf) where -import Prelude (Bool(True), Eq, Show, (==), all, any, otherwise, (<$>), ($), length, error, (<>), show, (<>), null, not, and, snd, (&&), (.), (/=), fst) +import Prelude (Bool(True), Eq, Show, (==), (||), all, otherwise, (<$>), ($), length, error, (<>), show, null, not, and, snd, (&&), (.), (/=), fst) import Data.Either (isRight) import Data.List (filter, uncons) -import qualified Data.List as DL (head) - import Data.List.Extra (unsnoc) import Data.Maybe (isNothing, fromJust, fromMaybe, Maybe(Just, Nothing), isJust) @@ -38,15 +36,15 @@ import Slist.Type (Slist(Slist)) import Slist (slist, isEmpty, len, init, tail, take, dropWhile, head, one, last) -import Slist as SL (reverse) +import qualified Data.List as DL (head) -import Graphics.Slicer.Math.Arcs (getInsideArc) +import qualified Slist as SL (reverse) import Graphics.Slicer.Math.Definitions (LineSeg, mapWithFollower) import Graphics.Slicer.Math.Intersections (noIntersection, intersectionBetween, isCollinear) -import Graphics.Slicer.Math.Skeleton.Definitions (StraightSkeleton(StraightSkeleton), ENode, INode(INode), ENodeSet(ENodeSet), INodeSet(INodeSet), NodeTree(NodeTree), allPLinesOfINode, eNodesOfSide, getFirstLineSeg, getLastLineSeg, oneSideOf, finalINodeOf, finalOutOf, ancestorsOf, firstInOf, lastInOf, sortPLinesByReference) +import Graphics.Slicer.Math.Skeleton.Definitions (StraightSkeleton(StraightSkeleton), ENode, INode(INode), ENodeSet(ENodeSet), INodeSet(INodeSet), NodeTree(NodeTree), allPLinesOfINode, getFirstLineSeg, getLastLineSeg, finalINodeOf, finalOutOf, ancestorsOf, firstInOf, lastInOf) import Graphics.Slicer.Math.Skeleton.NodeTrees (lastSegOf, findENodeByOutput, findINodeByOutput, firstSegOf, lastENodeOf, firstENodeOf, pathFirst, pathLast) @@ -161,42 +159,64 @@ getFaces (NodeTree eNodeSet iNodeSet) = getFaces' iNodeSet eNodeSet iNodeSet getFaces' :: Maybe INodeSet -> ENodeSet -> Maybe INodeSet -> INode -> [Face] getFaces' _ (ENodeSet (Slist [] _)) _ _ = error "no sides?" getFaces' _ (ENodeSet (Slist (_:_:_) _)) _ _ = error "too many sides?" -getFaces' origINodeSet eNodeSet iNodeSet iNode = findFacesRecurse iNode mySortedPLines +getFaces' origINodeSet eNodeSet iNodeSet iNode = findFacesRecurse iNode myPLines where - mySortedPLines - | hasArc iNode = iNodeRes - | otherwise = noINodeRes - where - iNodeRes = (\(Slist a _) -> sortPLinesByReference flippedOut a) $ allPLinesOfINode iNode - where - flippedOut = (\(outPLine, outPLineErr) -> (flipL outPLine, outPLineErr)) $ outAndErrOf iNode - noINodeRes = (\(Slist a _) -> sortPLinesByReference foundReference a)$ allPLinesOfINode iNode - firstPLine = DL.head mySortedPLines + myPLines = (\(Slist a _) -> a) $ allPLinesOfINode iNode + firstPLine = DL.head myPLines -- | responsible for placing faces under the first pline given (if applicable), and between that pline, and the following pline. then.. recurse! findFacesRecurse :: INode -> [(ProjectiveLine, PLine2Err)] -> [Face] findFacesRecurse myINode pLines = case pLines of [] -> error "we should never get here." -- Just one PLine? assume we're the last one. do not place a face, but do place faces under the PLine. - [onePLine] -> placeFacesBeneath onePLine - <> placeFaceBetween onePLine firstPLine - -- More than one PLine? place faces under onePLine, place a face between onePLine and anotherPLine, and recurse! - (onePLine : anotherPLine : myMorePLines) -> placeFacesBeneath onePLine - <> placeFaceBetween onePLine anotherPLine - <> findFacesRecurse myINode (anotherPLine:myMorePLines) + [pLine] -> placeFacesBeneath pLine + <> placeFaceBetween pLine firstPLine + -- More than one PLine? place faces under pLine1, place a face between pLine1 and pLine2, and recurse! + (pLine1 : pLine2 : myMorePLines) -> placeFacesBeneath pLine1 + <> placeFaceBetween pLine1 pLine2 + <> findFacesRecurse myINode (pLine2:myMorePLines) where - -- zero or one face, not a real list. + -- returns only zero or one face. not a real list. placeFaceBetween :: (ProjectiveLine, PLine2Err) -> (ProjectiveLine, PLine2Err) -> [Face] - placeFaceBetween onePLine anotherPLine - | hasArc myINode && isCollinear (outAndErrOf myINode) onePLine = [] -- don't place faces along the incoming PLine. the caller does that. - | hasArc myINode && isCollinear (outAndErrOf myINode) anotherPLine = [] -- don't place faces along the incoming PLine. the caller does that. - | otherwise = [areaBetween eNodeSet origINodeSet onePLine anotherPLine] + placeFaceBetween pLine1 pLine2 + | hasArc myINode && isCollinear (outAndErrOf myINode) pLine1 = [] -- don't place faces along the incoming PLine. the caller does that. + | hasArc myINode && isCollinear (outAndErrOf myINode) pLine2 = [] -- don't place faces along the incoming PLine. the caller does that. + | getFirstLineSeg eNode1Last == getLastLineSeg eNode2First || + getLastLineSeg eNode1Last == getFirstLineSeg eNode2First = [areaBetween eNodeSet origINodeSet pLine1 eNode1Last pLine2 eNode2First] + | getFirstLineSeg eNode1First == getLastLineSeg eNode2Last || + getLastLineSeg eNode1First == getFirstLineSeg eNode2Last = errBackwards -- [areaBetween eNodeSet origINodeSet pLine2 eNode2Last pLine1 eNode1First] + | otherwise = errNotNeighbors + where + eNode1Last = lastDescendent eNodeSet origINodeSet pLine1 + eNode1First = firstDescendent eNodeSet origINodeSet pLine1 + eNode2First = firstDescendent eNodeSet origINodeSet pLine2 + eNode2Last = lastDescendent eNodeSet origINodeSet pLine2 + errNotNeighbors = error $ "asked to place a face between two ENodes that do not neighbor:\n" + <> "ENode1Last: " <> show eNode1Last <> "\n" + <> "ENode1First: " <> show eNode1First <> "\n" + <> "ENode2First: " <> show eNode2First <> "\n" + <> "ENode2Last: " <> show eNode2Last <> "\n" + <> "origINodeSet: " <> show origINodeSet <> "\n" + <> "myINode: " <> show myINode <> "\n" + <> "pLines: " <> show pLines <> "\n" + <> "pLine1: " <> show pLine1 <> "\n" + <> "pLine2: " <> show pLine2 <> "\n" + errBackwards = error $ "asked to place a face between two ENodes in reverse order:\n" + <> "ENode1Last: " <> show eNode1Last <> "\n" + <> "ENode1First: " <> show eNode1First <> "\n" + <> "ENode2First: " <> show eNode2First <> "\n" + <> "ENode2Last: " <> show eNode2Last <> "\n" + <> "origINodeSet: " <> show origINodeSet <> "\n" + <> "myINode: " <> show myINode <> "\n" + <> "pLines: " <> show pLines <> "\n" + <> "pLine1: " <> show pLine1 <> "\n" + <> "pLine2: " <> show pLine2 <> "\n" placeFacesBeneath :: (ProjectiveLine, PLine2Err) -> [Face] - placeFacesBeneath onePLine - | isENode eNodeSet (fst onePLine) = [] -- don't climb down an enode, you're done - | hasArc myINode && isCollinear (outAndErrOf myINode) onePLine = [] -- don't try to climb back up the tree + placeFacesBeneath pLine + | isENode eNodeSet (fst pLine) = [] -- don't climb down an enode, you're done + | hasArc myINode && isCollinear (outAndErrOf myINode) pLine = [] -- don't try to climb back up the tree | isNothing iNodeSet = error "we need INodes here." - | ancestorsOf (fromJust iNodeSet) /= [] = myGetFaces $ onlyOne $ filter (\a -> outAndErrOf (finalINodeOf a) == onePLine) $ ancestorsOf (fromJust iNodeSet) + | ancestorsOf (fromJust iNodeSet) /= [] = myGetFaces $ onlyOne $ filter (\a -> outAndErrOf (finalINodeOf a) == pLine) $ ancestorsOf (fromJust iNodeSet) | otherwise = error "no between to plant?" where onlyOne :: (Show a) => [a] -> a @@ -208,39 +228,19 @@ getFaces' origINodeSet eNodeSet iNodeSet iNode = findFacesRecurse iNode mySorted | otherwise = error "fail!" where -- FIXME: repair firstINodeOfPLine so it does not need the whole INodeSet. - firstINode = firstINodeOfPLine eNodeSet (fromJust iNodeSet) onePLine - foundReference = reference' (outAndErrOf <$> (eNodesOfSide $ oneSideOf eNodeSet)) [] - where - reference' :: [(ProjectiveLine, PLine2Err)] -> [(ProjectiveLine, PLine2Err)] -> (ProjectiveLine, PLine2Err) - reference' inPLines checkedPLines = - case inPLines of - [] -> error "impossible" - [a] -> a - -- FIXME: shouldn't we bisect the two PLines the largest distance apart? - [a,b] -> if any (\x -> (fst a) `pLineIsLeft` (fst x) == Nothing) $ b:checkedPLines - then if any (\x -> (fst b) `pLineIsLeft` (fst x) == Nothing) $ a:checkedPLines - then reference' [newPLine,a,b] checkedPLines - else b - else a - where - newPLine = getInsideArc a b - (a:xs) -> if any (\x -> (fst a) `pLineIsLeft` (fst x) == Nothing) $ xs <> checkedPLines - then reference' xs (a:checkedPLines) - else a + firstINode = firstINodeOfPLine eNodeSet (fromJust iNodeSet) pLine --- | Create a face covering the space between two PLines with a single Face. +-- | Create a single face covering the space between two PLine. -- Both PLines must be a part of the same INode. -- No other PLines from this iNode must travel between the two given PLines. -areaBetween :: ENodeSet -> Maybe INodeSet -> (ProjectiveLine, PLine2Err) -> (ProjectiveLine, PLine2Err) -> Face -areaBetween (ENodeSet (Slist [] _)) _ _ _ = error "no sides?" -areaBetween (ENodeSet (Slist (_:_:_) _)) _ _ _ = error "too many sides?" -areaBetween eNodeSet@(ENodeSet (Slist [_] _)) iNodeSet pLine1 pLine2 +areaBetween :: ENodeSet -> Maybe INodeSet -> (ProjectiveLine, PLine2Err) -> ENode -> (ProjectiveLine, PLine2Err) -> ENode -> Face +areaBetween (ENodeSet (Slist [] _)) _ _ _ _ _ = error "no sides?" +areaBetween (ENodeSet (Slist (_:_:_) _)) _ _ _ _ _ = error "too many sides?" +areaBetween eNodeSet@(ENodeSet (Slist [_] _)) iNodeSet pLine1 eNode1 pLine2 eNode2 | getFirstLineSeg eNode1 == getLastLineSeg eNode2 = faceOrError eNode1 (arcsToLastDescendent pLine1) (arcsToFirstDescendent pLine2) eNode2 | getLastLineSeg eNode1 == getFirstLineSeg eNode2 = faceOrError eNode2 (arcsToLastDescendent pLine2) (arcsToFirstDescendent pLine1) eNode1 - | otherwise = error $ "found ENodes that do not follow.\n" <> show eNode1 <> "\n" <> show eNode2 <> "\n" <> show eNodeSet <> "\n" <> show iNodeSet <> "\n" + | otherwise = error $ "found ENodes that do not follow.\n" <> show eNode1 <> "\n" <> show eNode2 <> "\n" <> show eNodeSet <> "\n" <> show iNodeSet <> "\n" where - eNode1 = lastDescendent eNodeSet iNodeSet pLine1 - eNode2 = firstDescendent eNodeSet iNodeSet pLine2 arcsToLastDescendent myPLine | getFirstLineSeg eNode1 == getLastLineSeg eNode2 = flipArc <$> pathToLastDescendent eNodeSet iNodeSet myPLine | getLastLineSeg eNode1 == getFirstLineSeg eNode2 = pathToLastDescendent eNodeSet iNodeSet myPLine diff --git a/layout/ormolu.version b/layout/ormolu.version index 473b31b42..67c942947 100644 --- a/layout/ormolu.version +++ b/layout/ormolu.version @@ -1 +1 @@ -0.1.4.1 +0.5.3.0 diff --git a/tests/GoldenSpec/Spec.hs b/tests/GoldenSpec/Spec.hs index 51a0af9c4..2333c76b4 100644 --- a/tests/GoldenSpec/Spec.hs +++ b/tests/GoldenSpec/Spec.hs @@ -52,6 +52,7 @@ import Graphics.Slicer.Math.Skeleton.Line (insetBy, insetMany, infiniteInset) goldenSpec :: Spec goldenSpec = describe "golden tests" $ do + golden "C0-Divide" $ onlyOne $ findDivisions c0 $ fromJust $ crashMotorcycles c0 [] golden "C0-Cell1" $ cellFrom $ findFirstCellOfContour c0 $ findDivisions c0 $ fromMaybe (error "Got Nothing") $ crashMotorcycles c0 [] golden "C0-Cell1-NodeTree" $ fst $ getRawNodeTreeOfCell $ cellFrom $ findFirstCellOfContour c0 $ findDivisions c0 $ fromJust $ crashMotorcycles c0 [] golden "C0-Remainder1" $ onlyOne $ remainderFrom $ findFirstCellOfContour c0 $ findDivisions c0 $ fromJust $ crashMotorcycles c0 [] @@ -59,20 +60,19 @@ goldenSpec = describe "golden tests" $ do golden "C0-Cell2-NodeTree" $ fst $ getRawNodeTreeOfCell $ cellFrom $ findNextCell $ onlyOne $ remainderFrom $ findFirstCellOfContour c0 $ findDivisions c0 $ fromJust $ crashMotorcycles c0 [] golden "C0-MotorcycleCell1" $ head $ allMotorcycleCells c0 $ fromJust $ crashMotorcycles c0 [] golden "C0-MotorcycleCell2" $ last $ allMotorcycleCells c0 $ fromJust $ crashMotorcycles c0 [] - golden "C0-Straight_Skeleton" $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c0 [] - goldens "C0-Straight_Skeleton_And_Inset" [ toGanja $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c0 [] - , toGanja $ onlyOne $ contoursFrom $ insetBy 0.1 $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c0 []] - goldens "C0-Straight_Skeleton_And_Four_Insets" ([ toGanja $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c0 []] <> - (toGanja <$> (contoursFrom $ insetMany 0.1 4 $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c0 []))) - goldens "C0-Straight_Skeleton_And_Insets" ([ toGanja $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c0 []] <> - (toGanja <$> (infiniteInset 0.1 $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c0 []))) golden "C0-NodeTree" $ addNodeTreesAlongDivide (fst $ getRawNodeTreeOfCell (cellFrom $ findFirstCellOfContour c0 $ findDivisions c0 $ fromJust $ crashMotorcycles c0 [])) (fst $ getRawNodeTreeOfCell (cellFrom $ findNextCell $ onlyOne $ remainderFrom $ findFirstCellOfContour c0 $ findDivisions c0 $ fromJust $ crashMotorcycles c0 [])) (onlyOne $ findDivisions c0 $ fromJust $ crashMotorcycles c0 []) - golden "C0-Divide" $ onlyOne $ findDivisions c0 $ fromJust $ crashMotorcycles c0 [] + golden "C0-Straight_Skeleton" $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c0 [] golden "C0-Faces-Default" $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c0 [] golden "C0-Faces-Ordered" $ orderedFacesOf c0l0 (fromMaybe (error "got Nothing") $ findStraightSkeleton c0 []) + goldens "C0-Straight_Skeleton_And_Inset" [ toGanja $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c0 [] + , toGanja $ onlyOne $ contoursFrom $ insetBy 0.1 $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c0 []] + goldens "C0-Straight_Skeleton_And_Four_Insets" ([ toGanja $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c0 []] <> + (toGanja <$> (contoursFrom $ insetMany 0.1 4 $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c0 []))) + goldens "C0-Straight_Skeleton_And_Insets" ([ toGanja $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c0 []] <> + (toGanja <$> (infiniteInset 0.1 $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c0 []))) golden "C1-Cell1" $ cellFrom $ findFirstCellOfContour c1 $ findDivisions c1 $ fromMaybe (error "Got Nothing") $ crashMotorcycles c1 [] golden "C1-Cell1-NodeTree" $ fst $ getRawNodeTreeOfCell $ cellFrom $ findFirstCellOfContour c1 $ findDivisions c1 $ fromJust $ crashMotorcycles c1 [] golden "C1-Remainder1" $ onlyOne $ remainderFrom $ findFirstCellOfContour c1 $ findDivisions c1 $ fromJust $ crashMotorcycles c1 [] @@ -81,17 +81,19 @@ goldenSpec = describe "golden tests" $ do goldens "C1-Straight_Skeleton_And_Inset" [ toGanja $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c1 [] , toGanja $ onlyOne $ contoursFrom $ insetBy 0.1 $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c1 []] goldens "C1-Straight_Skeleton_And_Insets" ([ toGanja $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c1 []] <> - (toGanja <$> (infiniteInset 0.1 $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c1 []))) + (toGanja <$> (infiniteInset 0.1 $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c1 []))) golden "C2-Cell1" $ cellFrom $ findFirstCellOfContour c2 $ findDivisions c2 $ fromMaybe (error "Got Nothing") $ crashMotorcycles c2 [] golden "C2-Cell1-NodeTree" $ fst $ getRawNodeTreeOfCell $ cellFrom $ findFirstCellOfContour c2 $ findDivisions c2 $ fromJust $ crashMotorcycles c2 [] golden "C2-Remainder1" $ onlyOne $ remainderFrom $ findFirstCellOfContour c2 $ findDivisions c2 $ fromJust $ crashMotorcycles c2 [] golden "C2-Straight_Skeleton" $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c2 [] + goldens "C2-Straight_Skeleton_And_Insets" ([ toGanja $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c2 []] <> + (toGanja <$> (infiniteInset 0.1 $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c2 []))) golden "C3-Divide" $ onlyOne $ findDivisions c3 $ fromJust $ crashMotorcycles c3 [] golden "C3-Cell1" $ cellFrom $ findFirstCellOfContour c3 $ findDivisions c3 $ fromMaybe (error "Got Nothing") $ crashMotorcycles c3 [] golden "C3-Remainder1" $ onlyOne $ remainderFrom $ findFirstCellOfContour c3 $ findDivisions c3 $ fromJust $ crashMotorcycles c3 [] golden "C3-Straight_Skeleton" $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c3 [] goldens "C3-Straight_Skeleton_And_Insets" ([ toGanja $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c3 []] <> - (toGanja <$> (infiniteInset 0.1 $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c3 []))) + (toGanja <$> (infiniteInset 0.1 $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c3 []))) golden "C4-Cell1" $ cellFrom $ findFirstCellOfContour c4 $ findDivisions c4 $ fromMaybe (error "Got Nothing") $ crashMotorcycles c4 [] golden "C4-Remainder1" $ onlyOne $ remainderFrom $ findFirstCellOfContour c4 $ findDivisions c4 $ fromJust $ crashMotorcycles c4 [] golden "C4-Cell2" $ cellFrom $ findNextCell $ onlyOne $ remainderFrom $ findFirstCellOfContour c4 $ findDivisions c4 $ fromJust $ crashMotorcycles c4 [] @@ -104,7 +106,9 @@ goldenSpec = describe "golden tests" $ do golden "C5-Cell2" $ cellFrom $ findNextCell $ onlyOne $ remainderFrom $ findFirstCellOfContour c5 $ findDivisions c5 $ fromJust $ crashMotorcycles c5 [] golden "C5-Divide" $ onlyOne $ findDivisions c5 $ fromJust $ crashMotorcycles c5 [] golden "C5-Straight_Skeleton" $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c5 [] --- golden "C5-Faces-Default" $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c5 [] + golden "C5-Faces-Default" $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c5 [] + goldens "C5-Straight_Skeleton_And_Insets" ([ toGanja $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c5 []] <> + (toGanja <$> (infiniteInset 0.1 $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c5 []))) golden "C6-Divide" $ onlyOne $ findDivisions c6 $ fromJust $ crashMotorcycles c6 [] golden "C6-Straight_Skeleton" $ fromMaybe (error "no skeleton?") $ findStraightSkeleton c6 [] -- golden "C6-Faces-Default" $ facesOf $ fromMaybe (error "got Nothing") $ findStraightSkeleton c6 [] diff --git a/tests/Math/Geometry/ConvexBisectableQuad.hs b/tests/Math/Geometry/ConvexBisectableQuad.hs index a95ce0a6a..4e3d45ddb 100644 --- a/tests/Math/Geometry/ConvexBisectableQuad.hs +++ b/tests/Math/Geometry/ConvexBisectableQuad.hs @@ -23,7 +23,7 @@ module Math.Geometry.ConvexBisectableQuad ( convexBisectableQuadSpec ) where -import Prelude (Bool, Show(show), ($), (<$>), error) +import Prelude (Bool, Show(show), (<), ($), (<$>), error) -- The Maybe library. import Data.Maybe (fromMaybe) @@ -47,7 +47,7 @@ import Graphics.Slicer.Math.Intersections (intersectionsAtSamePoint) import Graphics.Slicer.Math.PGA (outAndErrOf) -- The functions for generating random geometry, for testing purposes. -import Graphics.Slicer.Math.RandomGeometry (Radian(Radian), randomConvexBisectableQuad) +import Graphics.Slicer.Math.RandomGeometry (Radian(Radian), generationsOf, oneNodeTreeOf, randomConvexBisectableQuad) -- Our logic for dividing a contour into cells, which each get nodetrees for them, which are combined into a straight skeleton. import Graphics.Slicer.Math.Skeleton.Cells (findDivisions) @@ -58,6 +58,9 @@ import Graphics.Slicer.Math.Skeleton.Concave (eNodesOfOutsideContour) -- The portion of our library that reasons about motorcycles, emiting from the concave nodes of our contour. import Graphics.Slicer.Math.Skeleton.Motorcycles (crashMotorcycles) +-- The entry point for getting the straight skeleton of a contour. +import Graphics.Slicer.Math.Skeleton.Skeleton (findStraightSkeleton) + -- Shared tests, between different geometry. import Math.Geometry.CommonTests (prop_CanPlaceFaces, prop_ENodeArcsIntersectAtSamePoint, prop_FacesAllWoundLeft, prop_FacesHaveThreeSides, prop_FacesInOrder, prop_HasFourFaces, prop_HasAStraightSkeleton, prop_NodeTreeHasFewerThanThreeGenerations, prop_NoDivides, prop_NoMotorcycles, prop_StraightSkeletonHasOneNodeTree) @@ -85,16 +88,30 @@ unit_ConvexBisectableQuadENodeArcsIntersectAtSamePoint = retVal retVal = intersectionsAtSamePoint nodeOutsAndErrs nodeOutsAndErrs = outAndErrOf <$> eNodes eNodes = eNodesOfOutsideContour convexBisectableQuad - convexBisectableQuad = randomConvexBisectableQuad centerX centerY rawFirstTilt rawSecondTilt rawFirstDistanceToCorner rawSecondDistanceToCorner - centerX,centerY :: ℝ - centerX = -1.0 - centerY = 0.0 + convexBisectableQuad = randomConvexBisectableQuad x y rawFirstTilt rawSecondTilt rawFirstDistanceToCorner rawSecondDistanceToCorner + x,y :: ℝ + x = -1.0 + y = 0.0 rawFirstTilt = Radian 1.0 rawSecondTilt = Radian 4.1 rawFirstDistanceToCorner, rawSecondDistanceToCorner :: Positive ℝ rawFirstDistanceToCorner = 3.0 rawSecondDistanceToCorner = 1.0e-3 +-- | Causes the generation of a backwards going insideArc in sortPLinesByReferenceSafe. Error filtered out, for now. +unit_ConvexBisectableQuadNodeTreeHasFewerThanThreeGenerations :: Bool +unit_ConvexBisectableQuadNodeTreeHasFewerThanThreeGenerations = generationsOf (oneNodeTreeOf $ fromMaybe (error "no straight skeleton?") $ findStraightSkeleton convexBisectableQuad []) < 3 + where + convexBisectableQuad = randomConvexBisectableQuad x y rawFirstTilt rawSecondTilt rawFirstDistanceToCorner rawSecondDistanceToCorner + x,y :: ℝ + x = -0.0 + y = 2.0 + rawFirstTilt = Radian 0.5 + rawSecondTilt = Radian 0.48 + rawFirstDistanceToCorner, rawSecondDistanceToCorner :: Positive ℝ + rawFirstDistanceToCorner = 20.0 + rawSecondDistanceToCorner = 6.0e-2 + -- | Tests that are expected to fail. convexBisectableQuadBrokenSpec :: Spec convexBisectableQuadBrokenSpec = @@ -118,6 +135,8 @@ convexBisectableQuadSpec = do property (expectationFromConvexBisectableQuad prop_StraightSkeletonHasOneNodeTree) it "generates fewer than three generations of INodes" $ property (boolFromConvexBisectableQuad prop_NodeTreeHasFewerThanThreeGenerations) + it "generates fewer than three generations of INodes (unit)" $ + unit_ConvexBisectableQuadNodeTreeHasFewerThanThreeGenerations it "finds that all of the outArcs of the ENodes intersect at the same point" $ property (boolFromConvexBisectableQuad prop_ENodeArcsIntersectAtSamePoint) it "can place faces on the straight skeleton" $ diff --git a/tests/Math/Geometry/Square.hs b/tests/Math/Geometry/Square.hs index ddf91761d..513fb34dc 100644 --- a/tests/Math/Geometry/Square.hs +++ b/tests/Math/Geometry/Square.hs @@ -23,7 +23,7 @@ module Math.Geometry.Square ( squareSpec ) where -import Prelude (Bool(True), Show(show), ($), (/), (<>), (<$>), error, length, otherwise) +import Prelude (Bool(True), Show(show), (<), ($), (/), (<>), (<$>), error, length, otherwise) -- The List library. import Data.List (head) @@ -57,7 +57,7 @@ import Graphics.Slicer.Math.Intersections (intersectionsAtSamePoint) import Graphics.Slicer.Math.PGA (outAndErrOf) -- The functions for generating random geometry, for testing purposes. -import Graphics.Slicer.Math.RandomGeometry (Radian(Radian), randomSquare) +import Graphics.Slicer.Math.RandomGeometry (Radian(Radian), generationsOf, oneNodeTreeOf, randomSquare) -- The logic for creating straight skeletons from concave contours. import Graphics.Slicer.Math.Skeleton.Concave (eNodesOfOutsideContour) @@ -170,6 +170,18 @@ unit_SquareFacesInsetWithoutRemainder = (length insetContours, length remainingF distanceToCorner :: Positive ℝ distanceToCorner = Positive 2.0e-3 +-- | Failed to find a reference when sorting PLines. Fixed. +unit_SquareFacesFewerThanThreeGenerations :: Bool +unit_SquareFacesFewerThanThreeGenerations = generationsOf (oneNodeTreeOf $ fromMaybe (error "no straight skeleton?") $ findStraightSkeleton square []) < 3 + where + square = randomSquare x y tilt distanceToCorner + x,y :: ℝ + x = 0.2 + y = 0.0 + tilt = Radian 1.5 + distanceToCorner :: Positive ℝ + distanceToCorner = Positive 1.0 + squareBrokenSpec :: Spec squareBrokenSpec = do describe "Squares" $ @@ -189,6 +201,8 @@ squareSpec = do property (expectationFromSquare prop_StraightSkeletonHasOneNodeTree) it "has fewer than three generations of INodes in the NodeTree" $ property (boolFromSquare prop_NodeTreeHasFewerThanThreeGenerations) + it "has fewer than three generations of INodes in the NodeTree (unit)" $ + unit_SquareFacesFewerThanThreeGenerations it "finds that all of the outArcs of the ENodes intersect at the same point" $ property (boolFromSquare prop_ENodeArcsIntersectAtSamePoint) it "can place faces on the straight skeleton" $ diff --git a/tests/Math/PGA.hs b/tests/Math/PGA.hs index 44c8bdd56..98e3737b1 100644 --- a/tests/Math/PGA.hs +++ b/tests/Math/PGA.hs @@ -80,7 +80,7 @@ import Graphics.Slicer.Machine.Infill (InfillType(Horiz, Vert), makeInfill) -- Our Facet library. import Graphics.Slicer.Math.Arcs (towardIntersection) import Graphics.Slicer.Math.Skeleton.Concave (averageNodes, makeENode, makeENodes) -import Graphics.Slicer.Math.Skeleton.Definitions (INode(INode), Motorcycle(Motorcycle), getFirstLineSeg, getLastLineSeg, sortPLinesByReference) +import Graphics.Slicer.Math.Skeleton.Definitions (INode(INode), Motorcycle(Motorcycle), getFirstLineSeg, getLastLineSeg, sortPLinesByReference, sortPLinesByReferenceSafe) import Graphics.Slicer.Math.Skeleton.Motorcycles (convexMotorcycles, crashMotorcycles) import Graphics.Slicer.Math.Skeleton.Skeleton (findStraightSkeleton) @@ -1765,6 +1765,46 @@ facetSpec = do it "flips a contour (unit)" unit_ContourFlip1 describe "Sorting (Skeleton)" $ do + it "sorts PLines safely (normal ID)" $ + sortPLinesByReferenceSafe pl1 [pl3, pl2] --> [pl3, pl2] + it "sorts PLines safely (normal 1)" $ + sortPLinesByReferenceSafe pl1 [pl2, pl3] --> [pl3, pl2] + it "sorts PLines safely (normal 2)" $ + sortPLinesByReferenceSafe pl3 [pl2, pl1] --> [pl2, pl1] + it "sorts PLines safely (normal 3)" $ + sortPLinesByReferenceSafe pl2 [pl1, pl3] --> [pl1, pl3] + it "sorts PLines safely (anticolinear ID)" $ + sortPLinesByReferenceSafe pl1 [pl4, pl2] --> [pl4, pl2] + it "sorts PLines safely (anticolinear 1)" $ + sortPLinesByReferenceSafe pl1 [pl2, pl4] --> [pl4, pl2] + it "sorts PLines safely (anticolinear 2)" $ + sortPLinesByReferenceSafe pl4 [pl1, pl2] --> [pl2, pl1] + it "sorts PLines safely (anticolinear 3)" $ + sortPLinesByReferenceSafe pl2 [pl4, pl1] --> [pl1, pl4] + it "sorts PLines safely (anticolinear 4)" $ + sortPLinesByReferenceSafe pl1 [pl2, pl4, pl3] --> [pl3, pl4, pl2] + it "sorts PLines safely (anticolinear 4A)" $ + sortPLinesByReferenceSafe pl1 [pl4, pl3, pl2] --> [pl3, pl4, pl2] + it "sorts PLines safely (anticolinear 4B)" $ + sortPLinesByReferenceSafe pl1 [pl3, pl2, pl4] --> [pl3, pl4, pl2] + it "sorts PLines safely (anticolinear 4C)" $ + sortPLinesByReferenceSafe pl1 [pl3, pl4, pl2] --> [pl3, pl4, pl2] + it "sorts PLines safely (anticolinear 4D)" $ + sortPLinesByReferenceSafe pl1 [pl4, pl2, pl3] --> [pl3, pl4, pl2] + it "sorts PLines safely (anticolinear 4E)" $ + sortPLinesByReferenceSafe pl1 [pl2, pl3, pl4] --> [pl3, pl4, pl2] + it "sorts PLines safely (anticolinear 5)" $ + sortPLinesByReferenceSafe pl3 [pl1, pl2, pl4] --> [pl4, pl2, pl1] + it "sorts PLines safely (anticolinear 5A)" $ + sortPLinesByReferenceSafe pl3 [pl2, pl4, pl1] --> [pl4, pl2, pl1] + it "sorts PLines safely (anticolinear 5B)" $ + sortPLinesByReferenceSafe pl3 [pl4, pl1, pl2] --> [pl4, pl2, pl1] + it "sorts PLines safely (anticolinear 6)" $ + sortPLinesByReferenceSafe pl4 [pl3, pl1, pl2] --> [pl2, pl1, pl3] + it "sorts PLines safely (anticolinear 7)" $ + sortPLinesByReferenceSafe pl2 [pl4, pl3, pl1] --> [pl1, pl3, pl4] + it "sorts PLines safely (rectangle 1)" $ + sortPLinesByReferenceSafe pl7 [pl6, pl5] --> [pl5, pl6] it "sorts PLines (normal ID)" $ sortPLinesByReference pl1 [pl3, pl2] --> [pl3, pl2] it "sorts PLines (normal 1)" $ @@ -1803,6 +1843,8 @@ facetSpec = do sortPLinesByReference pl4 [pl3, pl1, pl2] --> [pl2, pl1, pl3] it "sorts PLines (anticolinear 7)" $ sortPLinesByReference pl2 [pl4, pl3, pl1] --> [pl1, pl3, pl4] + it "sorts PLines (rectangle 1)" $ + sortPLinesByReference pl7 [pl6, pl5] --> [pl5, pl6] where c1 = makePointContour [Point2 (-1,-1), Point2 (0,0), Point2 (1,-1), Point2 (1,1), Point2 (-1,1)] -- The next corners are part of a 2x2 square around the origin with a piece missing: (c2 from above) @@ -1834,3 +1876,6 @@ facetSpec = do pl3 = eToPL $ makeLineSeg (Point2 (-3,-3)) (Point2 (0,0)) -- a line to the origin, from the negative Y direction pl4 = eToPL $ makeLineSeg (Point2 (0,-4)) (Point2 (0,0)) + pl5 = eToPL $ makeLineSeg (Point2 (1,0.5)) (Point2 (0.5,0)) + pl6 = eToPL $ makeLineSeg (Point2 (1,-0.5)) (Point2 (0.5,0)) + pl7 = eToPL $ makeLineSeg (Point2 (0.5,0)) (Point2 (-0.5,0)) diff --git a/tests/golden/C0-NodeTree.ganja.js b/tests/golden/C0-NodeTree.ganja.js index e88feeb28..971da7d33 100644 --- a/tests/golden/C0-NodeTree.ganja.js +++ b/tests/golden/C0-NodeTree.ganja.js @@ -17,9 +17,9 @@ Algebra(2,0,1,()=>{ var aga = 0.3826834323650897e1-0.9238795325112867e2-0.541196100146197e0; var agb = 0.7071067811865475e1+0.7071067811865475e2+0.0e0; var agc = 0.9238795325112868e1-0.3826834323650897e2-0.5411961001461972e0; - var aha = 0.9238795325112868e1-0.3826834323650897e2-0.5411961001461972e0; + var aha = -0.9238795325112868e1-0.3826834323650897e2+0.5411961001461972e0; var ahb = 0.0e1-1.0e2+0.0e0; - var ahc = -0.9238795325112868e1-0.3826834323650897e2+0.5411961001461972e0; + var ahc = 0.9238795325112868e1-0.3826834323650897e2-0.5411961001461972e0; document.body.appendChild(this.graph([ 0x882288, [aaa,aab], diff --git a/tests/golden/C0-Straight_Skeleton.ganja.js b/tests/golden/C0-Straight_Skeleton.ganja.js index e88feeb28..971da7d33 100644 --- a/tests/golden/C0-Straight_Skeleton.ganja.js +++ b/tests/golden/C0-Straight_Skeleton.ganja.js @@ -17,9 +17,9 @@ Algebra(2,0,1,()=>{ var aga = 0.3826834323650897e1-0.9238795325112867e2-0.541196100146197e0; var agb = 0.7071067811865475e1+0.7071067811865475e2+0.0e0; var agc = 0.9238795325112868e1-0.3826834323650897e2-0.5411961001461972e0; - var aha = 0.9238795325112868e1-0.3826834323650897e2-0.5411961001461972e0; + var aha = -0.9238795325112868e1-0.3826834323650897e2+0.5411961001461972e0; var ahb = 0.0e1-1.0e2+0.0e0; - var ahc = -0.9238795325112868e1-0.3826834323650897e2+0.5411961001461972e0; + var ahc = 0.9238795325112868e1-0.3826834323650897e2-0.5411961001461972e0; document.body.appendChild(this.graph([ 0x882288, [aaa,aab], diff --git a/tests/golden/C0-Straight_Skeleton_And_Four_Insets.ganja.js b/tests/golden/C0-Straight_Skeleton_And_Four_Insets.ganja.js index b94dc1eb8..fab47e2f2 100644 --- a/tests/golden/C0-Straight_Skeleton_And_Four_Insets.ganja.js +++ b/tests/golden/C0-Straight_Skeleton_And_Four_Insets.ganja.js @@ -17,9 +17,9 @@ Algebra(2,0,1,()=>{ var aga = 0.3826834323650897e1-0.9238795325112867e2-0.541196100146197e0; var agb = 0.7071067811865475e1+0.7071067811865475e2+0.0e0; var agc = 0.9238795325112868e1-0.3826834323650897e2-0.5411961001461972e0; - var aha = 0.9238795325112868e1-0.3826834323650897e2-0.5411961001461972e0; + var aha = -0.9238795325112868e1-0.3826834323650897e2+0.5411961001461972e0; var ahb = 0.0e1-1.0e2+0.0e0; - var ahc = -0.9238795325112868e1-0.3826834323650897e2+0.5411961001461972e0; + var ahc = 0.9238795325112868e1-0.3826834323650897e2-0.5411961001461972e0; var ba = point(0.14142135623730953,0.0); var bb = point(-0.7585786437626906,-0.9); var bc = point(0.9,-0.9); diff --git a/tests/golden/C0-Straight_Skeleton_And_Inset.ganja.js b/tests/golden/C0-Straight_Skeleton_And_Inset.ganja.js index 6498a960a..ad8f2922d 100644 --- a/tests/golden/C0-Straight_Skeleton_And_Inset.ganja.js +++ b/tests/golden/C0-Straight_Skeleton_And_Inset.ganja.js @@ -17,9 +17,9 @@ Algebra(2,0,1,()=>{ var aga = 0.3826834323650897e1-0.9238795325112867e2-0.541196100146197e0; var agb = 0.7071067811865475e1+0.7071067811865475e2+0.0e0; var agc = 0.9238795325112868e1-0.3826834323650897e2-0.5411961001461972e0; - var aha = 0.9238795325112868e1-0.3826834323650897e2-0.5411961001461972e0; + var aha = -0.9238795325112868e1-0.3826834323650897e2+0.5411961001461972e0; var ahb = 0.0e1-1.0e2+0.0e0; - var ahc = -0.9238795325112868e1-0.3826834323650897e2+0.5411961001461972e0; + var ahc = 0.9238795325112868e1-0.3826834323650897e2-0.5411961001461972e0; var ba = point(0.14142135623730953,0.0); var bb = point(-0.7585786437626906,-0.9); var bc = point(0.9,-0.9); diff --git a/tests/golden/C0-Straight_Skeleton_And_Insets.ganja.js b/tests/golden/C0-Straight_Skeleton_And_Insets.ganja.js index e9a2aaf21..ae98baf7a 100644 --- a/tests/golden/C0-Straight_Skeleton_And_Insets.ganja.js +++ b/tests/golden/C0-Straight_Skeleton_And_Insets.ganja.js @@ -17,9 +17,9 @@ Algebra(2,0,1,()=>{ var aga = 0.3826834323650897e1-0.9238795325112867e2-0.541196100146197e0; var agb = 0.7071067811865475e1+0.7071067811865475e2+0.0e0; var agc = 0.9238795325112868e1-0.3826834323650897e2-0.5411961001461972e0; - var aha = 0.9238795325112868e1-0.3826834323650897e2-0.5411961001461972e0; + var aha = -0.9238795325112868e1-0.3826834323650897e2+0.5411961001461972e0; var ahb = 0.0e1-1.0e2+0.0e0; - var ahc = -0.9238795325112868e1-0.3826834323650897e2+0.5411961001461972e0; + var ahc = 0.9238795325112868e1-0.3826834323650897e2-0.5411961001461972e0; var ba = point(0.14142135623730953,0.0); var bb = point(-0.7585786437626906,-0.9); var bc = point(0.9,-0.9); diff --git a/tests/golden/C1-Straight_Skeleton.ganja.js b/tests/golden/C1-Straight_Skeleton.ganja.js index c56f3bea8..0a438c7e0 100644 --- a/tests/golden/C1-Straight_Skeleton.ganja.js +++ b/tests/golden/C1-Straight_Skeleton.ganja.js @@ -17,9 +17,9 @@ Algebra(2,0,1,()=>{ var aga = 0.9238795325112867e1+0.3826834323650897e2-0.541196100146197e0; var agb = -0.7071067811865475e1+0.7071067811865475e2+0.0e0; var agc = 0.3826834323650897e1+0.9238795325112868e2-0.5411961001461972e0; - var aha = 0.3826834323650897e1+0.9238795325112868e2-0.5411961001461972e0; + var aha = 0.3826834323650897e1-0.9238795325112868e2+0.5411961001461972e0; var ahb = 1.0e1+0.0e2+0.0e0; - var ahc = 0.3826834323650897e1-0.9238795325112868e2+0.5411961001461972e0; + var ahc = 0.3826834323650897e1+0.9238795325112868e2-0.5411961001461972e0; document.body.appendChild(this.graph([ 0x882288, [aaa,aab], diff --git a/tests/golden/C1-Straight_Skeleton_And_Inset.ganja.js b/tests/golden/C1-Straight_Skeleton_And_Inset.ganja.js index c47a80db4..ee723d0bd 100644 --- a/tests/golden/C1-Straight_Skeleton_And_Inset.ganja.js +++ b/tests/golden/C1-Straight_Skeleton_And_Inset.ganja.js @@ -17,9 +17,9 @@ Algebra(2,0,1,()=>{ var aga = 0.9238795325112867e1+0.3826834323650897e2-0.541196100146197e0; var agb = -0.7071067811865475e1+0.7071067811865475e2+0.0e0; var agc = 0.3826834323650897e1+0.9238795325112868e2-0.5411961001461972e0; - var aha = 0.3826834323650897e1+0.9238795325112868e2-0.5411961001461972e0; + var aha = 0.3826834323650897e1-0.9238795325112868e2+0.5411961001461972e0; var ahb = 1.0e1+0.0e2+0.0e0; - var ahc = 0.3826834323650897e1-0.9238795325112868e2+0.5411961001461972e0; + var ahc = 0.3826834323650897e1+0.9238795325112868e2-0.5411961001461972e0; var ba = point(-0.0,0.14142135623730953); var bb = point(0.9,-0.7585786437626906); var bc = point(0.9,0.9); diff --git a/tests/golden/C1-Straight_Skeleton_And_Insets.ganja.js b/tests/golden/C1-Straight_Skeleton_And_Insets.ganja.js index 9367a57c2..2b791da64 100644 --- a/tests/golden/C1-Straight_Skeleton_And_Insets.ganja.js +++ b/tests/golden/C1-Straight_Skeleton_And_Insets.ganja.js @@ -17,9 +17,9 @@ Algebra(2,0,1,()=>{ var aga = 0.9238795325112867e1+0.3826834323650897e2-0.541196100146197e0; var agb = -0.7071067811865475e1+0.7071067811865475e2+0.0e0; var agc = 0.3826834323650897e1+0.9238795325112868e2-0.5411961001461972e0; - var aha = 0.3826834323650897e1+0.9238795325112868e2-0.5411961001461972e0; + var aha = 0.3826834323650897e1-0.9238795325112868e2+0.5411961001461972e0; var ahb = 1.0e1+0.0e2+0.0e0; - var ahc = 0.3826834323650897e1-0.9238795325112868e2+0.5411961001461972e0; + var ahc = 0.3826834323650897e1+0.9238795325112868e2-0.5411961001461972e0; var ba = point(-0.0,0.14142135623730953); var bb = point(0.9,-0.7585786437626906); var bc = point(0.9,0.9); diff --git a/tests/golden/C2-Straight_Skeleton.ganja.js b/tests/golden/C2-Straight_Skeleton.ganja.js index b323056ec..c1e7b2735 100644 --- a/tests/golden/C2-Straight_Skeleton.ganja.js +++ b/tests/golden/C2-Straight_Skeleton.ganja.js @@ -17,9 +17,9 @@ Algebra(2,0,1,()=>{ var aga = -0.3826834323650897e1+0.9238795325112867e2-0.541196100146197e0; var agb = -0.7071067811865475e1-0.7071067811865475e2+0.0e0; var agc = -0.9238795325112868e1+0.3826834323650897e2-0.5411961001461972e0; - var aha = -0.9238795325112868e1+0.3826834323650897e2-0.5411961001461972e0; + var aha = 0.9238795325112868e1+0.3826834323650897e2+0.5411961001461972e0; var ahb = 0.0e1+1.0e2+0.0e0; - var ahc = 0.9238795325112868e1+0.3826834323650897e2+0.5411961001461972e0; + var ahc = -0.9238795325112868e1+0.3826834323650897e2-0.5411961001461972e0; document.body.appendChild(this.graph([ 0x882288, [aaa,aab], diff --git a/tests/golden/C2-Straight_Skeleton_And_Insets.ganja.js b/tests/golden/C2-Straight_Skeleton_And_Insets.ganja.js new file mode 100644 index 000000000..24191cf8b --- /dev/null +++ b/tests/golden/C2-Straight_Skeleton_And_Insets.ganja.js @@ -0,0 +1,156 @@ +Algebra(2,0,1,()=>{ + var line = (a,b,c)=>a*1e1 + b*1e2 + c*1e0; + var point = (x,y)=>!(1e0 + x*1e1 + y*1e2); + var aaa = point(-1.0,-1.0); + var aab = point(1.0,-1.0); + var aba = point(1.0,-1.0); + var abb = point(0.0,0.0); + var aca = point(0.0,0.0); + var acb = point(1.0,1.0); + var ada = point(1.0,1.0); + var adb = point(-1.0,1.0); + var aea = point(-1.0,1.0); + var aeb = point(-1.0,-1.0); + var afa = 0.7071067811865475e1-0.7071067811865475e2+0.0e0; + var afb = 0.3826834323650897e1+0.9238795325112867e2+0.541196100146197e0; + var afc = 0.9238795325112868e1+0.3826834323650897e2+0.5411961001461972e0; + var aga = -0.3826834323650897e1+0.9238795325112867e2-0.541196100146197e0; + var agb = -0.7071067811865475e1-0.7071067811865475e2+0.0e0; + var agc = -0.9238795325112868e1+0.3826834323650897e2-0.5411961001461972e0; + var aha = 0.9238795325112868e1+0.3826834323650897e2+0.5411961001461972e0; + var ahb = 0.0e1+1.0e2+0.0e0; + var ahc = -0.9238795325112868e1+0.3826834323650897e2-0.5411961001461972e0; + var ba = point(-0.14142135623730953,0.0); + var bb = point(0.7585786437626906,0.9); + var bc = point(-0.9,0.9); + var bd = point(-0.9,-0.9); + var be = point(0.7585786437626906,-0.9); + var ca = point(-0.28284271247461906,0.0); + var cb = point(0.517157287525381,0.8); + var cc = point(-0.8,0.8); + var cd = point(-0.8,-0.8); + var ce = point(0.517157287525381,-0.8); + var da = point(-0.4242640687119286,0.0); + var db = point(0.27573593128807133,0.7); + var dc = point(-0.7,0.7); + var dd = point(-0.7,-0.7); + var de = point(0.27573593128807133,-0.7); + var ea = point(-0.5656854249492381,0.0); + var eb = point(0.03431457505076187,0.6); + var ec = point(-0.6,0.6); + var ed = point(-0.6,-0.6); + var ee = point(0.03431457505076187,-0.6); + var fa = point(-0.5,0.20710678118654763); + var fb = point(-0.20710678118654763,0.5); + var fc = point(-0.5,0.5); + var ga = point(-0.5,-0.20710678118654763); + var gb = point(-0.5,-0.5); + var gc = point(-0.20710678118654763,-0.5); + document.body.appendChild(this.graph([ + 0x882288, + [aaa,aab], + 0x00AA88, + aaa, "aaa", + aab, "aab", + 0x882288, + [aba,abb], + 0x00AA88, + aba, "aba", + abb, "abb", + 0x882288, + [aca,acb], + 0x00AA88, + aca, "aca", + acb, "acb", + 0x882288, + [ada,adb], + 0x00AA88, + ada, "ada", + adb, "adb", + 0x882288, + [aea,aeb], + 0x00AA88, + aea, "aea", + aeb, "aeb", + afa, "afa", + afb, "afb", + afc, "afc", + aga, "aga", + agb, "agb", + agc, "agc", + aha, "aha", + ahb, "ahb", + ahc, "ahc", + 0x882288, + [ba,bb], + [bb,bc], + [bc,bd], + [bd,be], + [be,ba], + 0x00AA88, + ba, "ba", + bb, "bb", + bc, "bc", + bd, "bd", + be, "be", + 0x882288, + [ca,cb], + [cb,cc], + [cc,cd], + [cd,ce], + [ce,ca], + 0x00AA88, + ca, "ca", + cb, "cb", + cc, "cc", + cd, "cd", + ce, "ce", + 0x882288, + [da,db], + [db,dc], + [dc,dd], + [dd,de], + [de,da], + 0x00AA88, + da, "da", + db, "db", + dc, "dc", + dd, "dd", + de, "de", + 0x882288, + [ea,eb], + [eb,ec], + [ec,ed], + [ed,ee], + [ee,ea], + 0x00AA88, + ea, "ea", + eb, "eb", + ec, "ec", + ed, "ed", + ee, "ee", + 0x882288, + [fa,fb], + [fb,fc], + [fc,fa], + 0x00AA88, + fa, "fa", + fb, "fb", + fc, "fc", + 0x882288, + [ga,gb], + [gb,gc], + [gc,ga], + 0x00AA88, + ga, "ga", + gb, "gb", + gc, "gc", + ],{ + grid: true, + labels: true, + lineWidth: 3, + pointRadius: 1, + fontSize: 1, + scale: 1, +})); +}); diff --git a/tests/golden/C5-Faces-Default.ganja.js b/tests/golden/C5-Faces-Default.ganja.js new file mode 100644 index 000000000..2919c1899 --- /dev/null +++ b/tests/golden/C5-Faces-Default.ganja.js @@ -0,0 +1,87 @@ +Algebra(2,0,1,()=>{ + var line = (a,b,c)=>a*1e1 + b*1e2 + c*1e0; + var point = (x,y)=>!(1e0 + x*1e1 + y*1e2); + var aaa = point(1.0,1.0); + var aab = point(-1.0,1.0); + var aba = point(-1.0,1.0); + var abb = point(0.0,0.0); + var aca = point(0.0,0.0); + var acb = point(-1.0,-1.0); + var ada = point(-1.0,-1.0); + var adb = point(1.0,-1.0); + var aea = point(1.0,-1.0); + var aeb = point(2.0,0.0); + var afa = point(2.0,0.0); + var afb = point(1.0,1.0); + var ag = -0.3826834323650897e1-0.9238795325112867e2+0.541196100146197e0; + var ah = 0.9238795325112867e1-0.3826834323650899e2-0.5411961001461969e0; + var ai = 0.0e1-1.0e2+0.0e0; + var aj = -0.7071067811865476e1-0.7071067811865476e2+0.7071067811865476e0; + var ak = 0.3826834323650897e1+0.9238795325112867e2-0.541196100146197e0; + var al = 0.3826834323650897e1-0.9238795325112867e2-0.541196100146197e0; + var am = 0.7071067811865476e1-0.7071067811865476e2-0.7071067811865476e0; + var an = 0.0e1+1.0e2+0.0e0; + var ao = 0.9238795325112867e1+0.3826834323650899e2-0.5411961001461969e0; + var ap = -0.3826834323650897e1+0.9238795325112867e2+0.541196100146197e0; + var aq = 0.0e1+1.0e2+0.0e0; + var ar = -0.7071067811865476e1+0.7071067811865476e2+0.7071067811865476e0; + var as = -0.9238795325112867e1-0.3826834323650899e2+0.5411961001461969e0; + var at = -0.9238795325112867e1+0.3826834323650899e2+0.5411961001461969e0; + var au = 0.7071067811865476e1+0.7071067811865476e2-0.7071067811865476e0; + var av = 0.0e1-1.0e2+0.0e0; + document.body.appendChild(this.graph([ + 0x882288, + [aaa,aab], + 0x00AA88, + aaa, "aaa", + aab, "aab", + 0x882288, + [aba,abb], + 0x00AA88, + aba, "aba", + abb, "abb", + 0x882288, + [aca,acb], + 0x00AA88, + aca, "aca", + acb, "acb", + 0x882288, + [ada,adb], + 0x00AA88, + ada, "ada", + adb, "adb", + 0x882288, + [aea,aeb], + 0x00AA88, + aea, "aea", + aeb, "aeb", + 0x882288, + [afa,afb], + 0x00AA88, + afa, "afa", + afb, "afb", + ag, "ag", + ah, "ah", + ai, "ai", + aj, "aj", + ak, "ak", + al, "al", + am, "am", + an, "an", + ao, "ao", + ap, "ap", + aq, "aq", + ar, "ar", + as, "as", + at, "at", + au, "au", + av, "av", + ],{ + grid: true, + labels: true, + lineWidth: 3, + pointRadius: 1, + fontSize: 1, + scale: 1, +})); +}); diff --git a/tests/golden/C5-Straight_Skeleton_And_Insets.ganja.js b/tests/golden/C5-Straight_Skeleton_And_Insets.ganja.js new file mode 100644 index 000000000..080e5ed74 --- /dev/null +++ b/tests/golden/C5-Straight_Skeleton_And_Insets.ganja.js @@ -0,0 +1,215 @@ +Algebra(2,0,1,()=>{ + var line = (a,b,c)=>a*1e1 + b*1e2 + c*1e0; + var point = (x,y)=>!(1e0 + x*1e1 + y*1e2); + var aaa = point(0.0,0.0); + var aab = point(-1.0,-1.0); + var aba = point(-1.0,-1.0); + var abb = point(1.0,-1.0); + var aca = point(1.0,-1.0); + var acb = point(2.0,0.0); + var ada = point(2.0,0.0); + var adb = point(1.0,1.0); + var aea = point(1.0,1.0); + var aeb = point(-1.0,1.0); + var afa = point(-1.0,1.0); + var afb = point(0.0,0.0); + var aga = 0.3826834323650897e1-0.9238795325112867e2-0.541196100146197e0; + var agb = 0.9238795325112867e1+0.3826834323650899e2-0.5411961001461969e0; + var agc = 0.7071067811865476e1-0.7071067811865476e2-0.7071067811865476e0; + var aha = -0.9238795325112867e1+0.3826834323650899e2+0.5411961001461969e0; + var ahb = -0.3826834323650897e1-0.9238795325112867e2+0.541196100146197e0; + var ahc = 0.7071067811865476e1+0.7071067811865476e2-0.7071067811865476e0; + var aia = 0.0e1+1.0e2+0.0e0; + var aib = 0.7071067811865476e1+0.7071067811865476e2-0.7071067811865476e0; + var aic = 0.0e1-1.0e2+0.0e0; + var aid = 0.7071067811865476e1-0.7071067811865476e2-0.7071067811865476e0; + var ba = point(-0.7585786437626906,0.9); + var bb = point(0.14142135623730953,0.0); + var bc = point(-0.7585786437626906,-0.9); + var bd = point(0.9585786437626905,-0.9); + var be = point(1.8585786437626908,0.0); + var bf = point(0.9585786437626905,0.9); + var ca = point(-0.517157287525381,0.8); + var cb = point(0.28284271247461906,0.0); + var cc = point(-0.517157287525381,-0.8); + var cd = point(0.9171572875253811,-0.8); + var ce = point(1.717157287525381,0.0); + var cf = point(0.9171572875253811,0.8); + var da = point(-0.27573593128807133,0.7); + var db = point(0.4242640687119286,0.0); + var dc = point(-0.27573593128807133,-0.7); + var dd = point(0.8757359312880715,-0.7); + var de = point(1.5757359312880714,0.0); + var df = point(0.8757359312880715,0.7); + var ea = point(-0.03431457505076187,0.6); + var eb = point(0.5656854249492381,0.0); + var ec = point(-0.03431457505076187,-0.6); + var ed = point(0.834314575050762,-0.6); + var ee = point(1.4343145750507618,0.0); + var ef = point(0.834314575050762,0.6); + var fa = point(0.2071067811865476,0.5); + var fb = point(0.7071067811865476,0.0); + var fc = point(0.2071067811865476,-0.5); + var fd = point(0.7928932188134524,-0.5); + var fe = point(1.2928932188134525,0.0); + var ff = point(0.7928932188134524,0.5); + var ga = point(0.44852813742385733,0.39999999999999986); + var gb = point(0.8485281374238572,0.0); + var gc = point(0.44852813742385733,-0.39999999999999986); + var gd = point(0.751471862576143,-0.3999999999999999); + var ge = point(1.1514718625761429,0.0); + var gf = point(0.751471862576143,0.3999999999999999); + var ha = point(0.6899494936611668,0.29999999999999993); + var hb = point(0.9899494936611667,0.0); + var hc = point(0.6899494936611668,-0.29999999999999993); + var hd = point(0.7100505063388334,-0.29999999999999993); + var he = point(1.0100505063388332,0.0); + var hf = point(0.7100505063388334,0.29999999999999993); + document.body.appendChild(this.graph([ + 0x882288, + [aaa,aab], + 0x00AA88, + aaa, "aaa", + aab, "aab", + 0x882288, + [aba,abb], + 0x00AA88, + aba, "aba", + abb, "abb", + 0x882288, + [aca,acb], + 0x00AA88, + aca, "aca", + acb, "acb", + 0x882288, + [ada,adb], + 0x00AA88, + ada, "ada", + adb, "adb", + 0x882288, + [aea,aeb], + 0x00AA88, + aea, "aea", + aeb, "aeb", + 0x882288, + [afa,afb], + 0x00AA88, + afa, "afa", + afb, "afb", + aga, "aga", + agb, "agb", + agc, "agc", + aha, "aha", + ahb, "ahb", + ahc, "ahc", + aia, "aia", + aib, "aib", + aic, "aic", + aid, "aid", + 0x882288, + [ba,bb], + [bb,bc], + [bc,bd], + [bd,be], + [be,bf], + [bf,ba], + 0x00AA88, + ba, "ba", + bb, "bb", + bc, "bc", + bd, "bd", + be, "be", + bf, "bf", + 0x882288, + [ca,cb], + [cb,cc], + [cc,cd], + [cd,ce], + [ce,cf], + [cf,ca], + 0x00AA88, + ca, "ca", + cb, "cb", + cc, "cc", + cd, "cd", + ce, "ce", + cf, "cf", + 0x882288, + [da,db], + [db,dc], + [dc,dd], + [dd,de], + [de,df], + [df,da], + 0x00AA88, + da, "da", + db, "db", + dc, "dc", + dd, "dd", + de, "de", + df, "df", + 0x882288, + [ea,eb], + [eb,ec], + [ec,ed], + [ed,ee], + [ee,ef], + [ef,ea], + 0x00AA88, + ea, "ea", + eb, "eb", + ec, "ec", + ed, "ed", + ee, "ee", + ef, "ef", + 0x882288, + [fa,fb], + [fb,fc], + [fc,fd], + [fd,fe], + [fe,ff], + [ff,fa], + 0x00AA88, + fa, "fa", + fb, "fb", + fc, "fc", + fd, "fd", + fe, "fe", + ff, "ff", + 0x882288, + [ga,gb], + [gb,gc], + [gc,gd], + [gd,ge], + [ge,gf], + [gf,ga], + 0x00AA88, + ga, "ga", + gb, "gb", + gc, "gc", + gd, "gd", + ge, "ge", + gf, "gf", + 0x882288, + [ha,hb], + [hb,hc], + [hc,hd], + [hd,he], + [he,hf], + [hf,ha], + 0x00AA88, + ha, "ha", + hb, "hb", + hc, "hc", + hd, "hd", + he, "he", + hf, "hf", + ],{ + grid: true, + labels: true, + lineWidth: 3, + pointRadius: 1, + fontSize: 1, + scale: 1, +})); +}); diff --git a/tests/golden/C6-Straight_Skeleton.ganja.js b/tests/golden/C6-Straight_Skeleton.ganja.js index fde61feef..289314963 100644 --- a/tests/golden/C6-Straight_Skeleton.ganja.js +++ b/tests/golden/C6-Straight_Skeleton.ganja.js @@ -27,9 +27,9 @@ Algebra(2,0,1,()=>{ var aka = 0.9932897335288758e1+0.11565251949756605e2-0.606432399999752e0; var akb = -0.7071067811865475e1+0.7071067811865475e2+0.0e0; var akc = 0.5257311121191336e1+0.8506508083520399e2-0.5877852522924731e0; - var ala = 0.5257311121191336e1+0.8506508083520399e2-0.5877852522924731e0; + var ala = 0.5257311121191336e1-0.8506508083520399e2+0.5877852522924731e0; var alb = 1.0e1+0.0e2+0.0e0; - var alc = 0.5257311121191336e1-0.8506508083520399e2+0.5877852522924731e0; + var alc = 0.5257311121191336e1+0.8506508083520399e2-0.5877852522924731e0; document.body.appendChild(this.graph([ 0x882288, [aaa,aab], diff --git a/tests/golden/C7-Straight_Skeleton.ganja.js b/tests/golden/C7-Straight_Skeleton.ganja.js index 0e4c325c0..277c3b1c9 100644 --- a/tests/golden/C7-Straight_Skeleton.ganja.js +++ b/tests/golden/C7-Straight_Skeleton.ganja.js @@ -37,9 +37,9 @@ Algebra(2,0,1,()=>{ var aoa = -0.5257311121191337e1-0.8506508083520399e2-0.3249196962329061e0; var aob = 0.7071067811865475e1-0.7071067811865475e2-0.7071067811865475e0; var aoc = 0.9732489894677302e1+0.22975292054736116e2-0.22975292054736116e0; - var apa = 0.9732489894677302e1+0.22975292054736116e2-0.22975292054736116e0; + var apa = -0.5257311121191335e1-0.85065080835204e2+0.26286555605956674e0; var apb = 0.7071067811865475e1-0.7071067811865475e2+0.0e0; - var apc = -0.5257311121191335e1-0.85065080835204e2+0.26286555605956674e0; + var apc = 0.9732489894677302e1+0.22975292054736116e2-0.22975292054736116e0; document.body.appendChild(this.graph([ 0x882288, [aaa,aab],