package world // drawPointInTile draws point marker copies that intersect the tile. // lastStyle is already applied; it provides PointRadiusPx. func (w *World) drawPointInTile(drawer PrimitiveDrawer, plan RenderPlan, td TileDrawPlan, p Point, allowWrap bool, lastStyle Style) { rPx := lastStyle.PointRadiusPx if rPx <= 0 { // Nothing visible. return } // Convert screen radius to world-fixed conservatively. rWorldFp := PixelSpanToWorldFixed(int(rPx+0.999999), plan.ZoomFp) var shifts []wrapShift if allowWrap { shifts = pointWrapShifts(p, rWorldFp, w.W, w.H) } else { shifts = []wrapShift{{dx: 0, dy: 0}} } for _, s := range shifts { if allowWrap && !pointCopyIntersectsTile(p, rWorldFp, s.dx, s.dy, td.Tile) { continue } px := worldSpanFixedToCanvasPx((p.X+td.Tile.OffsetX+s.dx)-plan.WorldRect.minX, plan.ZoomFp) py := worldSpanFixedToCanvasPx((p.Y+td.Tile.OffsetY+s.dy)-plan.WorldRect.minY, plan.ZoomFp) drawer.AddPoint(float64(px), float64(py), rPx) fill := alphaNonZero(lastStyle.FillColor) stroke := alphaNonZero(lastStyle.StrokeColor) if fill { drawer.Fill() } if stroke { // Stroke must be last when both are present. drawer.Stroke() } } } func (w *World) drawCircleInTile(drawer PrimitiveDrawer, plan RenderPlan, td TileDrawPlan, c Circle, allowWrap bool, lastStyle Style) { var shifts []wrapShift effRadius := circleRadiusEffFp(c.Radius, w.circleRadiusScaleFp) if allowWrap { shifts = circleWrapShifts(c.X, c.Y, effRadius, w.W, w.H) } else { shifts = []wrapShift{{dx: 0, dy: 0}} } rPx := worldSpanFixedToCanvasPx(effRadius, plan.ZoomFp) for _, s := range shifts { if allowWrap && !circleCopyIntersectsTile(c.X, c.Y, effRadius, s.dx, s.dy, td.Tile, w.W, w.H) { continue } cxPx := worldSpanFixedToCanvasPx((c.X+td.Tile.OffsetX+s.dx)-plan.WorldRect.minX, plan.ZoomFp) cyPx := worldSpanFixedToCanvasPx((c.Y+td.Tile.OffsetY+s.dy)-plan.WorldRect.minY, plan.ZoomFp) drawer.AddCircle(float64(cxPx), float64(cyPx), float64(rPx)) fill := alphaNonZero(lastStyle.FillColor) stroke := alphaNonZero(lastStyle.StrokeColor) if fill { drawer.Fill() } if stroke { // Stroke must be last when both are present. drawer.Stroke() } } } func (w *World) drawLineInTile(drawer PrimitiveDrawer, plan RenderPlan, td TileDrawPlan, l Line, allowWrap bool) { var segs []lineSeg if allowWrap { segs = torusShortestLineSegments(l, w.W, w.H) } else { segs = []lineSeg{{x1: l.X1, y1: l.Y1, x2: l.X2, y2: l.Y2}} } for _, s := range segs { // Project into tile/canvas. x1 := worldSpanFixedToCanvasPx((s.x1+td.Tile.OffsetX)-plan.WorldRect.minX, plan.ZoomFp) y1 := worldSpanFixedToCanvasPx((s.y1+td.Tile.OffsetY)-plan.WorldRect.minY, plan.ZoomFp) x2 := worldSpanFixedToCanvasPx((s.x2+td.Tile.OffsetX)-plan.WorldRect.minX, plan.ZoomFp) y2 := worldSpanFixedToCanvasPx((s.y2+td.Tile.OffsetY)-plan.WorldRect.minY, plan.ZoomFp) drawer.AddLine(float64(x1), float64(y1), float64(x2), float64(y2)) drawer.Stroke() } }