/** 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) }
func normalize(v1 mgl32.Vec2, length float32) mgl32.Vec2 { length_current := v1.Len() if length_current > 0 { v1 = v1.Mul(length / length_current) } return v1 }
func (polyline *polyLine) renderNoEdge(sleeve, current, next mgl32.Vec2) { sleeve_normal := getNormal(sleeve, polyline.halfwidth/sleeve.Len()) polyline.normals = append(polyline.normals, sleeve_normal) polyline.normals = append(polyline.normals, sleeve_normal.Mul(-1)) sleeve = next.Sub(current) sleeve_normal = getNormal(sleeve, polyline.halfwidth/sleeve.Len()) polyline.normals = append(polyline.normals, sleeve_normal.Mul(-1)) polyline.normals = append(polyline.normals, sleeve_normal) 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) }
func (m *Mob) moveTowardExit(elapsed time.Duration, level *Level) { var ( dest mgl32.Vec2 ok bool pct = float32(elapsed) / float32(time.Second) gridDist mgl32.Vec2 goalDist int32 stepDist = pct * m.Speed ) if dest, goalDist, ok = level.Grid.GetNextStepToSink(m.Pos); !ok { return } gridDist = dest.Sub(m.Pos) if goalDist == 1 && gridDist.Len() < stepDist+0.5 { m.PendingDisable = true } if gridDist.X() > 0 { m.swapState(Left, Right) } else { m.swapState(Right, Left) } m.Pos = m.Pos.Add(gridDist.Normalize().Mul(stepDist)) }