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