Решение на Пресичания от Красена Давидова

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

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

Резултати

  • 10 точки от тестове
  • 1 отнета точка
  • 9 точки общо
  • 19 успешни тест(а)
  • 1 неуспешни тест(а)

Код

package main
import (
"github.com/fmi/go-homework/geom"
"math"
)
type Triangle struct {
a, b, c geom.Vector
}
type Sphere struct {
centre geom.Vector
radius float64
}
type Quad struct {
a, b, c, d geom.Vector
}
func NewTriangle(x, y, z geom.Vector) Triangle {
return Triangle{a: x, b: y, c: z}
}
func NewSphere(origin geom.Vector, r float64) Sphere {
return Sphere{centre: origin, radius: r}
}
func NewQuad(x, y, z, t geom.Vector) Quad {
return Quad{a: x, b: y, c: z, d: t}
}
func vectorsTri(t Triangle, c chan<- geom.Vector) {
defer close(c)
ab := vectorOp(t.a, t.b, func(x, y float64) float64 { return y - x })
ac := vectorOp(t.a, t.c, func(x, y float64) float64 { return y - x })
bc := vectorOp(t.b, t.c, func(x, y float64) float64 { return y - x })
ca := vectorOp(t.c, t.a, func(x, y float64) float64 { return y - x })
c <- ab
c <- ac
c <- bc
c <- ca
}
func (t Triangle) Intersect(ray geom.Ray) bool {
channel := make(chan geom.Vector, 4)
go vectorsTri(t, channel)
ab, ac, bc, ca := <-channel, <-channel, <-channel, <-channel
norm := crossProd(ab, ac)
sqrtNorm := math.Sqrt(vectorSum(vectorOp(norm, norm, func(x, y float64) float64 { return x * y })))
norm = geom.NewVector(norm.X/sqrtNorm, norm.Y/sqrtNorm, norm.Z/sqrtNorm)
d := vectorSum(vectorOp(norm, t.a, func(x, y float64) float64 { return x * y }))
normDir := vectorSum(vectorOp(norm, ray.Direction, func(x, y float64) float64 { return x * y }))
normOr := vectorSum(vectorOp(norm, ray.Origin, func(x, y float64) float64 { return x * y }))
if normDir == 0 { // ray is parallel to the plane
return false
}
solv := (d - normOr) / normDir
if solv < 0 {
return false
}
inPnt := vectorOp(ray.Origin, ray.Direction, func(x, y float64) float64 {
return func(p float64) float64 {
return x + y*p
}(solv)
})
ainPnt := vectorOp(t.a, inPnt, func(x, y float64) float64 { return y - x })
binPnt := vectorOp(t.b, inPnt, func(x, y float64) float64 { return y - x })
cinPnt := vectorOp(t.c, inPnt, func(x, y float64) float64 { return y - x })
condAB := vectorSum(vectorOp(crossProd(ab, ainPnt), norm, func(x, y float64) float64 { return x * y }))
condBC := vectorSum(vectorOp(crossProd(bc, binPnt), norm, func(x, y float64) float64 { return x * y }))
condCA := vectorSum(vectorOp(crossProd(ca, cinPnt), norm, func(x, y float64) float64 { return x * y }))
if condAB >= 0 && condBC >= 0 && condCA >= 0 {
return true
} else {
return false
}
}
func (s Sphere) Intersect(ray geom.Ray) bool {
oc := vectorOp(ray.Origin, s.centre, func(x, y float64) float64 { return y - x })
c := vectorSum(vectorOp(oc, oc, func(x, y float64) float64 { return x * y })) - s.radius*s.radius
b := vectorSum(vectorOp(ray.Direction, oc, func(x, y float64) float64 { return x * y })) * 2
a := vectorSum(vectorOp(ray.Direction, ray.Direction, func(x, y float64) float64 { return x * y }))
d := b*b - 4*a*c
if d >= 0 {
return true
} else {
return false
}
}
func degree(x, y geom.Vector) float64 {
xy := vectorSum(vectorOp(x, y, func(x, y float64) float64 { return x * y }))
xd := math.Sqrt(vectorSum(vectorOp(x, x, func(x, y float64) float64 { return x * y })))
yd := math.Sqrt(vectorSum(vectorOp(y, y, func(x, y float64) float64 { return x * y })))
return math.Acos(xy/(xd*yd)) * 180 / math.Pi
}
func vectorsQuad(q Quad, c chan<- geom.Vector) {
defer close(c)
ba := vectorOp(q.b, q.a, func(x, y float64) float64 { return y - x })
bc := vectorOp(q.b, q.c, func(x, y float64) float64 { return y - x })
cb := vectorOp(q.c, q.b, func(x, y float64) float64 { return y - x })
cd := vectorOp(q.c, q.d, func(x, y float64) float64 { return y - x })
dc := vectorOp(q.d, q.c, func(x, y float64) float64 { return y - x })
da := vectorOp(q.d, q.a, func(x, y float64) float64 { return y - x })
ad := vectorOp(q.a, q.d, func(x, y float64) float64 { return y - x })
ab := vectorOp(q.a, q.b, func(x, y float64) float64 { return y - x })
c <- ba
c <- bc
c <- cb
c <- cd
c <- dc
c <- da
c <- ad
c <- ab
}
func (q Quad) Intersect(ray geom.Ray) bool {
channel := make(chan geom.Vector, 8)
go vectorsQuad(q, channel)
ba, bc, cb, cd, dc, da, ad, ab := <-channel, <-channel, <-channel, <-channel, <-channel, <-channel, <-channel, <-channel
a := degree(ad, ab)
b := degree(ba, bc)
c := degree(cb, cd)
d := degree(dc, da)
var fst, snd Triangle
if c >= 90 || a >= 90 {
fst = NewTriangle(q.a, q.b, q.c)
snd = NewTriangle(q.a, q.d, q.c)
} else if b >= 90 || d >= 90 {
fst = NewTriangle(q.a, q.b, q.d)
snd = NewTriangle(q.b, q.c, q.d)
}
if fst.Intersect(ray) || snd.Intersect(ray) {
return true
} else {
return false
}
}
func crossProd(fst, snd geom.Vector) geom.Vector {
return geom.NewVector(fst.Y*snd.Z-fst.Z*snd.Y, fst.Z*snd.X-fst.X*snd.Z, fst.X*snd.Y-fst.Y*snd.X)
}
func vectorOp(fst, snd geom.Vector, op func(x, y float64) float64) geom.Vector {
return geom.NewVector(op(fst.X, snd.X), op(fst.Y, snd.Y), op(fst.Z, snd.Z))
}
func vectorSum(fst geom.Vector) float64 {
return fst.X + fst.Y + fst.Z
}

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

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

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

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

+package main
+
+import (
+ "github.com/fmi/go-homework/geom"
+ "math"
+)
+
+type Triangle struct {
+ a, b, c geom.Vector
+}
+
+type Sphere struct {
+ centre geom.Vector
+ radius float64
+}
+
+type Quad struct {
+ a, b, c, d geom.Vector
+}
+
+func NewTriangle(x, y, z geom.Vector) Triangle {
+ return Triangle{a: x, b: y, c: z}
+}
+
+func NewSphere(origin geom.Vector, r float64) Sphere {
+ return Sphere{centre: origin, radius: r}
+}
+
+func NewQuad(x, y, z, t geom.Vector) Quad {
+ return Quad{a: x, b: y, c: z, d: t}
+}
+
+func vectorsTri(t Triangle, c chan<- geom.Vector) {
+ defer close(c)
+ ab := vectorOp(t.a, t.b, func(x, y float64) float64 { return y - x })
+ ac := vectorOp(t.a, t.c, func(x, y float64) float64 { return y - x })
+ bc := vectorOp(t.b, t.c, func(x, y float64) float64 { return y - x })
+ ca := vectorOp(t.c, t.a, func(x, y float64) float64 { return y - x })
+ c <- ab
+ c <- ac
+ c <- bc
+ c <- ca
+}
+
+func (t Triangle) Intersect(ray geom.Ray) bool {
+ channel := make(chan geom.Vector, 4)
+ go vectorsTri(t, channel)
+ ab, ac, bc, ca := <-channel, <-channel, <-channel, <-channel
+ norm := crossProd(ab, ac)
+ sqrtNorm := math.Sqrt(vectorSum(vectorOp(norm, norm, func(x, y float64) float64 { return x * y })))
+ norm = geom.NewVector(norm.X/sqrtNorm, norm.Y/sqrtNorm, norm.Z/sqrtNorm)
+ d := vectorSum(vectorOp(norm, t.a, func(x, y float64) float64 { return x * y }))
+ normDir := vectorSum(vectorOp(norm, ray.Direction, func(x, y float64) float64 { return x * y }))
+ normOr := vectorSum(vectorOp(norm, ray.Origin, func(x, y float64) float64 { return x * y }))
+ if normDir == 0 { // ray is parallel to the plane
+ return false
+ }
+ solv := (d - normOr) / normDir
+ inPnt := vectorOp(ray.Origin, ray.Direction, func(x, y float64) float64 {
+ return func(p float64) float64 {
+ return x + y*p
+ }(solv)
+ })
+ ainPnt := vectorOp(t.a, inPnt, func(x, y float64) float64 { return y - x })
+ binPnt := vectorOp(t.b, inPnt, func(x, y float64) float64 { return y - x })
+ cinPnt := vectorOp(t.c, inPnt, func(x, y float64) float64 { return y - x })
+ condAB := vectorSum(vectorOp(crossProd(ab, ainPnt), norm, func(x, y float64) float64 { return x * y }))
+ condBC := vectorSum(vectorOp(crossProd(bc, binPnt), norm, func(x, y float64) float64 { return x * y }))
+ condCA := vectorSum(vectorOp(crossProd(ca, cinPnt), norm, func(x, y float64) float64 { return x * y }))
+ if condAB >= 0 && condBC >= 0 && condCA >= 0 {
+ return true
+ } else {
+ return false
+ }
+}
+
+func (s Sphere) Intersect(ray geom.Ray) bool {
+ oc := vectorOp(ray.Origin, s.centre, func(x, y float64) float64 { return y - x })
+ c := vectorSum(vectorOp(oc, oc, func(x, y float64) float64 { return x * y })) - s.radius*s.radius
+ b := vectorSum(vectorOp(ray.Direction, oc, func(x, y float64) float64 { return x * y })) * 2
+ a := vectorSum(vectorOp(ray.Direction, ray.Direction, func(x, y float64) float64 { return x * y }))
+ d := b*b - 4*a*c
+ if d >= 0 {
+ return true
+ } else {
+ return false
+ }
+}
+
+func degree(x, y geom.Vector) float64 {
+ xy := vectorSum(vectorOp(x, y, func(x, y float64) float64 { return x * y }))
+ xd := math.Sqrt(vectorSum(vectorOp(x, x, func(x, y float64) float64 { return x * y })))
+ yd := math.Sqrt(vectorSum(vectorOp(y, y, func(x, y float64) float64 { return x * y })))
+ return math.Acos(xy/(xd*yd)) * 180 / math.Pi
+}
+
+func vectorsQuad(q Quad, c chan<- geom.Vector) {
+ defer close(c)
+ ba := vectorOp(q.b, q.a, func(x, y float64) float64 { return y - x })
+ bc := vectorOp(q.b, q.c, func(x, y float64) float64 { return y - x })
+ cb := vectorOp(q.c, q.b, func(x, y float64) float64 { return y - x })
+ cd := vectorOp(q.c, q.d, func(x, y float64) float64 { return y - x })
+ dc := vectorOp(q.d, q.c, func(x, y float64) float64 { return y - x })
+ da := vectorOp(q.d, q.a, func(x, y float64) float64 { return y - x })
+ ad := vectorOp(q.a, q.d, func(x, y float64) float64 { return y - x })
+ ab := vectorOp(q.a, q.b, func(x, y float64) float64 { return y - x })
+ c <- ba
+ c <- bc
+ c <- cb
+ c <- cd
+ c <- dc
+ c <- da
+ c <- ad
+ c <- ab
+
+}
+
+func (q Quad) Intersect(ray geom.Ray) bool {
+ channel := make(chan geom.Vector, 8)
+ go vectorsQuad(q, channel)
+ ba, bc, cb, cd, dc, da, ad, ab := <-channel, <-channel, <-channel, <-channel, <-channel, <-channel, <-channel, <-channel
+ a := degree(ad, ab)
+ b := degree(ba, bc)
+ c := degree(cb, cd)
+ d := degree(dc, da)
+ var fst, snd Triangle
+ if c >= 90 || a >= 90 {
+ fst = NewTriangle(q.a, q.b, q.c)
+ snd = NewTriangle(q.a, q.d, q.c)
+ } else if b >= 90 || d >= 90 {
+ fst = NewTriangle(q.a, q.b, q.d)
+ snd = NewTriangle(q.b, q.c, q.d)
+ }
+ if fst.Intersect(ray) || snd.Intersect(ray) {
+ return true
+ } else {
+ return false
+ }
+}
+
+func crossProd(fst, snd geom.Vector) geom.Vector {
+ return geom.NewVector(fst.Y*snd.Z-fst.Z*snd.Y, fst.Z*snd.X-fst.X*snd.Z, fst.X*snd.Y-fst.Y*snd.X)
+}
+
+func vectorOp(fst, snd geom.Vector, op func(x, y float64) float64) geom.Vector {
+ return geom.NewVector(op(fst.X, snd.X), op(fst.Y, snd.Y), op(fst.Z, snd.Z))
+}
+
+func vectorSum(fst geom.Vector) float64 {
+ return fst.X + fst.Y + fst.Z
+}

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

package main
import (
"github.com/fmi/go-homework/geom"
"math"
)
type Triangle struct {
a, b, c geom.Vector
}
type Sphere struct {
centre geom.Vector
radius float64
}
type Quad struct {
a, b, c, d geom.Vector
}
func NewTriangle(x, y, z geom.Vector) Triangle {
return Triangle{a: x, b: y, c: z}
}
func NewSphere(origin geom.Vector, r float64) Sphere {
return Sphere{centre: origin, radius: r}
}
func NewQuad(x, y, z, t geom.Vector) Quad {
return Quad{a: x, b: y, c: z, d: t}
}
func vectorsTri(t Triangle, c chan<- geom.Vector) {
defer close(c)
ab := vectorOp(t.a, t.b, func(x, y float64) float64 { return y - x })
ac := vectorOp(t.a, t.c, func(x, y float64) float64 { return y - x })
bc := vectorOp(t.b, t.c, func(x, y float64) float64 { return y - x })
ca := vectorOp(t.c, t.a, func(x, y float64) float64 { return y - x })
c <- ab
c <- ac
c <- bc
c <- ca
}
func (t Triangle) Intersect(ray geom.Ray) bool {
channel := make(chan geom.Vector, 4)
go vectorsTri(t, channel)
ab, ac, bc, ca := <-channel, <-channel, <-channel, <-channel
norm := crossProd(ab, ac)
sqrtNorm := math.Sqrt(vectorSum(vectorOp(norm, norm, func(x, y float64) float64 { return x * y })))
norm = geom.NewVector(norm.X/sqrtNorm, norm.Y/sqrtNorm, norm.Z/sqrtNorm)
d := vectorSum(vectorOp(norm, t.a, func(x, y float64) float64 { return x * y }))
normDir := vectorSum(vectorOp(norm, ray.Direction, func(x, y float64) float64 { return x * y }))
normOr := vectorSum(vectorOp(norm, ray.Origin, func(x, y float64) float64 { return x * y }))
if normDir == 0 { // ray is parallel to the plane
return false
}
solv := (d - normOr) / normDir
+ if solv < 0 {
+ return false
+ }
inPnt := vectorOp(ray.Origin, ray.Direction, func(x, y float64) float64 {
return func(p float64) float64 {
return x + y*p
}(solv)
})
ainPnt := vectorOp(t.a, inPnt, func(x, y float64) float64 { return y - x })
binPnt := vectorOp(t.b, inPnt, func(x, y float64) float64 { return y - x })
cinPnt := vectorOp(t.c, inPnt, func(x, y float64) float64 { return y - x })
condAB := vectorSum(vectorOp(crossProd(ab, ainPnt), norm, func(x, y float64) float64 { return x * y }))
condBC := vectorSum(vectorOp(crossProd(bc, binPnt), norm, func(x, y float64) float64 { return x * y }))
condCA := vectorSum(vectorOp(crossProd(ca, cinPnt), norm, func(x, y float64) float64 { return x * y }))
if condAB >= 0 && condBC >= 0 && condCA >= 0 {
return true
} else {
return false
}
}
func (s Sphere) Intersect(ray geom.Ray) bool {
oc := vectorOp(ray.Origin, s.centre, func(x, y float64) float64 { return y - x })
c := vectorSum(vectorOp(oc, oc, func(x, y float64) float64 { return x * y })) - s.radius*s.radius
b := vectorSum(vectorOp(ray.Direction, oc, func(x, y float64) float64 { return x * y })) * 2
a := vectorSum(vectorOp(ray.Direction, ray.Direction, func(x, y float64) float64 { return x * y }))
d := b*b - 4*a*c
if d >= 0 {
return true
} else {
return false
}
}
func degree(x, y geom.Vector) float64 {
xy := vectorSum(vectorOp(x, y, func(x, y float64) float64 { return x * y }))
xd := math.Sqrt(vectorSum(vectorOp(x, x, func(x, y float64) float64 { return x * y })))
yd := math.Sqrt(vectorSum(vectorOp(y, y, func(x, y float64) float64 { return x * y })))
return math.Acos(xy/(xd*yd)) * 180 / math.Pi
}
func vectorsQuad(q Quad, c chan<- geom.Vector) {
defer close(c)
ba := vectorOp(q.b, q.a, func(x, y float64) float64 { return y - x })
bc := vectorOp(q.b, q.c, func(x, y float64) float64 { return y - x })
cb := vectorOp(q.c, q.b, func(x, y float64) float64 { return y - x })
cd := vectorOp(q.c, q.d, func(x, y float64) float64 { return y - x })
dc := vectorOp(q.d, q.c, func(x, y float64) float64 { return y - x })
da := vectorOp(q.d, q.a, func(x, y float64) float64 { return y - x })
ad := vectorOp(q.a, q.d, func(x, y float64) float64 { return y - x })
ab := vectorOp(q.a, q.b, func(x, y float64) float64 { return y - x })
c <- ba
c <- bc
c <- cb
c <- cd
c <- dc
c <- da
c <- ad
c <- ab
}
func (q Quad) Intersect(ray geom.Ray) bool {
channel := make(chan geom.Vector, 8)
go vectorsQuad(q, channel)
ba, bc, cb, cd, dc, da, ad, ab := <-channel, <-channel, <-channel, <-channel, <-channel, <-channel, <-channel, <-channel
a := degree(ad, ab)
b := degree(ba, bc)
c := degree(cb, cd)
d := degree(dc, da)
var fst, snd Triangle
if c >= 90 || a >= 90 {
fst = NewTriangle(q.a, q.b, q.c)
snd = NewTriangle(q.a, q.d, q.c)
} else if b >= 90 || d >= 90 {
fst = NewTriangle(q.a, q.b, q.d)
snd = NewTriangle(q.b, q.c, q.d)
}
if fst.Intersect(ray) || snd.Intersect(ray) {
return true
} else {
return false
}
}
func crossProd(fst, snd geom.Vector) geom.Vector {
return geom.NewVector(fst.Y*snd.Z-fst.Z*snd.Y, fst.Z*snd.X-fst.X*snd.Z, fst.X*snd.Y-fst.Y*snd.X)
}
func vectorOp(fst, snd geom.Vector, op func(x, y float64) float64) geom.Vector {
return geom.NewVector(op(fst.X, snd.X), op(fst.Y, snd.Y), op(fst.Z, snd.Z))
}
func vectorSum(fst geom.Vector) float64 {
return fst.X + fst.Y + fst.Z
}