wblut/HE_Mesh

Straight Skeleton

Closed this issue · 2 comments

Dear @wblut,

I just found out about the straightskeleton external package and, despite all my efforts, can't seem to manage how to output the Straight Skeleton of a polygon. Would you mind providing a simple example ?

Here is my attempt so far:

#Jython2.7
add_library('hemesh')

from wblut.external.straightskeleton import * 

verts = [PVector(208, 131),PVector(213, 142),PVector(168, 141),PVector(260, 168),PVector(246, 149),PVector(277, 142),
        PVector(271, 163),PVector(302, 180),PVector(268, 173),PVector(305, 196),PVector(319, 225),PVector(367, 214),
        PVector(423, 169),PVector(471, 160),PVector(540, 208),PVector(588, 268),PVector(616, 270),PVector(644, 308),
        PVector(630, 446),PVector(647, 472),PVector(641, 459),PVector(656, 467),PVector(660, 450),PVector(646, 423),
        PVector(687, 447),PVector(666, 495),PVector(651, 495),PVector(711, 580),PVector(728, 584),PVector(714, 557),
        PVector(746, 560),PVector(735, 569),PVector(744, 617),PVector(769, 594),PVector(753, 624),PVector(771, 628),
        PVector(793, 700),PVector(842, 708),PVector(871, 759),PVector(902, 780),PVector(891, 788),PVector(871, 773),
        PVector(887, 799),PVector(947, 774),PVector(964, 782),PVector(978, 689),PVector(985, 678),PVector(990, 695),
        PVector(984, 555),PVector(868, 338),PVector(854, 294),PVector(869, 316),PVector(887, 314),PVector(892, 366),
        PVector(895, 322),PVector(805, 196),PVector(747, 61),PVector(759, 59),PVector(753, 43),PVector(691, 33),
        PVector(683, 98),PVector(661, 72),PVector(355, 83),PVector(333, 46),PVector(35, 70),PVector(70, 144),
        PVector(50, 165),PVector(77, 154),PVector(87, 125),PVector(99, 139),PVector(106, 118),PVector(122, 139),
        PVector(89, 152),PVector(169, 124)]


def setup():
    size(1360, 840, P2D)
    background("#FFFFFF")
    strokeWeight(4)
    fill(0)
    
    # number of vertices
    N = len(verts)
    
    # corner
    corners = [Corner(p.x, p.y) for p in verts]
    
    # edges
    edges = Loop()
    for i in xrange(N):
        edges.append(Edge(corners[i], corners[(i+1)%N]))
    
    # speeds
    speeds = []
    for i in xrange(N):        
        pv = verts[(i-1)%N] #prev vertex
        cv = verts[i] #current vertex
        nv = verts[(i+1)%N] #next vertex
        s = speed(pv, cv, nv)
        speeds.append(s)
        
    # apply speed to edges
    for i, e in enumerate(edges):
        e.machine = Machine(speeds[i])

        
    out = LoopL()
    out.add(edges)

    skel = Skeleton(out, True)
    skel.skeleton()
    faces = skel.output.faces.values()
    

    faceList = []

    for face in faces:
        temp = []
        for ptgroup in face.points:
            for i, p in enumerate(ptgroup):
                temp.append(p)
        faceList.append(temp)
        
        
                
    strokeWeight(1.3)
    for face in faceList:
        for p1, p2 in zip(face, face[1:] + face[:1]):
            line(p1.x, p1.y, p2.x, p2.y)

    for i, p in enumerate(verts):
        text(i, p.x, p.y)
    
    noLoop()
    
    

    
        
def speed(pv, cv, nv):
    
    '''Returns a float.
       Computes the speed of a vertex given both its previous and next neighbors'''
            
    vec1 = PVector.sub(cv, pv).normalize()
    vec2 = PVector.sub(nv, cv).normalize()

    a = angle(vec1, vec2)
    s = 1 / sin(a*.5) #speed  
    
    return s

 
def angle(vec1, vec2):
    
    '''Returns a float.
       Computes the angle between 2 vectors'''
    
    a = PI - PVector.angleBetween(vec1, vec2) 
        
    if vec1.cross(vec2).z > 0:
        a = TWO_PI - a
        
    return a

Also please tell me if my other question about plane fitting is poorly-worded and I will do my best to reformulate it.

Your help is very valuable to me.

Respectfully

wblut commented

Hi solub,

I missed this question. The external library is this one: https://github.com/twak/campskeleton/

In HE_Mesh, it's only used in the generic pyramid factory: https://github.com/wblut/HE_Mesh/blob/master/src/factory/wblut/geom/WB_PyramidFactory.java

The function createPyramidWithAngle is probably the best one to examine.

Hope this helps,

F.

Thank you very much for your help!

I ended-up using setPoints() combined with createOffset() (with a large random offset value) instead of createPyramidWithAngle(). Works like a charm.