Решение на Пресичания от Даяна Веселинова

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

Към профила на Даяна Веселинова

Резултати

  • 8 точки от тестове
  • 0 бонус точки
  • 8 точки общо
  • 15 успешни тест(а)
  • 5 неуспешни тест(а)

Код

package main
import (
"github.com/fmi/go-homework/geom"
"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 float64
a, b, c geom.Vector
}
type Sphere struct {
rad float64
origin geom.Vector
}
type Quad struct {
tr, tr2 Triangle
a, b, c, d geom.Vector
}
func NewTriangle(a, b, c geom.Vector) Triangle {
var sideA = math.Sqrt(math.Pow((c.X-b.X), 2) + math.Pow((c.Y-b.Y), 2) + math.Pow((c.Z-b.Z), 2))
var sideB = math.Sqrt(math.Pow((a.X-b.X), 2) + math.Pow((a.Y-b.Y), 2) + math.Pow((a.Z-b.Z), 2))
var sideC = math.Sqrt(math.Pow((a.X-c.X), 2) + math.Pow((a.Y-c.Y), 2) + math.Pow((a.Z-c.Z), 2))
if sideA+sideB > sideC && sideB+sideC > sideA && sideA+sideC > sideB {
return Triangle{sideA, sideB, sideC, a, b, c}
}
return Triangle{0, 0, 0, geom.NewVector(0, 0, 0), geom.NewVector(0, 0, 0), geom.NewVector(0, 0, 0)}
}
func NewQuad(a, b, c, d geom.Vector) Quad {
tr := NewTriangle(a, b, c)
tr2 := NewTriangle(a, b, d)
return Quad{tr, tr2, 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 norm geom.Vector
originNorm := geom.NewVector(0, 0, 0)
norm = geom.Cross(geom.Sub(tr.b, tr.a), geom.Sub(tr.c, tr.a))
dir := geom.NewVector(ray.Direction.X, ray.Direction.Y, ray.Direction.Z)
origin := geom.NewVector(ray.Origin.X, ray.Origin.Y, ray.Origin.Z)
denom := math.Abs(geom.Dot(norm, dir))
if denom > 1e-7 {
t := geom.Dot(geom.Sub(originNorm, origin), norm) / denom
return (t >= 0)
}
return false
}
func (qu Quad) Intersect(ray geom.Ray) bool {
if qu.tr.Intersect(ray) || qu.tr2.Intersect(ray) {
return true
}
return false
}
func (sp Sphere) Intersect(ray geom.Ray) bool {
originNorm := ray.Origin
tr := NewTriangle(geom.NewVector(sp.rad, 0, 0), geom.NewVector(0, sp.rad, 0), geom.NewVector(0, 0, sp.rad))
tr2 := NewTriangle(geom.NewVector(sp.rad, sp.rad, 0), geom.NewVector(0, sp.rad, sp.rad), geom.NewVector(sp.rad, 0, sp.rad))
norm := geom.Cross(geom.Sub(tr.b, tr.a), geom.Sub(tr.c, tr.a))
norm2 := geom.Cross(geom.Sub(tr2.b, tr2.a), geom.Sub(tr2.c, tr2.a))
t := geom.Dot(geom.Sub(originNorm, ray.Origin), norm) / geom.Dot(ray.Direction, norm)
t2 := geom.Dot(geom.Sub(originNorm, ray.Origin), norm2) / geom.Dot(ray.Direction, norm2)
if tr.Intersect(ray) {
newVec := geom.Sub(geom.Add(ray.Origin, geom.Mul(ray.Direction, t)), originNorm)
return (math.Sqrt(geom.Dot(newVec, newVec)) <= sp.rad)
} else if tr2.Intersect(ray) {
newVec := geom.Sub(geom.Add(ray.Origin, geom.Mul(ray.Direction, t2)), originNorm)
return (math.Sqrt(geom.Dot(newVec, newVec)) <= sp.rad)
}
return false
}

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

PASS
ok  	_/tmp/d20181122-57-1m7bbye	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-1m7bbye	0.002s
PASS
ok  	_/tmp/d20181122-57-1m7bbye	0.003s
PASS
ok  	_/tmp/d20181122-57-1m7bbye	0.002s
PASS
ok  	_/tmp/d20181122-57-1m7bbye	0.002s
PASS
ok  	_/tmp/d20181122-57-1m7bbye	0.002s
PASS
ok  	_/tmp/d20181122-57-1m7bbye	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-1m7bbye	0.002s
PASS
ok  	_/tmp/d20181122-57-1m7bbye	0.002s
PASS
ok  	_/tmp/d20181122-57-1m7bbye	0.002s
PASS
ok  	_/tmp/d20181122-57-1m7bbye	0.002s
PASS
ok  	_/tmp/d20181122-57-1m7bbye	0.002s
PASS
ok  	_/tmp/d20181122-57-1m7bbye	0.002s
PASS
ok  	_/tmp/d20181122-57-1m7bbye	0.002s
PASS
ok  	_/tmp/d20181122-57-1m7bbye	0.002s
PASS
ok  	_/tmp/d20181122-57-1m7bbye	0.002s
PASS
ok  	_/tmp/d20181122-57-1m7bbye	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-1m7bbye	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-1m7bbye	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-1m7bbye	0.002s

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

Даяна обнови решението на 21.11.2018 09:29 (преди 9 месеца)

+package main
+
+import (
+ "github.com/fmi/go-homework/geom"
+ "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 float64
+ a, b, c geom.Vector
+}
+
+type Sphere struct {
+ rad float64
+ origin geom.Vector
+}
+
+type Quad struct {
+ tr, tr2 Triangle
+ a, b, c, d geom.Vector
+}
+
+func NewTriangle(a, b, c geom.Vector) Triangle {
+ var sideA = math.Sqrt(math.Pow((c.X-b.X), 2) + math.Pow((c.Y-b.Y), 2) + math.Pow((c.Z-b.Z), 2))
+ var sideB = math.Sqrt(math.Pow((a.X-b.X), 2) + math.Pow((a.Y-b.Y), 2) + math.Pow((a.Z-b.Z), 2))
+ var sideC = math.Sqrt(math.Pow((a.X-c.X), 2) + math.Pow((a.Y-c.Y), 2) + math.Pow((a.Z-c.Z), 2))
+
+ if sideA+sideB > sideC && sideB+sideC > sideA && sideA+sideC > sideB {
+ return Triangle{sideA, sideB, sideC, a, b, c}
+ }
+
+ return Triangle{0, 0, 0, geom.NewVector(0, 0, 0), geom.NewVector(0, 0, 0), geom.NewVector(0, 0, 0)}
+}
+
+func NewQuad(a, b, c, d geom.Vector) Quad {
+ tr := NewTriangle(a, b, c)
+ tr2 := NewTriangle(a, b, d)
+
+ return Quad{tr, tr2, 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 norm geom.Vector
+ originNorm := geom.NewVector(0, 0, 0)
+ norm = geom.Cross(geom.Sub(tr.b, tr.a), geom.Sub(tr.c, tr.a))
+ dir := geom.NewVector(ray.Direction.X, ray.Direction.Y, ray.Direction.Z)
+ origin := geom.NewVector(ray.Origin.X, ray.Origin.Y, ray.Origin.Z)
+
+ denom := geom.Dot(norm, dir)
+
+ if denom > 1e-7 {
+ t := geom.Dot(geom.Sub(originNorm, origin), norm) / denom
+ return (t >= 0)
+ }
+
+ return false
+
+}
+
+func (qu Quad) Intersect(ray geom.Ray) bool {
+ if qu.tr.Intersect(ray) || qu.tr2.Intersect(ray) {
+ return true
+ }
+
+ return false
+}
+
+func (sp Sphere) Intersect(ray geom.Ray) bool {
+ originNorm := ray.Origin
+ tr := NewTriangle(geom.NewVector(sp.rad, 0, 0), geom.NewVector(0, sp.rad, 0), geom.NewVector(0, 0, sp.rad))
+ tr2 := NewTriangle(geom.NewVector(sp.rad, sp.rad, 0), geom.NewVector(0, sp.rad, sp.rad), geom.NewVector(sp.rad, 0, sp.rad))
+ norm := geom.Cross(geom.Sub(tr.b, tr.a), geom.Sub(tr.c, tr.a))
+ norm2 := geom.Cross(geom.Sub(tr2.b, tr2.a), geom.Sub(tr2.c, tr2.a))
+ t := geom.Dot(geom.Sub(originNorm, ray.Origin), norm) / geom.Dot(ray.Direction, norm)
+ t2 := geom.Dot(geom.Sub(originNorm, ray.Origin), norm2) / geom.Dot(ray.Direction, norm2)
+
+ if tr.Intersect(ray) {
+ newVec := geom.Sub(geom.Add(ray.Origin, geom.Mul(ray.Direction, t)), originNorm)
+ return (math.Sqrt(geom.Dot(newVec, newVec)) <= sp.rad)
+ } else if tr2.Intersect(ray) {
+ newVec := geom.Sub(geom.Add(ray.Origin, geom.Mul(ray.Direction, t2)), originNorm)
+ return (math.Sqrt(geom.Dot(newVec, newVec)) <= sp.rad)
+ }
+
+ return false
+}

Даяна обнови решението на 21.11.2018 12:33 (преди 9 месеца)

package main
import (
"github.com/fmi/go-homework/geom"
"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 float64
a, b, c geom.Vector
}
type Sphere struct {
rad float64
origin geom.Vector
}
type Quad struct {
tr, tr2 Triangle
a, b, c, d geom.Vector
}
func NewTriangle(a, b, c geom.Vector) Triangle {
var sideA = math.Sqrt(math.Pow((c.X-b.X), 2) + math.Pow((c.Y-b.Y), 2) + math.Pow((c.Z-b.Z), 2))
var sideB = math.Sqrt(math.Pow((a.X-b.X), 2) + math.Pow((a.Y-b.Y), 2) + math.Pow((a.Z-b.Z), 2))
var sideC = math.Sqrt(math.Pow((a.X-c.X), 2) + math.Pow((a.Y-c.Y), 2) + math.Pow((a.Z-c.Z), 2))
if sideA+sideB > sideC && sideB+sideC > sideA && sideA+sideC > sideB {
return Triangle{sideA, sideB, sideC, a, b, c}
}
return Triangle{0, 0, 0, geom.NewVector(0, 0, 0), geom.NewVector(0, 0, 0), geom.NewVector(0, 0, 0)}
}
func NewQuad(a, b, c, d geom.Vector) Quad {
tr := NewTriangle(a, b, c)
tr2 := NewTriangle(a, b, d)
return Quad{tr, tr2, 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 norm geom.Vector
originNorm := geom.NewVector(0, 0, 0)
norm = geom.Cross(geom.Sub(tr.b, tr.a), geom.Sub(tr.c, tr.a))
dir := geom.NewVector(ray.Direction.X, ray.Direction.Y, ray.Direction.Z)
origin := geom.NewVector(ray.Origin.X, ray.Origin.Y, ray.Origin.Z)
- denom := geom.Dot(norm, dir)
+ denom := math.Abs(geom.Dot(norm, dir))
if denom > 1e-7 {
t := geom.Dot(geom.Sub(originNorm, origin), norm) / denom
return (t >= 0)
}
return false
}
func (qu Quad) Intersect(ray geom.Ray) bool {
if qu.tr.Intersect(ray) || qu.tr2.Intersect(ray) {
return true
}
return false
}
func (sp Sphere) Intersect(ray geom.Ray) bool {
originNorm := ray.Origin
tr := NewTriangle(geom.NewVector(sp.rad, 0, 0), geom.NewVector(0, sp.rad, 0), geom.NewVector(0, 0, sp.rad))
tr2 := NewTriangle(geom.NewVector(sp.rad, sp.rad, 0), geom.NewVector(0, sp.rad, sp.rad), geom.NewVector(sp.rad, 0, sp.rad))
norm := geom.Cross(geom.Sub(tr.b, tr.a), geom.Sub(tr.c, tr.a))
norm2 := geom.Cross(geom.Sub(tr2.b, tr2.a), geom.Sub(tr2.c, tr2.a))
t := geom.Dot(geom.Sub(originNorm, ray.Origin), norm) / geom.Dot(ray.Direction, norm)
t2 := geom.Dot(geom.Sub(originNorm, ray.Origin), norm2) / geom.Dot(ray.Direction, norm2)
if tr.Intersect(ray) {
newVec := geom.Sub(geom.Add(ray.Origin, geom.Mul(ray.Direction, t)), originNorm)
return (math.Sqrt(geom.Dot(newVec, newVec)) <= sp.rad)
} else if tr2.Intersect(ray) {
newVec := geom.Sub(geom.Add(ray.Origin, geom.Mul(ray.Direction, t2)), originNorm)
return (math.Sqrt(geom.Dot(newVec, newVec)) <= sp.rad)
}
return false
}