def _BresTriBase(p0,p1,p2,dss_rerun=False, iscan_iline=None): '''Do grunt work common to both Bresenham Triangle functions''' borderPts = GetTriangleBorderPoints(p0,p1,p2) if iscan_iline is not None: iscan, iline = iscan_iline return iscan, iline, borderPts # Get the steepest dimension relative to every other dimension: dSS = GetDirectionsOfSteepestSlope(p0,p1,p2) dSS_notNone = [i for i in dSS if i!=None] if len(dSS_notNone) == 0: # Degenerate slope matrix (all 0's); points are collinear return borderPts iscan = getMostCommonVal(dSS_notNone) if dss_rerun: all_but = [i for i in range(len(p0)) if i != iscan] p0a,p1a,p2a = fL([p0,p1,p2])[:, all_but] dSS2 = GetDirectionsOfSteepestSlope(p0a,p1a,p2a) dSS2_notNone = [i for i in dSS2 if i!=None] iline = getMostCommonVal(dSS2_notNone) if iline >= iscan: iline += 1 else: iline = dSS[iscan] assert iline!=None, "iline is <flat>, that can't be right!" return iscan, iline, borderPts
def _BresenhamTriangle_PlaneFormulaVersion(p0, p1, p2, iscan_iline=None): # Generalization for triangle '''Bresenham N-D triangle rasterization Uses a Bresenham-like algorithm, but uses floating-point math and rounding for greater accuracy. Holes are prevented by proper selection of dimensions: the 'scan' dimension is fixed for each line (x') the 'line' dimension has the maximum slope perpendicular to iscan (y') All other dimensions are interpolated using the formula for a plane: for three points (x0,y0,z0,...), (x1,y1,z1,...), (x2,y2,z2,...): x = x0 + (x1-x0)*s + (x2-x0)*t y = y0 + (y1-y0)*s + (y2-y0)*t z = z0 + (z1-z0)*s + (z2-z0)*t ... When 2 of these (x' and y') are fixed, we can solve for s and t: (here using A and B instead of x' and y'): A = A0 + (A1-A0)*s + (A2-A0)*t B = B0 + (B1-B0)*s + (B2-B0)*t Using matrix form and with dX01 = X1-X0 and dX02 = X2-X0: [A - A0] = [dA01 dA02] * [s] [B - B0] = [dB01 dB02] * [t] We can solve by inverting tbe delta's matrix: [s] = [dA01 dA02]^-1 * [A - A0] [t] = [dB01 dB02] * [B - B0] Lastly, we find values for all remaining coordinates (x,y,z,...) by plugging s and t back into the original equations and rounding the result. ''' if p2==None: return BresenhamFunction(p0,p1) # In case the last argument is None just use a plane... p = np.array([p0,p1,p2]) iscan, iline, borderPts = _BresTriBase(p0,p1,p2,dss_rerun=False, iscan_iline=iscan_iline) # Draw Bresenham lines to rasterize the triangle (draw along y' direction for each x' value) minMaxList = _getMinMaxList(borderPts,iscan,iline) # Get the points in the iscan/iline projection of the output: minMaxProjected = fL(minMaxList)[:, :, (iscan, iline)] projectedTriPts = _map_BresLines(minMaxProjected) new_points = sample_points_from_plane(p, projectedTriPts, iscan, iline) return new_points