예제 #1
0
class Bubble:
    @staticmethod
    def getDir(key):  # key is pair of Bubbles
        return Vector2(key[0].ring.pos, key[1].ring.pos).unit()

    @staticmethod
    def getArc(key):  # key is pair of Bubbles
        a, b = key[0].ring, key[1].ring
        return math.asin(1.0 * b.r / (a.r + b.r))

    dirs = None  # Cache
    arcs = None

    def __init__(self):

        # Group Topology
        self.parent = None  # Noke  # not Bubble: for Group.buildGeometry()
        self.childs = []  # Nokes
        self.upper = False  # Upper level - first child

        self.group = None  # Parent Group of Bubble

        # Geometry and Correction
        self.ring = Ring((0, 0), 1)

        # For building Geometry
        self.tight = 0  # Left (Parents) and right (Childs) Tights
        self.corr = 0  # Correction of Radius
        self.angles = {}  # dict {Bubble:angle}

        # Eating
        self.fading = None  # Fading object

    def __repr__(self):
        return 'Bubble: %s' % self.ring

    def neighbor(self, n):
        "Returns previous or next neighbor (or parent if not); n = -1 or 1"
        if self.parent:
            nokes = self.parent().childs + [self.parent]
            bubbles = map(Noke.get, nokes)
            return nokes[bubbles.index(self) + n]

    def neighbors(self):
        "Iterates all neighbor Nokes"
        if self.childs:
            for n in self.childs:
                yield n

        if self.parent:
            yield self.parent
            for n in (-1, 1):
                neighbor = self.neighbor(n)
                if neighbor != self.parent:
                    yield neighbor

    #def strongParents( self ):
    #    "Skips first Parent if Bubble is not on upper level"
    #    return  self.parents[ self.upper^1 :]

    def lightCopy(self):
        "Copies main attributes of Bubble"
        bubble = Bubble()
        bubble.group = self.group
        bubble.ring = self.ring.copy()
        bubble.fading = self.fading
        return bubble

    def markUpperChilds(self, mark):

        self.upper = mark

        if self.childs:
            upper = self.childs[0]
            for c in self.childs:
                c().markUpperChilds(c == upper)

    def detTights(self):
        def arc(noke):
            return Bubble.arcs[(self, noke())]

        if self.parent:
            self.tight += arc(self.neighbor(-1))
            self.tight += arc(self.neighbor(1))
        if self.childs:
            self.tight += arc(self.childs[0])
            self.tight += arc(self.childs[-1])

        if not self.upper:

            a = self.parent()  # Bubbles: Parent
            c = self.neighbor(-1)()  #          Prev Neighbor

            ra = c.ring.r + self.ring.r  # Radiuses
            rb = a.ring.r + c.ring.r
            rc = a.ring.r + self.ring.r
            # Cosines
            ca = 1.0 * (rb**2 + rc**2 - ra**2) / (2 * rb * rc)
            cc = 1.0 * (ra**2 + rb**2 - rc**2) / (2 * ra * rb)

            aa = math.acos(ca)  # Angles
            ac = math.acos(cc)
            ab = math.pi - (aa + ac)

            a.tight += aa  # Increase Tights
            c.tight += ac
            self.tight += ab

            # Save angle aa for detPosition()
            a.angles[self] = aa

    def detCorrections(self):
        "Dets Correction values. Returns False if Correction is not needed."

        if not (self.parent or self.childs):  # Skip single Bubbles
            return False

        minChink = math.pi * 0.2  # ?? maybe to Constants

        # Set tight as chink
        self.tight = math.pi * 2 - self.tight
        self.tight /= 2

        if self.tight < minChink:  # Correction needed

            self.corr += 2
            for n in self.neighbors():
                n(
                ).corr -= 0.2  # ?? Here may be wrong values, and some Figures may be unbuildable

            return True

        return False  # Correction is not needed

    def correct(self):
        "Corrects Radius of Ring."
        if self.corr:
            self.ring.r *= math.exp(self.corr * 0.06)

    def detPosition(self):
        "Dets Position of Bubble. Calculates initial values of Chinks."

        if self.upper:

            if not self.parent:  # Root of Group
                self.ring.pos = Vector2((0, 0))
                return

            else:
                parent = self.parent()  # Parent Bubble

                if not parent.parent:
                    dir = Vector2((1, 0))  # Default direction

                else:
                    parent1 = parent.neighbor(-1)()
                    a = parent.tight + Bubble.arcs[
                        (parent, self)] + Bubble.arcs[(parent,
                                                       parent1)] - math.pi
                    dir = Bubble.dirs[(parent1, parent)]
                    dir = dir.rotate(Vector2(angle=-a))  # Det direction

        else:
            parent = self.parent()
            prev = self.neighbor(-1)()
            a = parent.angles[self]
            dir = Bubble.dirs[(parent, prev)]
            dir = dir.rotate(Vector2(angle=-a))  # Det direction

        Bubble.dirs[(parent, self)] = dir

        self.ring.pos = parent.ring.pos + dir * (parent.ring.r + self.ring.r)

    def transform(self):
        """
        Returns transformation Matrix of Bubble,
        includes transformation Matrix of Group if is.
        """

        # Default transformation is Unit
        # (Variable or Lambda inside another Lambda)
        matrix = TransformMatrix()
        matrix.unit()

        # Group reference may not exist
        # (Variable or Lambda inside fading Let-Bound Variable ??)
        if self.group:
            matrix *= self.group.transformMatrix

        if self.ring:
            matrix *= TransformMatrix(ring=self.ring)

        return matrix
예제 #2
0
class Bubble:


    @staticmethod
    def getDir( key ):      # key is pair of Bubbles
        return Vector2( key[0].ring.pos, key[1].ring.pos ).unit()
    
    @staticmethod
    def getArc( key ):      # key is pair of Bubbles
        a,b = key[0].ring, key[1].ring
        return math.asin( 1.0 * b.r / (a.r + b.r) )



    dirs = None     # Cache
    arcs = None

    

    def __init__( self ):

        # Group Topology
        self.parent = None     # Noke  # not Bubble: for Group.buildGeometry()
        self.childs = []       # Nokes
        self.upper  = False    # Upper level - first child

        self.group  = None     # Parent Group of Bubble

        # Geometry and Correction
        self.ring   = Ring((0,0),1)
        
        # For building Geometry
        self.tight  = 0         # Left (Parents) and right (Childs) Tights
        self.corr   = 0         # Correction of Radius
        self.angles = {}        # dict {Bubble:angle}

        
        # Eating
        self.fading = None      # Fading object


    def __repr__( self ):
        return 'Bubble: %s' % self.ring


    def neighbor( self, n ):
        "Returns previous or next neighbor (or parent if not); n = -1 or 1"
        if self.parent:
            nokes = self.parent().childs + [self.parent]
            bubbles = map( Noke.get, nokes )
            return nokes[ bubbles.index( self ) + n ]

    def neighbors( self ):
        "Iterates all neighbor Nokes"
        if self.childs:
            for n in self.childs:
                yield n
        
        if self.parent:
            yield self.parent
            for n in (-1,1):
                neighbor = self.neighbor( n )
                if neighbor != self.parent:
                    yield neighbor


    #def strongParents( self ):
    #    "Skips first Parent if Bubble is not on upper level"
    #    return  self.parents[ self.upper^1 :]


    def lightCopy( self ):
        "Copies main attributes of Bubble"
        bubble = Bubble()
        bubble.group  = self.group
        bubble.ring   = self.ring.copy()
        bubble.fading = self.fading
        return bubble
        
    def markUpperChilds( self, mark ):
        
        self.upper = mark
        
        if self.childs:
            upper = self.childs[0]
            for c in self.childs:
                c().markUpperChilds( c == upper )
            

            

    def detTights( self ):
        
        def arc( noke ):
            return Bubble.arcs[ ( self,noke() ) ]

            
        if self.parent:
            self.tight += arc( self.neighbor(-1) )
            self.tight += arc( self.neighbor( 1) )
        if self.childs:
            self.tight += arc( self.childs[ 0] )
            self.tight += arc( self.childs[-1] )
        
        
        if not self.upper:

            a = self.parent()                   # Bubbles: Parent
            c = self.neighbor(-1)()             #          Prev Neighbor

            ra = c.ring.r + self.ring.r         # Radiuses
            rb = a.ring.r + c.ring.r
            rc = a.ring.r + self.ring.r
                                                # Cosines
            ca = 1.0 * ( rb**2 + rc**2 - ra**2 ) / ( 2 * rb * rc )
            cc = 1.0 * ( ra**2 + rb**2 - rc**2 ) / ( 2 * ra * rb )
            
            aa = math.acos( ca )                # Angles
            ac = math.acos( cc )
            ab = math.pi - (aa + ac)
            
            a   .tight += aa                    # Increase Tights
            c   .tight += ac
            self.tight += ab
        
            # Save angle aa for detPosition()
            a.angles[ self ] = aa
            

            
    def detCorrections( self ):
        "Dets Correction values. Returns False if Correction is not needed."

        if not ( self.parent or self.childs ):  # Skip single Bubbles
            return False


        minChink = math.pi * 0.2        # ?? maybe to Constants
        
        # Set tight as chink
        self.tight = math.pi*2 - self.tight
        self.tight /= 2
            

            
        if self.tight < minChink:       # Correction needed
        
            self.corr += 2
            for n in self.neighbors():
                n().corr -= 0.2         # ?? Here may be wrong values, and some Figures may be unbuildable
            
            return True
        
        return False                    # Correction is not needed
            
            
    def correct( self ):
        "Corrects Radius of Ring."
        if self.corr:
            self.ring.r *= math.exp( self.corr * 0.06 )

            
    def detPosition( self ):
        "Dets Position of Bubble. Calculates initial values of Chinks."
        
        if self.upper:
            
            if not self.parent:             # Root of Group
                self.ring.pos = Vector2((0,0))
                return
            
            else:
                parent = self.parent()      # Parent Bubble
                
                if not parent.parent:
                    dir = Vector2((1,0))    # Default direction
                
                else:
                    parent1 = parent.neighbor( -1 )()
                    a = parent.tight + Bubble.arcs[(parent,self)] + Bubble.arcs[(parent,parent1)] - math.pi
                    dir = Bubble.dirs[(parent1,parent)]
                    dir = dir.rotate( Vector2( angle= -a ) )     # Det direction

        else:
            parent = self.parent()
            prev   = self.neighbor(-1)()
            a = parent.angles[ self ]
            dir = Bubble.dirs[(parent,prev)]
            dir = dir.rotate( Vector2( angle= -a ) )             # Det direction

            
        Bubble.dirs[(parent,self)] = dir
        
        self.ring.pos = parent.ring.pos + dir * (parent.ring.r + self.ring.r)
          


    def transform( self ):
        """
        Returns transformation Matrix of Bubble,
        includes transformation Matrix of Group if is.
        """
        
        # Default transformation is Unit 
        # (Variable or Lambda inside another Lambda)
        matrix = TransformMatrix()
        matrix.unit()
        
        # Group reference may not exist 
        # (Variable or Lambda inside fading Let-Bound Variable ??)
        if self.group:
            matrix *= self.group.transformMatrix

        if self.ring:
            matrix *= TransformMatrix( ring= self.ring )

        return  matrix