Source code for svcco.branch_addition.triangle

import numpy as np
import numba as nb
from scipy import interpolate

[docs]def get_local_points(data,vessel,terminal,num,isclamped): proximal = data[vessel,0:3] distal = data[vessel,3:6] direction = distal - proximal direction = direction/np.linalg.norm(direction) #length = np.linalg.norm(direction) if np.all(vessel == 0) and isclamped: length = data[vessel,20] #print(length*np.linspace(0,1,num)) shift = direction.reshape(-1,1)*length*np.linspace(0,1,num) points = proximal.reshape(1,-1) + shift.T else: line = np.linspace(0,1,num) s,t = np.meshgrid(line,line) s = s.flatten().reshape(-1,1) t = t.flatten().reshape(-1,1) points = proximal.reshape(1,-1)*(1-t)*s + \ distal.reshape(1,-1)*(t*s)+\ terminal.reshape(1,-1)*(1-s) #print('SHAPE: {}'.format(points.shape)) return points
""" @nb.jit(nopython=True,cache=True) def angle_constraint(p0,p1,p2,constraint,greater): tmp = [] for i in range(p0.shape[0]): vector_1 = p1 - p0[i] vector_2 = p2 - p0[i] vector_1 = vector_1 / np.linalg.norm(vector_1) vector_2 = vector_2 / np.linalg.norm(vector_2) if greater: if np.dot(vector_1,vector_2) > constraint: tmp.append(p0[i]) else: if np.dot(vector_1,vector_2) < constraint: tmp.append(p0[i]) return tmp """
[docs]def angle_constraint(p0,p1,p2,constraint,greater): vector_1 = p1 - p0 vector_2 = p2 - p0 vector_1 = vector_1 / np.linalg.norm(vector_1,axis=1).reshape(-1,1) vector_2 = vector_2 / np.linalg.norm(vector_2,axis=1).reshape(-1,1) angle = np.array([np.dot(vector_1[i],vector_2[i]) for i in range(len(vector_1))]) if greater: p0 = p0[angle>constraint,:] else: p0 = p0[angle<constraint,:] return p0
[docs]@nb.jit(nopython=True,cache=True) def relative_length_constraint(p0,p1,p2,p3,ratio): d_max = min([np.linalg.norm(p1-p2), np.linalg.norm(p1-p3), np.linalg.norm(p2-p3)])*ratio tmp = [] for i in range(p0.shape[0]): if not np.linalg.norm(p1-p0[i])>d_max: continue if not np.linalg.norm(p2-p0[i])>d_max: continue if not np.linalg.norm(p3-p0[i])>d_max: continue tmp.append(p0[i]) #p0 = np.array(tmp) #p0 = p0[np.linalg.norm(p1-p0,axis=1)>d_max] #p0 = p0[np.linalg.norm(p2-p0,axis=1)>d_max] #p0 = p0[np.linalg.norm(p3-p0,axis=1)>d_max] return tmp
[docs]def boundary_constraint(p0,boundary,patches): points = [] for idx in range(p0.shape[0]): if boundary.within(p0[idx,0],p0[idx,1],p0[idx,2],patches): points.append(p0[idx,:]) return np.array(points)
[docs]def absolute_length_constraint(): pass
""" class triangle: def __init__(self,level,ct,p0,p1,p2,p0_val,p1_val,degree=2,nodes=None,target=None): self.degree = degree if np.all(nodes) is not None: self.nodes = nodes self.targets = np.ones(self.nodes.shape[0])*target else: self.nodes,self.targets = self.sample(level,ct,degree,p0,p1,p2,p0_val,p1_val) def sample(self,level,ct,degree,p0,p1,p2,p0_val,p1_val): if degree == 1: nodes = [] pts = np.array([p0,p1,p2]) #for pt in pts: # nodes.append(level(*pt,ct).x) nodes = pts elif degree == 2: nodes = [] pts = np.array([p0,(p0+p1)/2,(p0+p2)/2,p1,(p1+p2)/2,p2]) tar = np.array([p0_val,(p0_val+p1_val)/2,(p0_val+ct)/2,p1_val,(p1_val+ct)/2,ct]) for idx,pt in enumerate(pts): if idx == 0 or idx==3 or idx == 5: nodes.append(pt) else: nodes.append(level(pt[0],pt[1],pt[2],tar[idx]).x) elif degree == 3: nodes = [] pts = np.array([p0,(2*p0+p1)/3,(2*p0+p2)/3,(p0+2*p1)/3,(p0+p1+p2)/3,(p0+2*p2)/3,p1,(2*p1+p2)/3,(p1+2*p2)/3,p2]) tar = np.array([p0_val,(2*p0_val+p1_val)/3,(2*p0_val+ct)/3,(p0_val+2*p1_val)/3,(p0_val+p1_val+ct)/3,(p0_val+2*ct)/3,p1_val,(2*p1_val+ct)/3,(p1_val+2*ct)/3,ct]) for idx,pt in enumerate(pts): if idx == 0 or idx == 6 or idx == 9: nodes.append(pt) else: nodes.append(level(*pt,tar[idx]).x) nodes = np.array(nodes) return nodes,tar def cubic(self,s,t,u): coef = np.array([t**3,3*s*t**2,3*u*t**2,3*s**2*t,6*s*t*u, 3*t*u**2,s**3,3*s**2*u,3*s*u**2,u**3]) #point = np.sum(coef*self.nodes,axis=0) point = coef[0,:].reshape(-1,1)*self.nodes[0,:].reshape(1,-1) +\ coef[1,:].reshape(-1,1)*self.nodes[1,:].reshape(1,-1) +\ coef[2,:].reshape(-1,1)*self.nodes[2,:].reshape(1,-1) +\ coef[3,:].reshape(-1,1)*self.nodes[3,:].reshape(1,-1) +\ coef[4,:].reshape(-1,1)*self.nodes[4,:].reshape(1,-1) +\ coef[5,:].reshape(-1,1)*self.nodes[5,:].reshape(1,-1) +\ coef[6,:].reshape(-1,1)*self.nodes[6,:].reshape(1,-1) +\ coef[7,:].reshape(-1,1)*self.nodes[7,:].reshape(1,-1) +\ coef[8,:].reshape(-1,1)*self.nodes[8,:].reshape(1,-1) +\ coef[9,:].reshape(-1,1)*self.nodes[9,:].reshape(1,-1) target = coef[0,:].reshape(-1,1)*self.targets[0].reshape(1,-1) +\ coef[1,:].reshape(-1,1)*self.targets[1].reshape(1,-1) +\ coef[2,:].reshape(-1,1)*self.targets[2].reshape(1,-1) +\ coef[3,:].reshape(-1,1)*self.targets[3].reshape(1,-1) +\ coef[4,:].reshape(-1,1)*self.targets[4].reshape(1,-1) +\ coef[5,:].reshape(-1,1)*self.targets[5].reshape(1,-1) +\ coef[6,:].reshape(-1,1)*self.targets[6].reshape(1,-1) +\ coef[7,:].reshape(-1,1)*self.targets[7].reshape(1,-1) +\ coef[8,:].reshape(-1,1)*self.targets[8].reshape(1,-1) +\ coef[9,:].reshape(-1,1)*self.targets[9].reshape(1,-1) return point,target def quart(self,s,t,u): coef = np.array([t**2,2*s*t,2*t*u,s**2,2*s*u,u**2]) #point = np.sum(coef*self.nodes,axis=0) point = coef[0,:].reshape(-1,1)*self.nodes[0,:].reshape(1,-1) +\ coef[1,:].reshape(-1,1)*self.nodes[1,:].reshape(1,-1) +\ coef[2,:].reshape(-1,1)*self.nodes[2,:].reshape(1,-1) +\ coef[3,:].reshape(-1,1)*self.nodes[3,:].reshape(1,-1) +\ coef[4,:].reshape(-1,1)*self.nodes[4,:].reshape(1,-1) +\ coef[5,:].reshape(-1,1)*self.nodes[5,:].reshape(1,-1) target = coef[0,:].reshape(-1,1)*self.targets[0].reshape(1,-1) +\ coef[1,:].reshape(-1,1)*self.targets[1].reshape(1,-1) +\ coef[2,:].reshape(-1,1)*self.targets[2].reshape(1,-1) +\ coef[3,:].reshape(-1,1)*self.targets[3].reshape(1,-1) +\ coef[4,:].reshape(-1,1)*self.targets[4].reshape(1,-1) +\ coef[5,:].reshape(-1,1)*self.targets[5].reshape(1,-1) return point,target def linear(self,s,t,u): coef = np.array([t,s,u]) #point = np.sum(coef*self.nodes,axis=0) point = coef[0,:].reshape(-1,1)*self.nodes[0,:].reshape(1,-1) +\ coef[1,:].reshape(-1,1)*self.nodes[1,:].reshape(1,-1) +\ coef[2,:].reshape(-1,1)*self.nodes[2,:].reshape(1,-1) target = coef[0,:].reshape(-1,1)*self.targets[0].reshape(1,-1) +\ coef[1,:].reshape(-1,1)*self.targets[1].reshape(1,-1) +\ coef[2,:].reshape(-1,1)*self.targets[2].reshape(1,-1) return point,target def generate(self,n=10): s = np.ones((n,n))*np.array([np.flip(np.linspace(0,1,num=n))]).T t = np.linspace(0,1-np.linspace(0,1,num=n),num=n) u = np.ones((n,n)) - s - t s = s[1:].flatten() t = t[1:].flatten() u = u[1:].flatten() if self.degree == 1: points,targets = self.linear(s,t,u) elif self.degree == 2: points,targets = self.quart(s,t,u) elif self.degree == 3: points,targets = self.cubic(s,t,u) else: points = None targets = None return points,targets,(s,t,u) def get_jit(self): if self.degree == 3: @nb.jit(nopython=True,cache=True) def cubic(s,t,u,nodes=self.nodes): coef = np.array([t**3,3*s*t**2,3*u*t**2,3*s**2*t,6*s*t*u, 3*t*u**2,s**3,3*s**2*u,3*s*u**2,u**3]) point = coef[0,:].reshape(-1,1)*nodes[0,:].reshape(1,-1) +\ coef[1,:].reshape(-1,1)*nodes[1,:].reshape(1,-1) +\ coef[2,:].reshape(-1,1)*nodes[2,:].reshape(1,-1) +\ coef[3,:].reshape(-1,1)*nodes[3,:].reshape(1,-1) +\ coef[4,:].reshape(-1,1)*nodes[4,:].reshape(1,-1) +\ coef[5,:].reshape(-1,1)*nodes[5,:].reshape(1,-1) +\ coef[6,:].reshape(-1,1)*nodes[6,:].reshape(1,-1) +\ coef[7,:].reshape(-1,1)*nodes[7,:].reshape(1,-1) +\ coef[8,:].reshape(-1,1)*nodes[8,:].reshape(1,-1) +\ coef[9,:].reshape(-1,1)*nodes[9,:].reshape(1,-1) return point return cubic class b_tri: def __init__(self,points): #Check for the correct number of control points degree = (-3+(9-4*(2-2*points.shape[0]))**(1/2))/2 degree_int = round(degree) self.points = points if np.isclose(degree,degree_int,0.0001): self.degree = degree_int else: print('Incorrect number of control points') if degree > 6: print('Number of control points greater than degrees.') def sample(self,n=10): s = np.ones((n,n))*np.array([np.flip(np.linspace(0,1,num=n))]).T t = np.linspace(0,1-np.linspace(0,1,num=n),num=n) u = np.ones((n,n)) - s - t s = s[1:].flatten() t = t[1:].flatten() u = u[1:].flatten() if self.degree == 1: coef = np.array([t,s,u]).T samples = [] for i in range(coef.shape[0]): tmp = np.sum(self.points*coef[i,:],axis=0) samples.append(tmp) elif self.degree == 2: coef = np.array([t**2,2*s*t,2*t*u,s**2,2*s*u,u**2]).T samples = [] for i in range(coef.shape[0]): tmp = np.sum(self.points*coef[i,:],axis=0) samples.append(tmp) elif self.degree == 3: coef = np.array([t**3,3*s*t**2,3*u*t**2,3*s**2*t,6*s*t*u, 3*t*u**2,s**3,3*s**2*u,3*s*u**2,u**3]).T samples = [] for i in range(coef.shape[0]): tmp = np.sum(self.points*coef[i,:],axis=0) samples.append(tmp) elif self.degree == 4: coef = np.array([t**4,4*s*t**3,4*u*t**3,6*t**2*s**2,12*t**2*u,6*t**2*u**2, 4*t*s**3,12*t*s**2*u,12*t*s*u**2,s**4,4*s**3*u,6*s**2*u**2, 4*s*u**3,u**4]).T samples = [] for i in range(coef.shape[0]): tmp = np.sum(self.points*coef[i,:],axis=0) samples.append(tmp) samples = np.array(samples) return samples """