def _discretize_geometry(self): """ Discretizes the alignment geometry to a series of vector points """ interval = self.Object.Seg_Value interval_type = self.Object.Method #alignment construction requires a 'look ahead' at the next element #This implementation does a 'look back' at the previous. #Thus, iteration starts at the second element and #the last element is duplicated to ensure it is constructed. geometry = self.Object.Geometry if not geometry: print('No geometry defined. Unnable to discretize') return None prev_geo = [float(_i) for _i in geometry[0].split(',')] #test in case we only have one geometric element if len(geometry) > 1: geometry = geometry[1:] geometry.append(geometry[-1]) prev_curve_tangent = 0.0 coords = [App.Vector(0.0, 0.0, 0.0)] for geo_string in geometry: #convert the commo-delimited string of floats into a list of strings, then to floats _geo = [float(_i) for _i in geo_string.split(',')] bearing_in = math.radians(prev_geo[1]) bearing_out = math.radians(_geo[1]) curve_dir, central_angle = Utils.directed_angle( Utils.vector_from_angle(bearing_in), Utils.vector_from_angle(bearing_out)) curve_tangent = prev_geo[2] * math.tan(central_angle / 2.0) #alternate calculation for spiral curves if prev_geo[3] > 0.0: curve_tangent = (prev_geo[3] / 2.0) + (prev_geo[2] + ( (prev_geo[3]**2) / (24 * prev_geo[2]))) * math.tan(central_angle / 2.0) #previous tangent length = distance between PI's minus the two curve tangents prev_tan_len = prev_geo[0] - curve_tangent - prev_curve_tangent #skip if our tangent length is too short leadng up to a curve (likely a compound curve) if prev_tan_len >= 1: coords.extend( self.discretize_arc(coords[-1], bearing_in, prev_tan_len, 0.0, 0.0, 'Segment')) #zero radius means no curve. We're done if prev_geo[2] > 0.0: if prev_geo[3] > 0.0: coords.extend( self.discretize_spiral(coords[-1], bearing_in, prev_geo[2], central_angle * curve_dir, prev_geo[3], interval, interval_type)) else: coords.extend( self.discretize_arc(coords[-1], bearing_in, prev_geo[2], central_angle * curve_dir, interval, interval_type)) prev_geo = _geo prev_curve_tangent = curve_tangent return coords
def _discretize_geometry(self, segments): ''' Discretizes the alignment geometry to a series of vector points ''' print('discretizing ', self.Object.Geometry) #alignment construction requires a 'look ahead' at the next element #This implementation does a 'look back' at the previous. #Thus, iteration starts at the second element and #the last element is duplicated to ensure it is constructed. geometry = self.Object.Geometry if not geometry: print('No geometry defined. Unnable to discretize') return None prev_geo = geometry[0] #test in case we only have one geometric element if len(geometry) > 1: geometry = geometry[1:] geometry.append(geometry[-1]) prev_coord = App.Vector(0.0, 0.0, 0.0) prev_curve_tangent = 0.0 coords = [App.Vector(0.0, 0.0, 0.0)] for _geo in geometry: print('\n-----=======>>>>>', _geo) distance = prev_geo[0] bearing_in = math.radians(prev_geo[1]) bearing_out = math.radians(_geo[1]) in_tangent = Utils.vector_from_angle(bearing_in) out_tangent = Utils.vector_from_angle(bearing_out) curve_dir, central_angle = Utils.directed_angle( in_tangent, out_tangent) radius = prev_geo[2] #if both the current geometry and the look-back geometry have nno-zero radii, #we're between curves between_curves = radius > 0.0 and _geo[2] > 0.0 curve_tangent = radius * math.tan(central_angle / 2.0) prev_tan_len = distance - curve_tangent - prev_curve_tangent _forward = App.Vector(math.sin(bearing_in), math.cos(bearing_in), 0.0) print('bearing in ', bearing_in) print('bearing_out ', bearing_out) print('distance ', distance) print('in-tangent ', in_tangent) print('out-tangent ', out_tangent) print('curve-dir ', curve_dir) print('central angle ', central_angle) print('radius ', radius) print('between curves? ', between_curves) print('prev_tan_len ', prev_tan_len) print('curve tangent ', curve_tangent) #skip if our tangent length is too short leadng up to a curve (likely a compound curve) if prev_tan_len >= 1: #DocumentProperties.MinimumTangentLength.get_value() or not between_curves: #append three coordinates: # one a millimeter away from the starting point # one a millimeter away from the ending point # one at the end point mm_tan_len = prev_tan_len * 304.80 coords.append(prev_coord.add(_forward)) coords.append( prev_coord.add( App.Vector(_forward).multiply(mm_tan_len - 1))) coords.append( prev_coord.add(App.Vector(_forward).multiply(mm_tan_len))) #zero radius or curve direction means no curve. We're done if radius > 0.0: _left = App.Vector(_forward.y, -_forward.x, 0.0) seg_rad = central_angle / float(segments) prev_coord = coords[-1] radius_mm = radius * 304.80 unit_delta = seg_rad * 0.01 print('prev coord ', prev_coord) print('radius mm ', radius_mm) print('unit delta ', unit_delta) print('seg_rad ', seg_rad) print('segments ', segments) for _i in range(0, segments): delta = float(_i + 1) * seg_rad _dfw = App.Vector(_forward).multiply(math.sin(delta)) _dlt = App.Vector(_left).multiply(curve_dir * (1 - math.cos(delta))) coords.append( prev_coord.add(_dfw.add(_dlt).multiply(radius_mm))) print('next coord ', coords[-1]) prev_geo = _geo prev_coord = coords[-1] prev_curve_tangent = curve_tangent print('COORDS: ', coords) return coords