Решение на Пресичания от Ивайло Кирязов

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

Към профила на Ивайло Кирязов

Резултати

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

Код

package main
import (
"github.com/fmi/go-homework/geom"
"math"
)
func swap(x, y *float64) {
*x, *y = *y, *x
}
func CheckEdge(a, b, planeNormal, intersecPoint geom.Vector) bool {
edge := geom.Sub(a, b)
vp := geom.Sub(intersecPoint, b)
perpenToPlane := geom.Cross(edge, vp)
if geom.Dot(planeNormal, perpenToPlane) < 0 {
return false
} else {
return true
}
}
func IntersectHelp(triangle *Triangle, ray geom.Ray) (bool, geom.Vector, geom.Vector) {
planeNormal := geom.NewVector(0, 0, 0)
intersecPoint := geom.NewVector(0, 0, 0)
firstSecond := geom.Sub(triangle.Second, triangle.First)
firstThird := geom.Sub(triangle.Third, triangle.First)
planeNormal = geom.Cross(firstSecond, firstThird)
NdotRayDirection := geom.Dot(planeNormal, ray.Direction)
epsilon := math.Nextafter(1, 2) - 1
if math.Abs(NdotRayDirection) < epsilon {
return false, planeNormal, intersecPoint
}
direction := geom.Dot(planeNormal, triangle.First)
rayDistance := (geom.Dot(planeNormal, ray.Origin) + direction) / NdotRayDirection
if rayDistance < 0 {
return false, planeNormal, intersecPoint
}
directionMulti := geom.Mul(ray.Direction, rayDistance)
intersecPoint = geom.Add(ray.Origin, directionMulti)
return true, planeNormal, intersecPoint
}
type Triangle struct {
First geom.Vector
Second geom.Vector
Third geom.Vector
}
func NewTriangle(a, b, c geom.Vector) Triangle {
return Triangle{
First: a,
Second: b,
Third: c,
}
}
func (triangle Triangle) Intersect(ray geom.Ray) bool {
first, planeNormal, intersecPoint := IntersectHelp(&triangle, ray)
second := CheckEdge(triangle.Second, triangle.First, planeNormal, intersecPoint)
third := CheckEdge(triangle.Third, triangle.Second, planeNormal, intersecPoint)
fourth := CheckEdge(triangle.First, triangle.Third, planeNormal, intersecPoint)
return first && second && third && fourth
}
type Quad struct {
First geom.Vector
Second geom.Vector
Third geom.Vector
Fourth geom.Vector
}
func NewQuad(a, b, c, d geom.Vector) Quad {
return Quad{
First: a,
Second: b,
Third: c,
Fourth: d,
}
}
func (quad Quad) Intersect(ray geom.Ray) bool {
triangleToCheck := NewTriangle(quad.First, quad.Second, quad.Third)
first, planeNormal, intersecPoint := IntersectHelp(&triangleToCheck, ray)
second := CheckEdge(quad.Second, quad.First, planeNormal, intersecPoint)
third := CheckEdge(quad.Third, quad.Second, planeNormal, intersecPoint)
fourth := CheckEdge(quad.Fourth, quad.Third, planeNormal, intersecPoint)
five := CheckEdge(quad.First, quad.Fourth, planeNormal, intersecPoint)
return first && second && third && fourth && five
}
type Sphere struct {
Center geom.Vector
Radius float64
}
func NewSphere(origin geom.Vector, r float64) Sphere {
return Sphere{
Center: origin,
Radius: r,
}
}
func (sphere Sphere) Intersect(ray geom.Ray) bool {
hypotenuse := geom.Sub(sphere.Center, ray.Origin)
adjacentSide := geom.Dot(hypotenuse, ray.Direction)
direction := geom.Dot(hypotenuse, hypotenuse) - math.Pow(adjacentSide, 2)
radiusSquared := math.Pow(sphere.Radius, 2)
if direction > radiusSquared {
return false
}
adjacentSideSecond := math.Sqrt(radiusSquared - direction)
first := adjacentSide - adjacentSideSecond
second := adjacentSide + adjacentSideSecond
if first > second {
swap(&first, &second)
}
if first < 0 {
if second < 0 {
return false
}
}
return true
}
func main() {
}

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

--- FAIL: TestTriangleSimpleIntersection (0.00s)
    solution_test.go:206: Expected intersection to be true but it was not
FAIL
exit status 1
FAIL	_/tmp/d20181122-57-90n1mx	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-90n1mx	0.002s
--- FAIL: TestTriangleRayOppositeDirection (0.00s)
    solution_test.go:206: Expected intersection to be false but it was not
FAIL
exit status 1
FAIL	_/tmp/d20181122-57-90n1mx	0.002s
PASS
ok  	_/tmp/d20181122-57-90n1mx	0.002s
PASS
ok  	_/tmp/d20181122-57-90n1mx	0.002s
--- FAIL: TestTriangleRayOriginReallyCloseToObject (0.00s)
    solution_test.go:206: Expected intersection to be false but it was not
FAIL
exit status 1
FAIL	_/tmp/d20181122-57-90n1mx	0.002s
--- FAIL: TestQuadSimpleIntersection (0.00s)
    solution_test.go:206: Expected intersection to be true but it was not
FAIL
exit status 1
FAIL	_/tmp/d20181122-57-90n1mx	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-90n1mx	0.003s
--- FAIL: TestQuadRayOppositeDirection (0.00s)
    solution_test.go:206: Expected intersection to be false but it was not
FAIL
exit status 1
FAIL	_/tmp/d20181122-57-90n1mx	0.002s
PASS
ok  	_/tmp/d20181122-57-90n1mx	0.002s
PASS
ok  	_/tmp/d20181122-57-90n1mx	0.002s
--- FAIL: TestQuadOriginReallyClosedToObject (0.00s)
    solution_test.go:206: Expected intersection to be false but it was not
FAIL
exit status 1
FAIL	_/tmp/d20181122-57-90n1mx	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-90n1mx	0.002s
--- FAIL: TestQuadSecondIrregularHit (0.00s)
    solution_test.go:206: Expected intersection to be true but it was not
FAIL
exit status 1
FAIL	_/tmp/d20181122-57-90n1mx	0.002s
--- FAIL: TestQuadThirdIrregularHit (0.00s)
    solution_test.go:206: Expected intersection to be true but it was not
FAIL
exit status 1
FAIL	_/tmp/d20181122-57-90n1mx	0.002s
PASS
ok  	_/tmp/d20181122-57-90n1mx	0.002s
PASS
ok  	_/tmp/d20181122-57-90n1mx	0.002s
PASS
ok  	_/tmp/d20181122-57-90n1mx	0.002s
PASS
ok  	_/tmp/d20181122-57-90n1mx	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-90n1mx	0.002s

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

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

+package main
+
+import (
+ "github.com/fmi/go-homework/geom"
+ "math"
+)
+
+func swap(x, y *float64) {
+ *x, *y = *y, *x
+}
+
+func CheckEdge(a, b, planeNormal, intersecPoint geom.Vector) bool {
+ edge := geom.Sub(a, b)
+ vp := geom.Sub(intersecPoint, b)
+ perpenToPlane := geom.Cross(edge, vp)
+ if geom.Dot(planeNormal, perpenToPlane) < 0 {
+ return false
+ } else {
+ return true
+ }
+}
+
+func IntersectHelp(triangle *Triangle, ray geom.Ray) (bool, geom.Vector, geom.Vector) {
+ planeNormal := geom.NewVector(0, 0, 0)
+ intersecPoint := geom.NewVector(0, 0, 0)
+
+ firstSecond := geom.Sub(triangle.Second, triangle.First)
+ firstThird := geom.Sub(triangle.Third, triangle.First)
+
+ planeNormal = geom.Cross(firstSecond, firstThird)
+
+ NdotRayDirection := geom.Dot(planeNormal, ray.Direction)
+ epsilon := math.Nextafter(1, 2) - 1
+ if math.Abs(NdotRayDirection) < epsilon {
+ return false, planeNormal, intersecPoint
+ }
+
+ direction := geom.Dot(planeNormal, triangle.First)
+
+ rayDistance := (geom.Dot(planeNormal, ray.Origin) + direction) / NdotRayDirection
+
+ if rayDistance < 0 {
+ return false, planeNormal, intersecPoint
+ }
+ directionMulti := geom.Mul(ray.Direction, rayDistance)
+ intersecPoint = geom.Add(ray.Origin, directionMulti)
+
+ return true, planeNormal, intersecPoint
+}
+
+type Triangle struct {
+ First geom.Vector
+ Second geom.Vector
+ Third geom.Vector
+}
+
+func NewTriangle(a, b, c geom.Vector) Triangle {
+ return Triangle{
+ First: a,
+ Second: b,
+ Third: c,
+ }
+}
+
+func (triangle *Triangle) Intersect(ray geom.Ray) bool {
+ first, planeNormal, intersecPoint := IntersectHelp(triangle, ray)
+
+ second := CheckEdge(triangle.Second, triangle.First, planeNormal, intersecPoint)
+
+ third := CheckEdge(triangle.Third, triangle.Second, planeNormal, intersecPoint)
+
+ fourth := CheckEdge(triangle.First, triangle.Third, planeNormal, intersecPoint)
+
+ return first && second && third && fourth
+}
+
+type Quad struct {
+ First geom.Vector
+ Second geom.Vector
+ Third geom.Vector
+ Fourth geom.Vector
+}
+
+func NewQuad(a, b, c, d geom.Vector) Quad {
+ return Quad{
+ First: a,
+ Second: b,
+ Third: c,
+ Fourth: d,
+ }
+}
+
+func (quad *Quad) Intersect(ray geom.Ray) bool {
+ triangleToCheck := NewTriangle(quad.First, quad.Second, quad.Third)
+ first, planeNormal, intersecPoint := IntersectHelp(&triangleToCheck, ray)
+
+ second := CheckEdge(quad.Second, quad.First, planeNormal, intersecPoint)
+
+ third := CheckEdge(quad.Third, quad.Second, planeNormal, intersecPoint)
+
+ fourth := CheckEdge(quad.Fourth, quad.Third, planeNormal, intersecPoint)
+
+ five := CheckEdge(quad.First, quad.Fourth, planeNormal, intersecPoint)
+
+ return first && second && third && fourth && five
+}
+
+type Sphere struct {
+ Center geom.Vector
+ Radius float64
+}
+
+func NewSphere(origin geom.Vector, r float64) Sphere {
+ return Sphere{
+ Center: origin,
+ Radius: r,
+ }
+}
+
+func (sphere *Sphere) Intersect(ray geom.Ray) bool {
+ hypotenuse := geom.Sub(sphere.Center, ray.Origin)
+ adjacentSide := geom.Dot(hypotenuse, ray.Direction)
+
+ direction := geom.Dot(hypotenuse, hypotenuse) - math.Pow(adjacentSide, 2)
+
+ radiusSquared := math.Pow(sphere.Radius, 2)
+
+ if direction > radiusSquared {
+ return false
+ }
+
+ adjacentSideSecond := math.Sqrt(radiusSquared - direction)
+ first := adjacentSide - adjacentSideSecond
+ second := adjacentSide + adjacentSideSecond
+
+ if first > second {
+ swap(&first, &second)
+ }
+
+ if first < 0 {
+ if second < 0 {
+ return false
+ }
+ }
+
+ return true
+}
+
+func main() {
+}

Ивайло обнови решението на 21.11.2018 13:29 (преди 9 месеца)

package main
import (
"github.com/fmi/go-homework/geom"
"math"
)
func swap(x, y *float64) {
*x, *y = *y, *x
}
func CheckEdge(a, b, planeNormal, intersecPoint geom.Vector) bool {
edge := geom.Sub(a, b)
vp := geom.Sub(intersecPoint, b)
perpenToPlane := geom.Cross(edge, vp)
if geom.Dot(planeNormal, perpenToPlane) < 0 {
return false
} else {
return true
}
}
func IntersectHelp(triangle *Triangle, ray geom.Ray) (bool, geom.Vector, geom.Vector) {
planeNormal := geom.NewVector(0, 0, 0)
intersecPoint := geom.NewVector(0, 0, 0)
firstSecond := geom.Sub(triangle.Second, triangle.First)
firstThird := geom.Sub(triangle.Third, triangle.First)
planeNormal = geom.Cross(firstSecond, firstThird)
NdotRayDirection := geom.Dot(planeNormal, ray.Direction)
epsilon := math.Nextafter(1, 2) - 1
if math.Abs(NdotRayDirection) < epsilon {
return false, planeNormal, intersecPoint
}
direction := geom.Dot(planeNormal, triangle.First)
rayDistance := (geom.Dot(planeNormal, ray.Origin) + direction) / NdotRayDirection
if rayDistance < 0 {
return false, planeNormal, intersecPoint
}
directionMulti := geom.Mul(ray.Direction, rayDistance)
intersecPoint = geom.Add(ray.Origin, directionMulti)
return true, planeNormal, intersecPoint
}
type Triangle struct {
First geom.Vector
Second geom.Vector
Third geom.Vector
}
func NewTriangle(a, b, c geom.Vector) Triangle {
return Triangle{
First: a,
Second: b,
Third: c,
}
}
-func (triangle *Triangle) Intersect(ray geom.Ray) bool {
- first, planeNormal, intersecPoint := IntersectHelp(triangle, ray)
+func (triangle Triangle) Intersect(ray geom.Ray) bool {
+ first, planeNormal, intersecPoint := IntersectHelp(&triangle, ray)
second := CheckEdge(triangle.Second, triangle.First, planeNormal, intersecPoint)
third := CheckEdge(triangle.Third, triangle.Second, planeNormal, intersecPoint)
fourth := CheckEdge(triangle.First, triangle.Third, planeNormal, intersecPoint)
return first && second && third && fourth
}
type Quad struct {
First geom.Vector
Second geom.Vector
Third geom.Vector
Fourth geom.Vector
}
func NewQuad(a, b, c, d geom.Vector) Quad {
return Quad{
First: a,
Second: b,
Third: c,
Fourth: d,
}
}
-func (quad *Quad) Intersect(ray geom.Ray) bool {
+func (quad Quad) Intersect(ray geom.Ray) bool {
triangleToCheck := NewTriangle(quad.First, quad.Second, quad.Third)
first, planeNormal, intersecPoint := IntersectHelp(&triangleToCheck, ray)
second := CheckEdge(quad.Second, quad.First, planeNormal, intersecPoint)
third := CheckEdge(quad.Third, quad.Second, planeNormal, intersecPoint)
fourth := CheckEdge(quad.Fourth, quad.Third, planeNormal, intersecPoint)
five := CheckEdge(quad.First, quad.Fourth, planeNormal, intersecPoint)
return first && second && third && fourth && five
}
type Sphere struct {
Center geom.Vector
Radius float64
}
func NewSphere(origin geom.Vector, r float64) Sphere {
return Sphere{
Center: origin,
Radius: r,
}
}
-func (sphere *Sphere) Intersect(ray geom.Ray) bool {
+func (sphere Sphere) Intersect(ray geom.Ray) bool {
hypotenuse := geom.Sub(sphere.Center, ray.Origin)
adjacentSide := geom.Dot(hypotenuse, ray.Direction)
direction := geom.Dot(hypotenuse, hypotenuse) - math.Pow(adjacentSide, 2)
radiusSquared := math.Pow(sphere.Radius, 2)
if direction > radiusSquared {
return false
}
adjacentSideSecond := math.Sqrt(radiusSquared - direction)
first := adjacentSide - adjacentSideSecond
second := adjacentSide + adjacentSideSecond
if first > second {
swap(&first, &second)
}
if first < 0 {
if second < 0 {
return false
}
}
return true
}
func main() {
}