code: func rayCasting(cx, cy float64, objects []object) []line {
  	const rayLength = 1000 // something large enough to reach all objects
  
  	var rays []line
  	for _, obj := range objects {
  		// Cast two rays per point
  		for _, p := range obj.points() {
  			l := line{cx, cy, p[0], p[1]}
  			angle := l.angle()
  
  			for _, offset := range []float64{-0.005, 0.005} {
  				points := [][2]float64{}
  				ray := newRay(cx, cy, rayLength, angle+offset)
  
  				// Unpack all objects
  				for _, o := range objects {
  					for _, wall := range o.walls {
  						if px, py, ok := intersection(ray, wall); ok {
  							points = append(points, [2]float64{px, py})
  						}
  					}
  				}
  
  				// Find the point closest to start of ray
  				min := math.Inf(1)
  				minI := -1
  				for i, p := range points {
  					d2 := (cx-p[0])*(cx-p[0]) + (cy-p[1])*(cy-p[1])
  					if d2 < min {
  						min = d2
  						minI = i
  					}
  				}
  				rays = append(rays, line{cx, cy, points[minI][0], points[minI][1]})
  			}
  		}
  	}
  
  	// Sort rays based on angle, otherwise light triangles will not come out right
  	sort.Slice(rays, func(i int, j int) bool {
  		return rays[i].angle() < rays[j].angle()
  	})
  	return rays
  }
docs: // rayCasting returns a slice of line originating from point cx, cy and intersecting with objects