Browse Source

feat: простой поиск пересечения луча с фигурой

master
exepirit 8 months ago
parent
commit
17c2add23a
Signed by: exepirit GPG Key ID: 7F96A965465257B9
  1. 22
      cmd/sphere/main.go
  2. 51
      pkg/sdf/geometry.go
  3. 5
      pkg/sdf/interfaces.go
  4. 10
      pkg/sdf/primitives.go
  5. 30
      pkg/sdf/sdf.go

22
cmd/sphere/main.go

@ -0,0 +1,22 @@
package main
import (
"fmt"
"git.0x73.ru/exepirit/sdf/pkg/sdf"
)
func main() {
sphere := sdf.Sphere{
Center: sdf.NewVector3(0, 5, 0),
Radius: 1.0,
}
scene := sdf.Min(sphere.Distance)
ray := sdf.NewRay(sdf.NewVector3(0, 0, 0), sdf.NewVector3(0, 1, 0))
point, intersect := sdf.GetIntersection(ray, scene)
if intersect {
fmt.Printf("%#v\n", point)
} else {
fmt.Println("No intersection")
}
}

51
pkg/sdf/geometry.go

@ -0,0 +1,51 @@
package sdf
import "math"
type Vector3 struct {
x, y, z float64
}
func NewVector3(x, y, z float64) Vector3 {
return Vector3{x, y, z}
}
func (v Vector3) X() float64 {
return v.x
}
func (v Vector3) Y() float64 {
return v.y
}
func (v Vector3) Z() float64 {
return v.z
}
func (v Vector3) Add(v2 Vector3) Vector3 {
return Vector3{
x: v2.x + v.x,
y: v2.y + v.y,
z: v2.z + v.z,
}
}
func (v Vector3) Subtract(v2 Vector3) Vector3 {
return Vector3{v2.x - v.x, v2.y - v.y, v2.z - v.z}
}
func (v Vector3) Multiply(k float64) Vector3 {
return Vector3{v.x * k, v.y * k, v.z * k}
}
func (v Vector3) Mod() float64 {
return math.Sqrt(math.Pow(v.x, 2) + math.Pow(v.y, 2) + math.Pow(v.z, 2))
}
type Ray struct {
origin, dir Vector3
}
func NewRay(origin, direction Vector3) Ray {
return Ray{origin: origin, dir: direction}
}

5
pkg/sdf/interfaces.go

@ -0,0 +1,5 @@
package sdf
type Figure interface {
Distance(p Vector3) float64
}

10
pkg/sdf/primitives.go

@ -0,0 +1,10 @@
package sdf
type Sphere struct {
Center Vector3
Radius float64
}
func (sphere Sphere) Distance(p Vector3) float64 {
return sphere.Center.Subtract(p).Mod() - sphere.Radius
}

30
pkg/sdf/sdf.go

@ -0,0 +1,30 @@
package sdf
import "math"
const (
minDistance = 1e-3
maxDistance = 1e3
shiftCoefficient = 0.5
)
type SDF func(p Vector3) float64
func Min(functions ...SDF) SDF {
return func(p Vector3) float64 {
dist := -math.MaxFloat64
for _, sdf := range functions {
dist = math.Max(sdf(p), dist)
}
return dist
}
}
func GetIntersection(ray Ray, sdf SDF) (Vector3, bool) {
dist := sdf(ray.origin)
for dist > minDistance && dist < maxDistance {
ray.origin = ray.origin.Add(ray.dir.Multiply(dist * shiftCoefficient))
dist = sdf(ray.origin)
}
return ray.origin, dist < maxDistance
}
Loading…
Cancel
Save