def fullflattriareas(surfacemesh): ptsP = [P3(*p) for p in surfacemesh["pts"]] fptsP = [P2(*p) for p in surfacemesh["fpts"]] tris = surfacemesh["tris"] def P2Cross(a, b): return a.u * b.v - b.u * a.v triareas = [] ftriareas = [] cornerangs = [] fcornerangs = [] for tri in tris: p0, p1, p2 = ptsP[tri[0]], ptsP[tri[1]], ptsP[tri[2]] parea = 0.5 * P3.Cross(p1 - p0, p2 - p0).Len() triareas.append(parea) cornerangs.append(P3.Cross(P3.ZNorm(p1 - p0), P3.ZNorm(p2 - p0)).Len()) f0, f1, f2 = fptsP[tri[0]], fptsP[tri[1]], fptsP[tri[2]] farea = 0.5 * abs(P2Cross(f1 - f0, f2 - f0)) ftriareas.append(farea) fcornerangs.append(abs(P2Cross(P2.ZNorm(f1 - f0), P2.ZNorm(f2 - f0)))) surfacemesh["triareas"] = numpy.array(triareas) surfacemesh["ftriareas"] = numpy.array(ftriareas) surfacemesh["cornerangs"] = numpy.array(cornerangs) surfacemesh["fcornerangs"] = numpy.array(fcornerangs)
def __init__(self, nodeback, nodefore): self.nodeback = nodeback self.nodefore = nodefore self.barforeright = None self.barbackleft = None self.bbardeleted = False assert nodefore.i > nodeback.i self.nodemid = None # used to specify a contour cut or a voronoi polygon boundary cut self.midcontournumber = -1 # will be set to -2 to denote connecting to out of tolerance/unchecked tolerance trailing contour segment self.cellmarkright = None self.cellmarkleft = None self.barvecN = P3.ZNorm( self.nodefore.p - self.nodeback.p ) # used to detect colinearity as it's preserved on splitting
def calccellcuttangency( self ): # could be checked before splitting on the lines to give an option of picking a less tangential position assert not self.leadsplitbartop.bbardeleted and not self.leadsplitbarbot.bbardeleted node1, bar1, node2, bar2 = self.splitnodetop, self.leadsplitbartop, self.splitnodebot, self.leadsplitbarbot bar1a = bar1.GetForeRightBL(bar1.nodefore == node1) bar2a = bar2.GetForeRightBL(bar2.nodefore == node2) vtopbot = P3.ZNorm(self.splitnodebot.p - self.splitnodetop.p) db1 = -node1.cperpbardotN(bar1, vtopbot) db1a = node1.cperpbardotN(bar1a, vtopbot) db2 = node2.cperpbardotN(bar2, vtopbot) db2a = -node2.cperpbardotN(bar2a, vtopbot) res = min(db1, db1a, db2, db2a) assert res > -0.0001 return res
def DistLamPtrianglePZ(self, p0, p1, p2): # solve vd = lv + vp * lam - v1 * lam1 - v2 * lam2, where |vd| = r and vd.v1 = vd.v2 = 0 # solve +-r = (lv + vp * lam) . vnorm = lv . vnorm + vp . vnorm lam v1 = p1 - p0 v2 = p2 - p0 vcross = P3.Cross(v1, v2) assert abs(P3.Dot(vcross, v1)) < 0.001 assert abs(P3.Dot(vcross, v2)) < 0.001 vnorm = P3.ZNorm(vcross) lv = self.p - p0 lvdvnorm = P3.Dot(lv, vnorm) vpdvnorm = P3.Dot(self.vp, vnorm) if vpdvnorm == 0.0: return # lam = (+-r - lvdvnorm)/vpdvnorm if vpdvnorm > 0.0: lam = (-self.r - lvdvnorm) / vpdvnorm else: lam = (self.r - lvdvnorm) / vpdvnorm if lam < 0 or lam > self.lam: return lvl = lv + self.vp * lam v1dlv = P3.Dot(v1, lvl) v2dlv = P3.Dot(v2, lvl) v1sq = v1.Lensq() v2sq = v2.Lensq() v1dv2 = P3.Dot(v1, v2) det = v1sq * v2sq - v1dv2**2 if det == 0.0: return # no face size invdet = 1.0 / det # solve vd = lv - v1 * lam1 - v2 * lam2, where vd.v1 = vd.v2 = 0 # (v1sq v1dv2) ( lam1 ) ( v1dlv ) # (v1dv2 v2sq) . ( lam2 ) = ( v2dlv ) lam1 = (v2sq * v1dlv - v1dv2 * v2dlv) * invdet lam2 = (-v1dv2 * v1dlv + v1sq * v2dlv) * invdet if 0 < lam1 and 0 < lam2 and lam1 + lam2 < 1: vd = lvl - v1 * lam1 - v2 * lam2 assert abs(P3.Dot(vd, v1)) < 0.001 assert abs(P3.Dot(vd, v2)) < 0.001 assert abs(vd.Len() - self.r) < 0.001 self.lam = lam