def quad_qual(coords): vec = np.array([coords[i] - coords[i - 1] for i in range(len(coords))]) a = np.array([angle(vec[i], vec[(i - 1)]) for i in range(len(vec))]) length = np.array([np.linalg.norm([v]) for v in vec]) qual = 1 - np.sum([ np.abs(a - np.pi / 2) / (np.pi / 2) + np.abs(length - np.mean(length)) / np.mean(length) ]) / 8 return qual
def directionality_error(nodes, polygon): angles = [] for i in range(len(nodes)): #edge as vector v1 = nodes[i - 1] - nodes[i] #get vector of two closest boundary points to each node v2 = nearest_points(polygon,Point(nodes[i][0], nodes[i][1]))[0] -\ nearest_points(polygon,Point(nodes[i-1][0], nodes[i-1][1]))[0] angles.append((angle(v1, v2) % (0.5 * np.pi))) return 1 - (np.mean(angles) / (0.5 * np.pi))
def geometric_irregularity(nodes, mode="std-angle"): if mode == "std-edges": dist = [ np.sqrt((nodes[i - 1][0] - nodes[i][0])**2 + (nodes[i - 1][1] - nodes[i][1])**2) for i in range(len(nodes)) ] result = 1 - np.std(dist) / np.mean(dist) if mode == "std-angle": angles = [] for i in range(len(nodes)): # edge as vector v1 = nodes[i - 1] - nodes[i] v2 = nodes[i] - nodes[(i + 1) % len(nodes)] angles.append(angle(v1, v2)) result = 1 - np.std(angles) / np.pi #if angles don't add up to 360 degrees (only for quads) that means their dot product has a different sign somewhere #so it is non-convex --> avoid this quad if len(nodes) == 4 and not np.isclose(np.sum(angles), 2 * np.pi): return 0 return result
def dft_analysis(_input, window, N): """ Analysis of a signal using the discrete Fourier transform inputs: _input: tensor of shape [batch_size, N] window: analysis window, tensor of shape [N] N: FFT size returns: Tensors m, p: magnitude and phase spectrum of _input m of shape [batch_size, num_coefficients] p of shape [batch_size, num_coefficients] """ if not (is_power2(N)): raise ValueError("FFT size is not a power of 2") _, input_length = _input.get_shape() _input_shape = tf.shape(_input) if (int(input_length) > N): raise ValueError("Input length is greater than FFT size") if (int(window.get_shape()[0]) != N): raise ValueError("Window length is different from FFT size") if int(input_length) < N: with tf.name_scope('DFT_Zero_padding'): zeros_left = tf.zeros(_input_shape)[:, :int((N - (int(input_length)) + 1) / 2)] zeros_right = tf.zeros(_input_shape)[:, :int( (N - (int(input_length))) / 2)] _input = tf.concat([zeros_left, _input, zeros_right], axis=1) assert (int(_input.get_shape()[1]) == N) positive_spectrum_size = int(N / 2) + 1 with tf.name_scope('Windowing'): window_norm = tf.div(window, tf.reduce_sum(window)) # window the input windowed_input = tf.multiply(_input, window_norm) with tf.name_scope('Zero_phase_padding'): # zero-phase window in fftbuffer fftbuffer_left = tf.slice(windowed_input, [0, int(N / 2)], [-1, -1]) fftbuffer_right = tf.slice(windowed_input, [0, 0], [-1, int(N / 2)]) fftbuffer = tf.concat([fftbuffer_left, fftbuffer_right], axis=1) fft = tf.spectral.rfft(fftbuffer) with tf.name_scope('Slice_positive_side'): sliced_fft = tf.slice(fft, [0, 0], [-1, positive_spectrum_size]) with tf.name_scope('Magnitude'): # compute absolute value of positive side abs_fft = tf.abs(sliced_fft) # magnitude spectrum of positive frequencies in dB magnitude = 20 * log10(tf.maximum(abs_fft, 1E-06)) with tf.name_scope('Phase'): # phase of positive frequencies phase = angle(sliced_fft) return magnitude, phase