/** 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) }
// Scale scales the coordinate system in two dimensions. By default the coordinate system /// in amore corresponds to the display pixels in horizontal and vertical directions // one-to-one, and the x-axis increases towards the right while the y-axis increases // downwards. Scaling the coordinate system changes this relation. After scaling by // sx and sy, all coordinates are treated as if they were multiplied by sx and sy. // Every result of a drawing operation is also correspondingly scaled, so scaling by // (2, 2) for example would mean making everything twice as large in both x- and y-directions. Scaling by a negative value flips the coordinate system in the corresponding direction, which also means everything will be drawn flipped or upside down, or both. Scaling by zero is not a useful operation. // Scale and translate are not commutative operations, therefore, calling them // in different orders will change the outcome. Scaling lasts until drawing completes func Scale(args ...float32) { if args == nil || len(args) == 0 { panic("not enough params passed to scale call") } var sx, sy float32 sx = args[0] if len(args) > 1 { sy = args[1] } else { sy = sx } gl_state.viewStack.LeftMul(mgl32.Scale3D(sx, sy, 1)) states.back().pixelSize *= (2.0 / (mgl32.Abs(sx) + mgl32.Abs(sy))) }
/** 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) }