Ejemplo n.º 1
0
func GenerateMap(width, height int, gridSize int) *Map {

	m := new(Map)

	m.width = width
	m.height = height
	m.gridSize = gridSize
	m.grid = make([]int, width*height)

	diag := math.Hypot(float64(m.width/2), float64(m.height/2))
	for y := 0; y < height; y++ {
		for x := 0; x < width; x++ {

			fx := float64(x)
			fy := float64(y)
			// calculate inverse distance from center
			d := 1.0 - math.Hypot(float64(m.width/2)-fx, float64(m.height/2)-fy)/diag
			d = d
			v := noise.OctaveNoise2d(fx, fy, 4, 0.5, 1.0/64)
			v = (v + 1.0) / 2
			v = v * 256
			m.grid[y*width+x] = int(v)
			m.gridLines = append(m.gridLines, float32(x*m.gridSize), 0, float32(x*m.gridSize), float32((m.height-1)*m.gridSize))
		}
		m.gridLines = append(m.gridLines, 0, float32(y*m.gridSize), float32((m.width-1)*m.gridSize), float32(y*m.gridSize))
	}

	m.RebuildVertices()
	return m
}
Ejemplo n.º 2
0
func main() {
	var N int
	sc.Split(bufio.ScanWords)
	fmt.Scan(&N)
	dataA := make([]point, N)
	dataB := make([]point, N)
	var aveA, aveB point
	for i := 0; i < N; i++ {
		dataA[i].x = nextInt()
		dataA[i].y = nextInt()
		Add(&aveA, dataA[i])
	}
	for j := 0; j < N; j++ {
		dataB[j].x = nextInt()
		dataB[j].y = nextInt()
		Add(&aveB, dataB[j])
	}
	X := float64(N)
	aveA.x /= X
	aveA.y /= X
	aveB.x /= X
	aveB.y /= X
	lenA := float64(0)
	lenB := float64(0)
	for i := 0; i < N; i++ {
		if lenA < math.Hypot(dataA[i].x-aveA.x, dataA[i].y-aveA.y) {
			lenA = math.Hypot(dataA[i].x-aveA.x, dataA[i].y-aveA.y)
		}
		if lenB < math.Hypot(dataB[i].x-aveB.x, dataB[i].y-aveB.y) {
			lenB = math.Hypot(dataB[i].x-aveB.x, dataB[i].y-aveB.y)
		}
	}
	fmt.Println(lenB / lenA)
}
Ejemplo n.º 3
0
func wireBrane(min int, max int) {
	// wire the brane in a random fashion

	// for each neurode...
	for i := 0; i < len(brane.neurodes); i++ {
		this := brane.neurodes[i]

		// ...find all neurodes within reach of its forcept
		//var nearNeurodes []Neurode

		for j := 0; j < len(brane.neurodes); j++ {
			// skip self...
			if j != i {
				that := brane.neurodes[j]

				// calc 3d distance
				distance := int(math.Hypot(math.Hypot(float64(this.x)-float64(that.x), float64(this.y)-float64(that.y)), float64(this.z)-float64(that.z)))

				if distance <= this.flength {
					fmt.Println(this.id, that.id, distance)
				}
			}
		}
	}

}
Ejemplo n.º 4
0
// HasEdgeBetween optimistically returns whether an edge is exists between u and v.
func (l *LimitedVisionGrid) HasEdgeBetween(u, v graph.Node) bool {
	if u.ID() == v.ID() {
		return false
	}
	ur, uc := l.RowCol(u.ID())
	vr, vc := l.RowCol(v.ID())
	if abs(ur-vr) > 1 || abs(uc-vc) > 1 {
		return false
	}
	if !l.Grid.AllowDiagonal && ur != vr && uc != vc {
		return false
	}

	x, y := l.XY(l.Location)
	ux, uy := l.XY(u)
	vx, vy := l.XY(v)
	uKnown := l.Known[u.ID()] || math.Hypot(x-ux, y-uy) <= l.VisionRadius
	vKnown := l.Known[v.ID()] || math.Hypot(x-vx, y-vy) <= l.VisionRadius

	switch {
	case uKnown && vKnown:
		return l.Grid.HasEdgeBetween(u, v)
	case uKnown:
		return l.Grid.HasOpen(u)
	case vKnown:
		return l.Grid.HasOpen(v)
	default:
		return true
	}
}
Ejemplo n.º 5
0
// test that the barnes hut computation of repulsive
// forces is close to the classic computation
func TestComputeAccelerationOnBodyBarnesHut(t *testing.T) {

	bodies := make([]quadtree.Body, 2000000)
	SpreadOnCircle(&bodies)
	// quadtree.InitBodiesUniform( &bodies, 200)
	var r Run
	r.Init(&bodies)

	r.computeAccelerationOnBody(0)
	accReference := (*r.bodiesAccel)[0]

	r.computeAccelerationOnBodyBarnesHut(0)
	accBH := (*r.bodiesAccel)[0]

	r.q.CheckIntegrity(t)

	// measure the difference between reference and BH
	accReferenceLength := math.Hypot(accReference.X, accReference.Y)
	diff := math.Hypot((accReference.X - accBH.X), (accReference.Y - accBH.Y))

	relativeError := diff / accReferenceLength

	// tolerance is arbitrary set
	tolerance := 0.02 // 5%
	if relativeError > tolerance {
		t.Errorf("different results, accel ref x %f y %f, got x %f y %f", accReference.X, accReference.Y, accBH.X, accBH.Y)
		t.Errorf("different results, expected less than %f, got %f", tolerance, relativeError)
	}

}
Ejemplo n.º 6
0
func GenerateMap(width, depth int, gridSize int) *Map {

	m := new(Map)

	m.width = width
	m.depth = depth
	m.gridSize = gridSize
	m.minHeight = 1000000
	m.maxHeight = 0

	diag := math.Hypot(float64(m.width/2), float64(m.depth/2))
	for z := 0; z < depth; z++ {
		for x := 0; x < width; x++ {

			fx := float64(x) + float64(z%2)*0.5
			fz := float64(z)

			d := math.Hypot(float64(m.width/2)-fx, float64(m.depth/2)-fz)
			d = 1.0 - d/diag
			h := noise.OctaveNoise2d(fx, fz, 4, 0.25, 1.0/28)
			h = (h + 1.0) * 0.5
			h = math.Sqrt(h) * 1024 * (math.Pow(d, 2))
			h = math.Max(h, 120)
			m.heightMap = append(m.heightMap, float32(h))
			m.minHeight = math.Min(m.minHeight, h)
			m.maxHeight = math.Max(m.maxHeight, h)
		}
	}

	return m
}
Ejemplo n.º 7
0
func b(x, y int) uint8 {
	i := float64(x)
	j := float64(y)

	top := math.Hypot(300-i, 20-j) + 1
	bottom := math.Sqrt(float64(math.Abs(math.Sin((math.Hypot(503-i, 103-j))/115)))) + 1
	return uint8(top / bottom)
}
Ejemplo n.º 8
0
func r(x, y int) uint8 {
	i := float64(x)
	j := float64(y)

	top := math.Hypot(148-i, 1000-j) + 1
	bottom := math.Sqrt(float64(math.Abs(math.Sin((math.Hypot(500-i, 400-j))/115)))) + 1
	return uint8(top / bottom)
}
Ejemplo n.º 9
0
func g(x, y int) uint8 {
	i := float64(x)
	j := float64(y)

	top := math.Hypot(610-i, 60-j) + 1
	bottom := math.Sqrt(float64(math.Abs(math.Sin((math.Hypot(864-i, 860-j))/115)))) + 1
	return uint8(top / bottom)
}
Ejemplo n.º 10
0
// DrawLinear draws a linear gradient to dst. If the gradient vector (as
// defined by x0, y0, x1, and y1) is found to be purely horizontal or purely
// vertical, the appropriate optimized functions will be called.
func DrawLinear(dst draw.Image, x0, y0, x1, y1 float64, stops []Stop) {
	if y0 == y1 && x0 != x1 {
		drawHLinear(dst, x0, x1, stops)
		return
	}

	if x0 == x1 && y0 != y1 {
		drawVLinear(dst, y0, y1, stops)
		return
	}

	if len(stops) == 0 {
		return
	}

	if y0 > y1 {
		panic(fmt.Sprintf("invalid bounds y0(%f)>y1(%f)", y0, y1))
	}
	if x0 > x1 {
		panic(fmt.Sprintf("invalid bounds x0(%f)>x1(%f)", x0, x1))
	}

	bb := dst.Bounds()
	width, height := bb.Dx(), bb.Dy()

	x0, y0 = x0*float64(width), y0*float64(height)
	x1, y1 = x1*float64(width), y1*float64(height)

	dx, dy := x1-x0, y1-y0
	px0, py0 := x0-dy, y0+dx
	mag := math.Hypot(dx, dy)

	var col color.Color
	for y := 0; y < width; y++ {
		fy := float64(y)

		for x := 0; x < width; x++ {
			fx := float64(x)
			// is the pixel before the start of the gradient?
			s0 := (px0-x0)*(fy-y0) - (py0-y0)*(fx-x0)
			if s0 > 0 {
				col = stops[0].Col
			} else {
				// calculate the distance of the pixel from the first stop line
				u := ((fx-x0)*(px0-x0) + (fy-y0)*(py0-y0)) /
					(mag * mag)
				x2, y2 := x0+u*(px0-x0), y0+u*(py0-y0)
				d := math.Hypot(fx-x2, fy-y2) / mag

				col = getColour(d, stops)
			}
			dst.Set(x+bb.Min.X, y+bb.Min.Y, col)
		}
	}
}
Ejemplo n.º 11
0
func Arenstorf(yDot []float64, _ float64, y []float64) {
	mu1 := 0.012277471
	mu2 := 1 - mu1
	d1 := math.Hypot(y[0]+mu1, y[1])
	d1 *= d1 * d1
	d2 := math.Hypot(y[0]-mu2, y[1])
	d2 *= d2 * d2
	yDot[0] = y[2]
	yDot[1] = y[3]
	yDot[2] = y[0] + 2*y[3] - mu2*(y[0]+mu1)/d1 - mu1*(y[0]-mu2)/d2
	yDot[3] = y[1] - 2*y[2] - mu2*y[1]/d1 - mu1*y[1]/d2
}
// nearest finds the nearest mean to a given point.
// return values are the index of the nearest mean, and the distance from
// the point to the mean.
func nearest(p r2c, mean []r2) (int, float64) {
	iMin := 0
	dMin := math.Hypot(p.x-mean[0].x, p.y-mean[0].y)
	for i := 1; i < len(mean); i++ {
		d := math.Hypot(p.x-mean[i].x, p.y-mean[i].y)
		if d < dMin {
			dMin = d
			iMin = i
		}
	}
	return iMin, dMin
}
Ejemplo n.º 13
0
func TestHypot(t *testing.T) {
	f := func(x struct{ X, Y float32 }) bool {
		y := Hypot(x.X, x.Y)
		if math.Hypot(float64(x.X), float64(x.Y)) > math.MaxFloat32 {
			return true
		}
		return floats.EqualWithinRel(float64(y), math.Hypot(float64(x.X), float64(x.Y)), tol)
	}
	if err := quick.Check(f, nil); err != nil {
		t.Error(err)
	}
}
Ejemplo n.º 14
0
// Distance computes the L-norm of s - t. See Norm for special cases.
// A panic will occur if the lengths of s and t do not match.
func Distance(s, t []float64, L float64) float64 {
	if len(s) != len(t) {
		panic("floats: slice lengths do not match")
	}
	if len(s) == 0 {
		return 0
	}
	var norm float64
	if L == 2 {
		for i, v := range s {
			diff := t[i] - v
			norm = math.Hypot(norm, diff)
		}
		return norm
	}
	if L == 1 {
		for i, v := range s {
			norm += math.Abs(t[i] - v)
		}
		return norm
	}
	if math.IsInf(L, 1) {
		for i, v := range s {
			absDiff := math.Abs(t[i] - v)
			if absDiff > norm {
				norm = absDiff
			}
		}
		return norm
	}
	for i, v := range s {
		norm += math.Pow(math.Abs(t[i]-v), L)
	}
	return math.Pow(norm, 1/L)
}
Ejemplo n.º 15
0
// Norm returns the L norm of the slice S, defined as
// (sum_{i=1}^N s[i]^L)^{1/L}
// Special cases:
// L = math.Inf(1) gives the maximum absolute value.
// Does not correctly compute the zero norm (use Count).
func Norm(s []float64, L float64) float64 {
	// Should this complain if L is not positive?
	// Should this be done in log space for better numerical stability?
	//	would be more cost
	//	maybe only if L is high?
	if len(s) == 0 {
		return 0
	}
	if L == 2 {
		twoNorm := math.Abs(s[0])
		for i := 1; i < len(s); i++ {
			twoNorm = math.Hypot(twoNorm, s[i])
		}
		return twoNorm
	}
	var norm float64
	if L == 1 {
		for _, val := range s {
			norm += math.Abs(val)
		}
		return norm
	}
	if math.IsInf(L, 1) {
		for _, val := range s {
			norm = math.Max(norm, math.Abs(val))
		}
		return norm
	}
	for _, val := range s {
		norm += math.Pow(math.Abs(val), L)
	}
	return math.Pow(norm, 1/L)
}
Ejemplo n.º 16
0
// Position returns observed equatorial coordinates of a planet at a given time.
//
// Argument p must be a valid V87Planet object for the observed planet.
// Argument earth must be a valid V87Planet object for Earth.
//
// Results are right ascension and declination, α and δ in radians.
func Position(p, earth *pp.V87Planet, jde float64) (α, δ float64) {
	L0, B0, R0 := earth.Position(jde)
	L, B, R := p.Position(jde)
	sB0, cB0 := math.Sincos(B0)
	sL0, cL0 := math.Sincos(L0)
	sB, cB := math.Sincos(B)
	sL, cL := math.Sincos(L)
	x := R*cB*cL - R0*cB0*cL0
	y := R*cB*sL - R0*cB0*sL0
	z := R*sB - R0*sB0
	{
		Δ := math.Sqrt(x*x + y*y + z*z) // (33.4) p. 224
		τ := base.LightTime(Δ)
		// repeating with jde-τ
		L, B, R = p.Position(jde - τ)
		sB, cB = math.Sincos(B)
		sL, cL = math.Sincos(L)
		x = R*cB*cL - R0*cB0*cL0
		y = R*cB*sL - R0*cB0*sL0
		z = R*sB - R0*sB0
	}
	λ := math.Atan2(y, x)                // (33.1) p. 223
	β := math.Atan2(z, math.Hypot(x, y)) // (33.2) p. 223
	Δλ, Δβ := apparent.EclipticAberration(λ, β, jde)
	λ, β = pp.ToFK5(λ+Δλ, β+Δβ, jde)
	Δψ, Δε := nutation.Nutation(jde)
	λ += Δψ
	sε, cε := math.Sincos(nutation.MeanObliquity(jde) + Δε)
	return coord.EclToEq(λ, β, sε, cε)
	// Meeus gives a formula for elongation but doesn't spell out how to
	// obtaion term λ0 and doesn't give an example solution.
}
Ejemplo n.º 17
0
// Compute Wilkinson shift from symmetric 2x2 trailing submatrix
// Stable formula from Hogben 2007, 42.3
func wilkinson(tn1, tnn1, tn float64) float64 {
	var d, tsq float64
	d = (tn1 - tn) / 2.0
	tsq = math.Hypot(d, tnn1)
	u := tn - math.Copysign((tnn1/(math.Abs(d)+tsq))*tnn1, d)
	return u
}
Ejemplo n.º 18
0
func TestComplexContours(t *testing.T) {
	if !*visualDebug {
		return
	}
	for _, n := range []float64{0, 1, 2, 4, 8, 16, 32} {
		data := make([]float64, 6400)
		for i := range data {
			r := float64(i/80) - 40
			c := float64(i%80) - 40

			data[i] = rand.NormFloat64()*n + math.Hypot(r, c)
		}

		m := unitGrid{mat64.NewDense(80, 80, data)}

		levels := []float64{-1, 3, 7, 9, 13, 15, 19, 23, 27, 31}
		c := NewContour(m, levels, palette.Rainbow(10, palette.Blue, palette.Red, 1, 1, 1))

		plt, _ := plot.New()
		plt.Add(c)

		plt.X.Padding = 0
		plt.Y.Padding = 0
		plt.X.Max = 79.5
		plt.Y.Max = 79.5
		plt.Save(7, 7, fmt.Sprintf("complex_contour-%v.svg", n))
	}
}
Ejemplo n.º 19
0
Archivo: quake.go Proyecto: GeoNet/haz
// MMIDistance calculates the MMI at distance for New Zealand.  Distance and depth are in km.
func MMIDistance(distance, depth, mmi float64) float64 {
	// Minimum depth of 5 for numerical instability.
	d := math.Max(math.Abs(depth), 5.0)
	s := math.Hypot(d, distance)

	return math.Max(mmi-1.18*math.Log(s/d)-0.0044*(s-d), -1.0)
}
Ejemplo n.º 20
0
// DrotG gives plane rotation
//
// _      _    _   _     _   _
// | c  s |    | a |     | r |
// | -s c |  * | b |   = | 0 |
// _      _    _   _     _   _
//
// r = ±(a^2 + b^2)
// c = a/r, the cosine of the plane rotation
// s = b/r, the sine of the plane rotation
//
// NOTE: Netlib library seems to give a different
// sign for r when a or b is zero than other implementations
// and different than BLAS technical manual
func (Blas) Drotg(a, b float64) (c, s, r, z float64) {
	if b == 0 && a == 0 {
		return 1, 0, a, 0
	}
	/*
		if a == 0 {
			if b > 0 {
				return 0, 1, b, 1
			}
			return 0, -1, -b, 1
		}
	*/
	absA := math.Abs(a)
	absB := math.Abs(b)
	aGTb := absA > absB
	r = math.Hypot(a, b)
	if aGTb {
		r = math.Copysign(r, a)
	} else {
		r = math.Copysign(r, b)
	}
	c = a / r
	s = b / r
	if aGTb {
		z = s
	} else if c != 0 { // r == 0 case handled above
		z = 1 / c
	} else {
		z = 1
	}
	return
}
Ejemplo n.º 21
0
// Polar returns the polar coords (angle and radius) for a Cartesian point.
func Polar(loc Point) (theta, r float64) {
	if (loc == Point{0, 0}) {
		return 0, 0 // The angle is actually undefined but this will do.
	}
	x, y := float64(loc.X), float64(loc.Y)
	return math.Mod(math.Atan2(x, y)+2*math.Pi, 2*math.Pi), math.Hypot(x, y)
}
Ejemplo n.º 22
0
// Converts cylindrical coordinates with radial distance r,
// azimuth phi, and height z to spherical coordinates with radius r,
// inclination theta, and azimuth phi.
//
// Angles are in radians
func CylindircalToSpherical(rho, phi, z float64) (r, theta, phi2 float64) {
	r = float64(math.Hypot(float64(rho), float64(z)))
	phi2 = phi
	theta = float64(math.Atan2(float64(rho), float64(z)))

	return
}
Ejemplo n.º 23
0
// Convert Cartesian coordinates to polar.
// The reference ellipsoid is copied verbatim to the result.
// The resulting polar coordinates are in decimal degrees.
// Inspired by http://www.movable-type.co.uk/scripts/latlong-convert-coords.html
func CartesianToPolar(pt *CartPoint) *PolarCoord {

	var gc PolarCoord

	el := pt.El

	esq := (el.a*el.a - el.b*el.b) / (el.a * el.a)
	p := math.Hypot(pt.X, pt.Y)

	lat := math.Atan2(pt.Z, p*(1-esq))
	lat0 := 2.0 * math.Pi

	precision := 4.0 / el.a
	var v float64
	for math.Abs(lat-lat0) > precision {
		v = el.a / math.Sqrt(1-esq*math.Pow(math.Sin(lat), 2))

		lat0 = lat
		lat = math.Atan2(pt.Z+esq*v*math.Sin(lat), p)
	}

	gc.Height = p/math.Cos(lat) - v
	gc.Latitude = radtodeg(lat)
	gc.Longitude = radtodeg(math.Atan2(pt.Y, pt.X))

	gc.El = el

	return &gc
}
Ejemplo n.º 24
0
// Norm returns the specified matrix p-norm of the receiver.
//
// See the Normer interface for more information.
func (m *Dense) Norm(ord float64) float64 {
	var n float64
	switch {
	case ord == 1:
		col := make([]float64, m.mat.Rows)
		for i := 0; i < m.mat.Cols; i++ {
			var s float64
			for _, e := range m.Col(col, i) {
				s += math.Abs(e)
			}
			n = math.Max(s, n)
		}
	case math.IsInf(ord, +1):
		row := make([]float64, m.mat.Cols)
		for i := 0; i < m.mat.Rows; i++ {
			var s float64
			for _, e := range m.Row(row, i) {
				s += math.Abs(e)
			}
			n = math.Max(s, n)
		}
	case ord == -1:
		n = math.MaxFloat64
		col := make([]float64, m.mat.Rows)
		for i := 0; i < m.mat.Cols; i++ {
			var s float64
			for _, e := range m.Col(col, i) {
				s += math.Abs(e)
			}
			n = math.Min(s, n)
		}
	case math.IsInf(ord, -1):
		n = math.MaxFloat64
		row := make([]float64, m.mat.Cols)
		for i := 0; i < m.mat.Rows; i++ {
			var s float64
			for _, e := range m.Row(row, i) {
				s += math.Abs(e)
			}
			n = math.Min(s, n)
		}
	case ord == 0:
		for i := 0; i < len(m.mat.Data); i += m.mat.Stride {
			for _, v := range m.mat.Data[i : i+m.mat.Cols] {
				n = math.Hypot(n, v)
			}
		}
		return n
	case ord == 2, ord == -2:
		s := SVD(m, epsilon, small, false, false).Sigma
		if ord == 2 {
			return s[0]
		}
		return s[len(s)-1]
	default:
		panic(ErrNormOrder)
	}

	return n
}
Ejemplo n.º 25
0
func f(x, y float64) float64 {
	r := math.Hypot(x, y) // distance from (0,0)
	if r < 3 {
		return math.Sin(r) / 0
	}
	return math.Sin(r) / r
}
Ejemplo n.º 26
0
Archivo: ex1.go Proyecto: suzuken/gopl
func f(x, y float64) (float64, bool) {
	r := math.Hypot(x, y) // distance from (0,0)
	if math.IsNaN(r) || math.IsInf(r, 0) {
		return 0, false
	}
	return math.Sin(r) / r, true
}
func circles(p1, p2 point, r float64) (c1, c2 point, Case string) {
	if p1 == p2 {
		if r == 0 {
			return p1, p1, CoR0
		}
		Case = Co
		return
	}
	if r == 0 {
		return p1, p2, R0
	}
	dx := p2.x - p1.x
	dy := p2.y - p1.y
	q := math.Hypot(dx, dy)
	if q > 2*r {
		Case = Far
		return
	}
	m := point{(p1.x + p2.x) / 2, (p1.y + p2.y) / 2}
	if q == 2*r {
		return m, m, Diam
	}
	d := math.Sqrt(r*r - q*q/4)
	ox := d * dx / q
	oy := d * dy / q
	return point{m.x - oy, m.y + ox}, point{m.x + oy, m.y - ox}, Two
}
func isWithinPore(a Atom, x, y, r float64) bool {
	dist := math.Hypot(x-a.x, y-a.y)
	// if dist > r {
	//     log.Println(a.x, a.y, "Distance", dist, "r", r)
	// }
	return dist <= r
}
Ejemplo n.º 29
0
func hough(im image.Image, ntx, mry int) draw.Image {
	nimx := im.Bounds().Max.X
	mimy := im.Bounds().Max.Y
	mry = int(mry/2) * 2
	him := image.NewGray(image.Rect(0, 0, ntx, mry))
	draw.Draw(him, him.Bounds(), image.NewUniform(color.White),
		image.ZP, draw.Src)

	rmax := math.Hypot(float64(nimx), float64(mimy))
	dr := rmax / float64(mry/2)
	dth := math.Pi / float64(ntx)

	for jx := 0; jx < nimx; jx++ {
		for iy := 0; iy < mimy; iy++ {
			col := color.GrayModel.Convert(im.At(jx, iy)).(color.Gray)
			if col.Y == 255 {
				continue
			}
			for jtx := 0; jtx < ntx; jtx++ {
				th := dth * float64(jtx)
				r := float64(jx)*math.Cos(th) + float64(iy)*math.Sin(th)
				iry := mry/2 - int(math.Floor(r/dr+.5))
				col = him.At(jtx, iry).(color.Gray)
				if col.Y > 0 {
					col.Y--
					him.SetGray(jtx, iry, col)
				}
			}
		}
	}
	return him
}
Ejemplo n.º 30
0
func (m *Map) Add(x, y, val, radius int) {

	xi := (x - m.gridSize/2) / m.gridSize
	yi := (y - m.gridSize/2) / m.gridSize
	ri := radius / m.gridSize

	for y := -ri; y <= ri; y++ {
		for x := -ri; x <= ri; x++ {

			i := (yi+y)*m.width + (xi + x)
			if xi+x < 0 || xi+x >= m.width || yi+y < 0 || yi+y >= m.height {
				continue
			}

			a := float64(m.grid[i])
			b := float64(val)
			d := 1.0 - math.Hypot(float64(x), float64(y))/(float64(ri)*math.Sqrt2)
			d *= 0.25

			m.grid[i] = int(a + (b-a)*d)
			m.grid[i] = int(math.Max(0, float64(m.grid[i])))
			m.grid[i] = int(math.Min(512, float64(m.grid[i])))
		}
	}

	m.RebuildVertices()
}