Решение на Пресичания от Ива Милушева

Обратно към всички решения

Към профила на Ива Милушева

Резултати

  • 7 точки от тестове
  • 0 бонус точки
  • 7 точки общо
  • 14 успешни тест(а)
  • 6 неуспешни тест(а)

Код

package main
import "github.com/fmi/go-homework/geom"
import "math"
type Vector struct {
X, Y, Z float64
}
type Ray struct {
Origin Vector
Direction Vector
}
type Intersectable interface {
Intersect(ray Ray) bool
}
type Triangle struct {
a, b, c geom.Vector
}
type Sphere struct {
radius float64
origin geom.Vector
}
type Quad struct {
a, b, c, d geom.Vector
}
func NewTriangle(a, b, c geom.Vector) Triangle {
if geom.Len(a)+geom.Len(b) > geom.Len(c) && geom.Len(b)+geom.Len(c) > geom.Len(a) && geom.Len(a)+geom.Len(c) > geom.Len(b) {
return Triangle{a, b, c}
} else {
return Triangle{geom.NewVector(0, 0, 0), geom.NewVector(0, 0, 0), geom.NewVector(0, 0, 0)}
}
}
func NewQuad(a, b, c, d geom.Vector) Quad {
return Quad{a, b, c, d}
}
func NewSphere(origin geom.Vector, r float64) Sphere {
return Sphere{r, origin}
}
func (tr Triangle) Intersect(ray geom.Ray) bool {
var n geom.Vector
originNorm := geom.NewVector(0, 0, 0)
n = geom.Cross(geom.Sub(tr.b, tr.a), geom.Sub(tr.c, tr.a))
d := math.Abs(geom.Dot(n, geom.NewVector(ray.Direction.X, ray.Direction.Y, ray.Direction.Z)))
if d > 0.0000001 {
t := geom.Dot(geom.Sub(originNorm, geom.NewVector(ray.Origin.X, ray.Origin.Y, ray.Origin.Z)), n) / d
return (t >= 0)
} else {
return false
}
}
func (s Sphere) Intersect(ray geom.Ray) bool {
area := NewTriangle(geom.NewVector(s.radius, 0, 0), geom.NewVector(0, s.radius, 0), geom.NewVector(0, 0, s.radius))
secondarea := NewTriangle(geom.NewVector(s.radius, s.radius, 0), geom.NewVector(0, s.radius, s.radius), geom.NewVector(s.radius, 0, s.radius))
n := geom.Cross(geom.Sub(area.b, area.a), geom.Sub(area.c, area.a))
p := geom.Cross(geom.Sub(secondarea.b, secondarea.a), geom.Sub(secondarea.c, secondarea.a))
tvalue := geom.Dot(geom.Sub(ray.Origin, ray.Origin), n) / geom.Dot(ray.Direction, n)
tsecvalue := geom.Dot(geom.Sub(ray.Origin, ray.Origin), p) / geom.Dot(ray.Direction, p)
if area.Intersect(ray) {
vect := geom.Sub(geom.Add(ray.Origin, geom.Mul(ray.Direction, tvalue)), ray.Origin)
return (math.Sqrt(geom.Dot(vect, vect)) <= s.radius)
} else if secondarea.Intersect(ray) {
vect := geom.Sub(geom.Add(ray.Origin, geom.Mul(ray.Direction, tsecvalue)), ray.Origin)
return (math.Sqrt(geom.Dot(vect, vect)) <= s.radius)
} else {
return false
}
}
func (q Quad) Intersect(ray geom.Ray) bool {
triangle := NewTriangle(q.a, q.b, q.c)
opositeTriangle := NewTriangle(q.b, q.c, q.d)
if triangle.Intersect(ray) || opositeTriangle.Intersect(ray) {
return true
} else {
return false
}
}

Лог от изпълнението

PASS
ok  	_/tmp/d20181122-57-1mjenmd	0.002s
--- FAIL: TestTriangleNoBackFaceCulling (0.00s)
    solution_test.go:206: Expected intersection to be true but it was not
FAIL
exit status 1
FAIL	_/tmp/d20181122-57-1mjenmd	0.002s
PASS
ok  	_/tmp/d20181122-57-1mjenmd	0.002s
PASS
ok  	_/tmp/d20181122-57-1mjenmd	0.002s
PASS
ok  	_/tmp/d20181122-57-1mjenmd	0.002s
PASS
ok  	_/tmp/d20181122-57-1mjenmd	0.002s
PASS
ok  	_/tmp/d20181122-57-1mjenmd	0.002s
--- FAIL: TestQuadNoBackFaceCulling (0.00s)
    solution_test.go:206: Expected intersection to be true but it was not
FAIL
exit status 1
FAIL	_/tmp/d20181122-57-1mjenmd	0.002s
PASS
ok  	_/tmp/d20181122-57-1mjenmd	0.002s
PASS
ok  	_/tmp/d20181122-57-1mjenmd	0.002s
PASS
ok  	_/tmp/d20181122-57-1mjenmd	0.002s
PASS
ok  	_/tmp/d20181122-57-1mjenmd	0.002s
--- FAIL: TestQuadIrregularHit (0.00s)
    solution_test.go:206: Expected intersection to be true but it was not
FAIL
exit status 1
FAIL	_/tmp/d20181122-57-1mjenmd	0.002s
PASS
ok  	_/tmp/d20181122-57-1mjenmd	0.002s
PASS
ok  	_/tmp/d20181122-57-1mjenmd	0.002s
PASS
ok  	_/tmp/d20181122-57-1mjenmd	0.002s
PASS
ok  	_/tmp/d20181122-57-1mjenmd	0.002s
--- FAIL: TestSphereNoBackFaceCulling (0.00s)
    solution_test.go:206: Expected intersection to be true but it was not
FAIL
exit status 1
FAIL	_/tmp/d20181122-57-1mjenmd	0.002s
--- FAIL: TestSphereRayOppositeDirection (0.00s)
    solution_test.go:206: Expected intersection to be false but it was not
FAIL
exit status 1
FAIL	_/tmp/d20181122-57-1mjenmd	0.002s
--- FAIL: TestSphereNearMiss (0.00s)
    solution_test.go:206: Expected intersection to be false but it was not
FAIL
exit status 1
FAIL	_/tmp/d20181122-57-1mjenmd	0.002s

История (1 версия и 0 коментара)

Ива обнови решението на 21.11.2018 14:01 (преди 9 месеца)

+package main
+
+import "github.com/fmi/go-homework/geom"
+import "math"
+
+type Vector struct {
+ X, Y, Z float64
+}
+
+type Ray struct {
+ Origin Vector
+ Direction Vector
+}
+
+type Intersectable interface {
+ Intersect(ray Ray) bool
+}
+
+type Triangle struct {
+ a, b, c geom.Vector
+}
+type Sphere struct {
+ radius float64
+ origin geom.Vector
+}
+
+type Quad struct {
+ a, b, c, d geom.Vector
+}
+
+func NewTriangle(a, b, c geom.Vector) Triangle {
+ if geom.Len(a)+geom.Len(b) > geom.Len(c) && geom.Len(b)+geom.Len(c) > geom.Len(a) && geom.Len(a)+geom.Len(c) > geom.Len(b) {
+ return Triangle{a, b, c}
+ } else {
+ return Triangle{geom.NewVector(0, 0, 0), geom.NewVector(0, 0, 0), geom.NewVector(0, 0, 0)}
+ }
+}
+
+func NewQuad(a, b, c, d geom.Vector) Quad {
+ return Quad{a, b, c, d}
+}
+
+func NewSphere(origin geom.Vector, r float64) Sphere {
+ return Sphere{r, origin}
+}
+
+func (tr Triangle) Intersect(ray geom.Ray) bool {
+ var n geom.Vector
+ originNorm := geom.NewVector(0, 0, 0)
+
+ n = geom.Cross(geom.Sub(tr.b, tr.a), geom.Sub(tr.c, tr.a))
+ d := math.Abs(geom.Dot(n, geom.NewVector(ray.Direction.X, ray.Direction.Y, ray.Direction.Z)))
+
+ if d > 0.0000001 {
+ t := geom.Dot(geom.Sub(originNorm, geom.NewVector(ray.Origin.X, ray.Origin.Y, ray.Origin.Z)), n) / d
+ return (t >= 0)
+ } else {
+ return false
+ }
+}
+
+
+func (s Sphere) Intersect(ray geom.Ray) bool {
+ area := NewTriangle(geom.NewVector(s.radius, 0, 0), geom.NewVector(0, s.radius, 0), geom.NewVector(0, 0, s.radius))
+ secondarea := NewTriangle(geom.NewVector(s.radius, s.radius, 0), geom.NewVector(0, s.radius, s.radius), geom.NewVector(s.radius, 0, s.radius))
+
+ n := geom.Cross(geom.Sub(area.b, area.a), geom.Sub(area.c, area.a))
+ p := geom.Cross(geom.Sub(secondarea.b, secondarea.a), geom.Sub(secondarea.c, secondarea.a))
+
+ tvalue := geom.Dot(geom.Sub(ray.Origin, ray.Origin), n) / geom.Dot(ray.Direction, n)
+ tsecvalue := geom.Dot(geom.Sub(ray.Origin, ray.Origin), p) / geom.Dot(ray.Direction, p)
+
+ if area.Intersect(ray) {
+ vect := geom.Sub(geom.Add(ray.Origin, geom.Mul(ray.Direction, tvalue)), ray.Origin)
+ return (math.Sqrt(geom.Dot(vect, vect)) <= s.radius)
+ } else if secondarea.Intersect(ray) {
+ vect := geom.Sub(geom.Add(ray.Origin, geom.Mul(ray.Direction, tsecvalue)), ray.Origin)
+ return (math.Sqrt(geom.Dot(vect, vect)) <= s.radius)
+ } else {
+ return false
+ }
+}
+
+func (q Quad) Intersect(ray geom.Ray) bool {
+ triangle := NewTriangle(q.a, q.b, q.c)
+ opositeTriangle := NewTriangle(q.b, q.c, q.d)
+ if triangle.Intersect(ray) || opositeTriangle.Intersect(ray) {
+ return true
+ } else {
+ return false
+ }
+}