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
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.