Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ func function(x, y float64) float64 {
func main() {
scene := ln.Scene{}
box := ln.Box{ln.Vector{-2, -2, -4}, ln.Vector{2, 2, 2}}
scene.Add(ln.NewFunction(function, box, ln.Below))
scene.Add(ln.NewGridFunction(function, box, ln.Below))
eye := ln.Vector{3, 0, 3}
center := ln.Vector{1.1, 0, 0}
up := ln.Vector{0, 0, 1}
Expand Down
46 changes: 35 additions & 11 deletions ln/cylinder.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,44 @@ func (shape *Cylinder) Intersect(ray Ray) Hit {
return NoHit
}
s := math.Sqrt(q)
t := 1e30
t0 := (-b + s) / (2 * a)
t1 := (-b - s) / (2 * a)
if t0 > t1 {
t0, t1 = t1, t0
}
z0 := o.Z + t0*d.Z
z1 := o.Z + t1*d.Z
if t0 > 1e-6 && shape.Z0 < z0 && z0 < shape.Z1 {
return Hit{shape, t0}
if 1e-6 < t0 && t0 < t {
z := o.Z + t0*d.Z
if shape.Z0 < z && z < shape.Z1 {
t = t0
}
}
if t1 > 1e-6 && shape.Z0 < z1 && z1 < shape.Z1 {
return Hit{shape, t1}
t1 := (-b - s) / (2 * a)
if 1e-6 < t1 && t1 < t {
z := o.Z + t1*d.Z
if shape.Z0 < z && z < shape.Z1 {
t = t1
}
}
return NoHit
if d.Z != 0 {
t3 := (shape.Z0 - o.Z) / d.Z
if 1e-6 < t3 && t3 < t {
z := o.Add(d.MulScalar(t3))
z.Z = 0
if z.LengthSquared() < r * r {
t = t3
}
}
t4 := (shape.Z1 - o.Z) / d.Z
if 1e-6 < t4 && t4 < t {
z := o.Add(d.MulScalar(t4))
z.Z = 0
if z.LengthSquared() < r * r {
t = t4
}
}
}
if t < 1e30 {
return Hit{shape, t}
} else {
return NoHit
}

}

Expand Down
74 changes: 68 additions & 6 deletions ln/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@ type Function struct {
Function func(x, y float64) float64
Box Box
Direction Direction
PathsImpl func(f* Function) Paths
}

func NewFunction(function func(x, y float64) float64, box Box, direction Direction) Shape {
return &Function{function, box, direction}
func NewFunction(function func(x, y float64) float64, box Box, direction Direction, pathsImpl func(f* Function) Paths) Shape {
return &Function{function, box, direction, pathsImpl}
}

func (f *Function) Paths() Paths {
return f.PathsImpl(f);
}

func (f *Function) Compile() {
Expand Down Expand Up @@ -46,7 +51,8 @@ func (f *Function) Intersect(ray Ray) Hit {
return NoHit
}

func (f *Function) Paths3() Paths {
// Spiral
func SpiralPaths(f *Function) Paths {
var path Path
n := 10000
for i := 0; i < n; i++ {
Expand All @@ -59,11 +65,11 @@ func (f *Function) Paths3() Paths {
z = math.Max(z, f.Box.Min.Z)
path = append(path, Vector{x, y, z})
}
// return append(f.Paths2(), path)
return Paths{path}
}

func (f *Function) Paths() Paths {
// Radial
func RadialPaths(f *Function) Paths {
var paths Paths
fine := 1.0 / 256
for a := 0; a < 360; a += 5 {
Expand All @@ -84,7 +90,8 @@ func (f *Function) Paths() Paths {
return paths
}

func (f *Function) Paths1() Paths {
// Square grid
func GridPaths(f *Function) Paths {
var paths Paths
step := 1.0 / 8
fine := 1.0 / 64
Expand All @@ -110,3 +117,58 @@ func (f *Function) Paths1() Paths {
}
return paths
}

// Wavy Spiral
func WavySpiralPaths(f *Function) Paths {
var path Path
n := 50000
for i := 0; i < n; i++ {
t := float64(i) / float64(n)
angle := Radians(t*2*math.Pi*3000)

cos := math.Cos(angle)
sin := math.Sin(angle)

pow := math.Pow(t, 0.1)

wave_angle := angle * 100 * (1-math.Pow(t,0.99))
wave := math.Cos(wave_angle) * 0.1 * (1-pow)

r := 8 - pow*(8 + wave)

x := cos * r
y := sin * r

z := f.Function(x, y)
z = math.Min(z, f.Box.Max.Z)
z = math.Max(z, f.Box.Min.Z)
path = append(path, Vector{x, y, z})
}
return Paths{path}
}

func NewSpiralFunction(function func(x, y float64) float64, box Box, direction Direction) Shape {
return NewFunction(function, box, direction, SpiralPaths)
}

func NewRadialFunction(function func(x, y float64) float64, box Box, direction Direction) Shape {
return NewFunction(function, box, direction, RadialPaths)
}

func NewGridFunction(function func(x, y float64) float64, box Box, direction Direction) Shape {
return NewFunction(function, box, direction, GridPaths)
}

func NewWavySpiralFunction(function func(x, y float64) float64, box Box, direction Direction) Shape {
return NewFunction(function, box, direction, WavySpiralPaths)
}

// Double spirals
func DoubleSpiralsPaths(f *Function) Paths {
return append(SpiralPaths(f), RadialPaths(f)...)
}

func NewDoubleSpiralsFunction(function func(x, y float64) float64, box Box, direction Direction) Shape {
return NewFunction(function, box, direction, DoubleSpiralsPaths)
}

47 changes: 43 additions & 4 deletions ln/sphere.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,13 @@ func (s *Sphere) Intersect(r Ray) Hit {
return NoHit
}

func (s *Sphere) Paths4() Paths {
func seedRandomWithPos(s *Sphere) {
SeedRandomWithVector(&s.Center)
}

func (s *Sphere) RandomCirclesPaths() Paths {
var paths Paths
seedRandomWithPos(s)
var seen []Vector
var radii []float64
for i := 0; i < 140; i++ {
Expand Down Expand Up @@ -94,8 +99,9 @@ func (s *Sphere) Paths4() Paths {
return paths
}

func (s *Sphere) Paths3() Paths {
func (s *Sphere) RandomDotsPaths() Paths {
var paths Paths
seedRandomWithPos(s)
for i := 0; i < 20000; i++ {
v := RandomUnitVector()
v = v.MulScalar(s.Radius).Add(s.Center)
Expand All @@ -104,13 +110,14 @@ func (s *Sphere) Paths3() Paths {
return paths
}

func (s *Sphere) Paths2() Paths {
func (s *Sphere) RandomEquatorsPaths() Paths {
var equator Path
for lng := 0; lng <= 360; lng++ {
v := LatLngToXYZ(0, float64(lng), s.Radius)
equator = append(equator, v)
}
var paths Paths
seedRandomWithPos(s)
for i := 0; i < 100; i++ {
m := Identity()
for j := 0; j < 3; j++ {
Expand All @@ -123,7 +130,34 @@ func (s *Sphere) Paths2() Paths {
return paths
}

func (s *Sphere) Paths() Paths {
func (s *Sphere) RandomWavyEquatorsPaths() Paths {
var equator Path
sublng := 10
invsublng := 1. / float64(sublng)
wave_count := 50.
wave_amplitude := 5.
for lng10 := 0; lng10 <= 360 * sublng; lng10++ {
lng := float64(lng10) * invsublng
wave_angle := Radians(lng * wave_count)
wave := math.Cos(wave_angle) * wave_amplitude
v := LatLngToXYZ(wave, lng, s.Radius)
equator = append(equator, v)
}
var paths Paths
seedRandomWithPos(s)
for i := 0; i < 10; i++ {
m := Identity()
for j := 0; j < 3; j++ {
v := RandomUnitVector()
m = m.Rotate(v, rand.Float64()*2*math.Pi)
}
m = m.Translate(s.Center)
paths = append(paths, equator.Transform(m))
}
return paths
}

func (s *Sphere) LonLatPaths() Paths {
var paths Paths
n := 10
o := 10
Expand All @@ -146,6 +180,11 @@ func (s *Sphere) Paths() Paths {
return paths
}

func (s *Sphere) Paths() Paths {
return s.RandomWavyEquatorsPaths()
}


func LatLngToXYZ(lat, lng, radius float64) Vector {
lat, lng = Radians(lat), Radians(lng)
x := radius * math.Cos(lat) * math.Cos(lng)
Expand Down
10 changes: 9 additions & 1 deletion ln/vector.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,20 @@ type Vector struct {
X, Y, Z float64
}

func SeedRandomWithVector(v *Vector) {
rand.Seed(int64(
math.Float64bits(v.X) ^
math.Float64bits(v.Y) ^
math.Float64bits(v.Z) ^
uint64(0x7912457717875691) / 4))
}

func RandomUnitVector() Vector {
for {
x := rand.Float64()*2 - 1
y := rand.Float64()*2 - 1
z := rand.Float64()*2 - 1
if x*x+y*y+z*z > 1 {
if x == 0 && y == 0 && z == 0 {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this change would result in some bias in the random vectors.

continue
}
return Vector{x, y, z}.Normalize()
Expand Down