/** Calculate line boundary points. * * Sketch: * * uh1___uh2 * .' '. * .' q '. * .' ' ' '. *.' ' .'. ' '. * ' .' ul'. ' * p .' '. r * * * ul can be found as above, uh1 and uh2 are much simpler: * * uh1 = q + ns * w/2, uh2 = q + nt * w/2 */ func (polyline *polyLine) renderBevelEdge(sleeve, current, next mgl32.Vec2) { t := next.Sub(current) len_t := t.Len() det := determinant(sleeve, t) if mgl32.Abs(det)/(sleeve.Len()*len_t) < LINES_PARALLEL_EPS && sleeve.Dot(t) > 0 { // lines parallel, compute as u1 = q + ns * w/2, u2 = q - ns * w/2 n := getNormal(t, polyline.halfwidth/len_t) polyline.normals = append(polyline.normals, n) polyline.normals = append(polyline.normals, n.Mul(-1)) polyline.generateEdges(current, 2) return // early out } // cramers rule sleeve_normal := getNormal(sleeve, polyline.halfwidth/sleeve.Len()) nt := getNormal(t, polyline.halfwidth/len_t) lambda := determinant(nt.Sub(sleeve_normal), t) / det d := sleeve_normal.Add(sleeve.Mul(lambda)) if det > 0 { // 'left' turn -> intersection on the top polyline.normals = append(polyline.normals, d) polyline.normals = append(polyline.normals, sleeve_normal.Mul(-1)) polyline.normals = append(polyline.normals, d) polyline.normals = append(polyline.normals, nt.Mul(-1)) } else { polyline.normals = append(polyline.normals, sleeve_normal) polyline.normals = append(polyline.normals, d.Mul(-1)) polyline.normals = append(polyline.normals, nt) polyline.normals = append(polyline.normals, d.Mul(-1)) } polyline.generateEdges(current, 4) }
/** Calculate line boundary points. * * Sketch: * * u1 * -------------+---...___ * | ```'''-- --- * p- - - - - - q- - . _ _ | w/2 * | ` ' ' r + * -------------+---...___ | w/2 * u2 ```'''-- --- * * u1 and u2 depend on four things: * - the half line width w/2 * - the previous line vertex p * - the current line vertex q * - the next line vertex r * * u1/u2 are the intersection points of the parallel lines to p-q and q-r, * i.e. the point where * * (q + w/2 * ns) + lambda * (q - p) = (q + w/2 * nt) + mu * (r - q) (u1) * (q - w/2 * ns) + lambda * (q - p) = (q - w/2 * nt) + mu * (r - q) (u2) * * with nt,nt being the normals on the segments s = p-q and t = q-r, * * ns = perp(s) / |s| * nt = perp(t) / |t|. * * Using the linear equation system (similar for u2) * * q + w/2 * ns + lambda * s - (q + w/2 * nt + mu * t) = 0 (u1) * <=> q-q + lambda * s - mu * t = (nt - ns) * w/2 * <=> lambda * s - mu * t = (nt - ns) * w/2 * * the intersection points can be efficiently calculated using Cramer's rule. */ func (polyline *polyLine) renderMiterEdge(sleeve, current, next mgl32.Vec2) { sleeve_normal := getNormal(sleeve, polyline.halfwidth/sleeve.Len()) t := next.Sub(current) len_t := t.Len() det := determinant(sleeve, t) // lines parallel, compute as u1 = q + ns * w/2, u2 = q - ns * w/2 if mgl32.Abs(det)/(sleeve.Len()*len_t) < LINES_PARALLEL_EPS && sleeve.Dot(t) > 0 { polyline.normals = append(polyline.normals, sleeve_normal) polyline.normals = append(polyline.normals, sleeve_normal.Mul(-1)) } else { // cramers rule nt := getNormal(t, polyline.halfwidth/len_t) lambda := determinant(nt.Sub(sleeve_normal), t) / det d := sleeve_normal.Add(sleeve.Mul(lambda)) polyline.normals = append(polyline.normals, d) polyline.normals = append(polyline.normals, d.Mul(-1)) } polyline.generateEdges(current, 2) }