예제 #1
0
def xispline(pts, ams, eps=0.05, angle_on_straigth=True):
    """
    Calcola i punti base di una linea spline con spigoli che
    approssima i punti passati in pts, inserendo un punto spigolo quando
    l'angolo tra due segmenti è maggiore di ams, fino a raggiungere
    precisione eps. Restituisce la lista dei punti e base e una lista con gli
    indici relativi ai punti spigolo.
    """
    # Semplifica la linea in input (questo toglie anche i punti doppi)
    pts = geo2d.simplify(pts, eps/2)
    # Calcola gli indici dei punti spigolo interni
    sp = geo2d.getAnglePointsIndexes(pts, ams, angle_on_straigth)
    # Calcola il risultato finale
    res = [pts[0]]
    fsp = []
    for i in xrange(0, len(sp)-1):
        s = geo2d.ispline(geo2d.Path(pts[sp[i]:sp[i+1]+1]))
        res.extend(s[1:])
        fsp.append(len(res)-1) # Salva l'indice (in res!!) del punto spigolo

    del fsp[-1] # Elimina l'ultimo indice di spigolo

    auto_closed = geo2d.same(res[0], res[-1])

    # Se il primo e l'ultimo punto sono uguali, cancello l'ultimo
    if auto_closed:
        del res[-1]
        fsp.insert(0,0) # In questo caso l'inizio e' sempre punto spigolo

    return res, fsp, auto_closed
예제 #2
0
 def testReversed(self):
     tprev = self.tp.reversed()
     expected = [P(0, 2), P(0, 1), P(0, 0)]
     for p in expected:
         self.assert_(geo2d.same(p, tprev.path(expected.index(p))))
     self.assertAlmostEqual(tprev.t0, 0.8)
     self.assertAlmostEqual(tprev.t1, 1.5)
예제 #3
0
def offset(pts, d, tipo="SPIGOLO_VIVO", soglia_unibili=1.0):

    # Semplifica la linea in input (questo toglie anche i punti doppi)
    pts = geo2d.simplify(pts, soglia_unibili/50.0)

    if max(abs(dd) for dd in d) < soglia_unibili*0.6:
        # Caso speciale per offset a distanza piccolissima:
        #   calcola il risultato considerando semplicemente lo
        #   spostamento punto a punto lungo la bisettrice delle
        #   normali dei segmenti incidenti. La distanza usata
        #   viene modificata per evitare di "tagliare le curve".
        #   Il risultato finale e' una parallela a "spigolo vivo"
        #   corretta a meno delle auto-intersezioni e/o saltelli.

        # In realtà esiste un caso in cui a questo punto ci sono ancora
        # dei punti doppi consecutivi, ovvero quello in cui siamo
        # rimasti con due punti coincidenti.  In questo caso non è
        # chiaro cosa sia l'offset, per cui torniamo il path di partenza
        # come fa anche la offset di geo2dcpp
        if len(pts) < 3 and geo2d.same(pts[0], pts[1]):
            return [geo2d.Path(pts)]

        chiusa = abs(pts[0] - pts[-1]) < 0.0001

        res = []
        pts = geo2d.Path(pts)

        # Gli utilizzatori attuali della offset si aspettano che le curve
        # chiuse vengano sempre espanse verso l'esterno con offset positivo
        # e verso l'interno con offset negativo; ora, il lato scelto dalla
        # funzione offset dipende dal verso della curva, ma visto che non
        # vogliamo modificarlo solo per mantenere questa invariante, per
        # ottenere lo stesso risultato inverte il segno dell'offset richiesto.
        s = 1.0
        if chiusa and geo2d.sarea(pts) > 0:
            s = -1.0

        for dd in d:
            dd *= s

            off = []

            for i in xrange(0, len(pts)):
                ddir = geo2d.nd(pts, i, dd, chiusa)
                off.append(pts[i] + ddir)

            res.append(geo2d.Path(off))
    else:
        tipi = dict(SPIGOLO_VIVO=0, SMUSSATA=1)
        res = geo2d.offsetf(pts, d, tipi[tipo], soglia_unibili)

    return res
예제 #4
0
 def assertGeo2dSame(self, p1, p2, prec=1e-3):
     self.assertTrue(geo2d.same(p1, p2, prec), "%r != %r" % (p1, p2))
예제 #5
0
 def assertGeo2dNotSame(self, p1, p2, prec=1e-6):
     self.assertFalse(geo2d.same(p1, p2, prec), "%r == %r" % (p1, p2))
예제 #6
0
 def testPt(self):
     self.assert_(geo2d.same(self.tp.p0, P(0, 0.5)))
     self.assert_(geo2d.same(self.tp.p1, P(0, 1.2)))