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

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

Към профила на Константин Терзиев

Резултати

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

Код

package main
import (
"math"
"github.com/fmi/go-homework/geom"
)
const EPSILON = 0.000001
// Triangle represents a triangle with vertices a, b and c.
type Triangle struct {
a, b, c geom.Vector
}
// Quad represents a quadrilateral with vertices a, b, c and d.
type Quad struct {
a, b, c, d geom.Vector
}
// Sphere represents a sphere with origin origin and radius r.
type Sphere struct {
origin geom.Vector
r float64
}
// NewTriangle returns a *Triangle, pointer to a Triangle
// with vertices a, b and c.
func NewTriangle(a, b, c geom.Vector) *Triangle {
return &Triangle{
a: a,
b: b,
c: c,
}
}
// NewQuad returns a *Quad, pointer to a Quad with vertices a, b, c and d.
func NewQuad(a, b, c, d geom.Vector) *Quad {
return &Quad{
a: a,
b: b,
c: c,
d: d,
}
}
// NewSphere returns a *Sphere, pointer to a Sphere with
// origin origin and radius r.
func NewSphere(origin geom.Vector, r float64) *Sphere {
return &Sphere{
origin: origin,
r: r,
}
}
// Intersect returns bool that is true if ray intersects
// the Triangle pointed to by tri.
// Implementation of MT97 with slight adaptation:
// 1) Add check if tt >= 0 at the end.
// 2) Don't bother returning t, u, and v.
// Source: http://www.graphics.cornell.edu/pubs/1997/MT97.pdf
func (tri *Triangle) Intersect(ray geom.Ray) bool {
// find vectors for two edges sharing a
var edge1 = geom.Sub(tri.b, tri.a)
var edge2 = geom.Sub(tri.c, tri.a)
// begin calculating determinant - also used to calculate U parameter
var pvec = geom.Cross(ray.Direction, edge2)
// if determinant is near zero, ray lies in plane of triangle
var det = geom.Dot(edge1, pvec)
// scip #ifdef TEST_CULL and go straight to #else
if det > -EPSILON && det < EPSILON {
return false
}
var inv_det = 1.0 / det
// calculate distance from a to ray origin
var tvec = geom.Sub(ray.Origin, tri.a)
// calculate U parameter and test bounds
var u = geom.Dot(tvec, pvec) * inv_det
if u < 0.0 || u > 1.0 {
return false
}
// prepare to test V parameter
var qvec = geom.Cross(tvec, edge1)
// calculate V parameter and test bounds
var v = geom.Dot(ray.Direction, qvec) * inv_det
if v < 0.0 || u+v > 1.0 {
return false
}
// calculate t, if t >= 0 ray intersects triangle
var t = geom.Dot(edge2, qvec) * inv_det
if t >= 0 {
return true
}
return false
}
// Intersect returns bool that is true if ray intersects
// the Quad pointed to by q.
// Reduce the quad to to two triangles.
// However first take into consideration whether the quad is concave.
// In order to evaluate whether the quad is concave we will
// use that the the dot product of the vectors forming the
// angle is negative when the angle itself is obtuse.
// Whether alpha or gamma is obtuse is irrelevant.
// Same applies to beta and delta.
func (q *Quad) Intersect(ray geom.Ray) bool {
var alpha = geom.Dot(geom.Sub(q.a, q.d), geom.Sub(q.b, q.a))
var gamma = geom.Dot(geom.Sub(q.c, q.b), geom.Sub(q.d, q.c))
if alpha < 0.0 || gamma < 0.0 {
return NewTriangle(q.a, q.b, q.c).Intersect(ray) ||
NewTriangle(q.a, q.c, q.d).Intersect(ray)
}
// no check needed since only one angle can be obtuse in a quadrilateral
return NewTriangle(q.a, q.b, q.d).Intersect(ray) ||
NewTriangle(q.b, q.c, q.d).Intersect(ray)
}
// Intersect returns bool that is true if ray intersects
// the Sphere pointed to by s.
// Implementation of basic geometry algorithm.
// Source: https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection
func (s *Sphere) Intersect(ray geom.Ray) bool {
var l = geom.Sub(s.origin, ray.Origin)
var tca = geom.Dot(l, ray.Direction)
var d2 = geom.Dot(l, l) - tca*tca
var r2 = s.r * s.r
if d2 > r2 {
return false
}
var thc = math.Sqrt(r2 - d2)
var t0 = tca - thc
var t1 = tca + thc
// the ray origin might be inside the sphere
// that is why we check both intersection points
if t0 >= 0 || t1 >= 0 {
return true
}
return false
}
func main() {
}

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

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

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

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

+package main

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

-package main
+package main
+
+// import (
+// "fmi/go-homework/geom"
+// "math"
+// )
+
+// const EPSILON = 0.000001
+
+// // Triangle represents a triangle with vertices a, b and c.
+// type Triangle struct {
+// a, b, c geom.Vector
+// }
+
+// // Quad represents a quadrilateral with vertices a, b, c and d.
+// type Quad struct {
+// a, b, c, d geom.Vector
+// }
+
+// // Sphere represents a sphere with origin origin and radius r.
+// type Sphere struct {
+// origin geom.Vector
+// r float64
+// }
+
+// // NewTriangle returns a *Triangle, pointer to a Triangle
+// // with vertices a, b and c.
+// func NewTriangle(a, b, c geom.Vector) *Triangle {
+// return &Triangle{
+// a: a,
+// b: b,
+// c: c,
+// }
+// }
+
+// // NewQuad returns a *Quad, pointer to a Quad with vertices a, b, c and d.
+// func NewQuad(a, b, c, d geom.Vector) *Quad {
+// return &Quad{
+// a: a,
+// b: b,
+// c: c,
+// d: d,
+// }
+// }
+
+// // NewSphere returns a *Sphere, pointer to a Sphere with
+// // origin origin and radius r.
+// func NewSphere(origin geom.Vector, r float64) *Sphere {
+// return &Sphere{
+// origin: origin,
+// r: r,
+// }
+// }
+
+// // Intersect returns bool that is true if ray intersects
+// // the Triangle pointed to by tri.
+// // Implementation of MT97 with slight adaptation:
+// // 1) Add check if tt >= 0 at the end.
+// // 2) Don't bother returning t, u, and v.
+// // Source: http://www.graphics.cornell.edu/pubs/1997/MT97.pdf
+// func (tri *Triangle) Intersect(ray geom.Ray) bool {
+// // find vectors for two edges sharing a
+// var edge1 = geom.Sub(tri.b, tri.a)
+// var edge2 = geom.Sub(tri.c, tri.a)
+
+// // begin calculating determinant - also used to calculate U parameter
+// var pvec = geom.Cross(ray.Direction, edge2)
+
+// // if determinant is near zero, ray lies in plane of triangle
+// var det = geom.Dot(edge1, pvec)
+
+// // scip #ifdef TEST_CULL and go straight to #else
+// if det > -EPSILON && det < EPSILON {
+// return false
+// }
+// var inv_det = 1.0 / det
+
+// // calculate distance from a to ray origin
+// var tvec = geom.Sub(ray.Origin, tri.a)
+
+// // calculate U parameter and test bounds
+// var u = geom.Dot(tvec, pvec) * inv_det
+// if u < 0.0 || u > 1.0 {
+// return false
+// }
+
+// // prepare to test V parameter
+// var qvec = geom.Cross(tvec, edge1)
+
+// // calculate V parameter and test bounds
+// var v = geom.Dot(ray.Direction, qvec) * inv_det
+// if v < 0.0 || v > 1.0 {
+// return false
+// }
+
+// // calculate t, if t >= 0 ray intersects triangle
+// var t = geom.Dot(edge2, qvec) * inv_det
+// if t >= 0 {
+// return true
+// }
+// return false
+
+// }
+
+// // Intersect returns bool that is true if ray intersects
+// // the Quad pointed to by q.
+// // Reduce the quad to to two triangles.
+// // However first take into consideration whether the quad is concave.
+// // In order to evaluate whether the quad is concave we will
+// // use that the the dot product of the vectors forming the
+// // angle is negative when the angle itself is obtuse.
+// // Whether alpha or gamma is obtuse is irrelevant.
+// // Same applies to beta and delta.
+// func (q *Quad) Intersect(ray geom.Ray) bool {
+// var alpha = geom.Dot(geom.Sub(q.a, q.d), geom.Sub(q.b, q.a))
+// var gamma = geom.Dot(geom.Sub(q.c, q.b), geom.Sub(q.d, q.c))
+
+// if alpha < 0.0 || gamma < 0.0 {
+// return NewTriangle(q.a, q.b, q.c).Intersect(ray) ||
+// NewTriangle(q.a, q.c, q.d).Intersect(ray)
+// }
+
+// // no check needed since only one angle can be obtuse in a quadrilateral
+// return NewTriangle(q.a, q.b, q.d).Intersect(ray) ||
+// NewTriangle(q.b, q.c, q.d).Intersect(ray)
+// }
+
+// // Intersect returns bool that is true if ray intersects
+// // the Sphere pointed to by s.
+// // Implementation of basic geometry algorithm.
+// // Source: https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection
+// func (s *Sphere) Intersect(ray geom.Ray) bool {
+// var l = geom.Sub(s.origin, ray.Origin)
+// var tca = geom.Dot(l, ray.Direction)
+// var d2 = geom.Dot(l, l) + tca*tca
+// var r2 = s.r * s.r
+// if d2 > r2 {
+// return false
+// }
+// var thc = math.Sqrt(r2 - d2)
+// var t0 = tca - thc
+// var t1 = tca + thc
+// // the ray origin might be inside the sphere
+// // that is why we check both intersection points
+// if t0 >= 0 || t1 >= 0 {
+// return true
+// }
+// return false
+// }
+
+// func main() {
+// }

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

package main
// import (
-// "fmi/go-homework/geom"
+// "go-homework/geom"
// "math"
// )
// const EPSILON = 0.000001
// // Triangle represents a triangle with vertices a, b and c.
// type Triangle struct {
// a, b, c geom.Vector
// }
// // Quad represents a quadrilateral with vertices a, b, c and d.
// type Quad struct {
// a, b, c, d geom.Vector
// }
// // Sphere represents a sphere with origin origin and radius r.
// type Sphere struct {
// origin geom.Vector
// r float64
// }
// // NewTriangle returns a *Triangle, pointer to a Triangle
// // with vertices a, b and c.
// func NewTriangle(a, b, c geom.Vector) *Triangle {
// return &Triangle{
// a: a,
// b: b,
// c: c,
// }
// }
// // NewQuad returns a *Quad, pointer to a Quad with vertices a, b, c and d.
// func NewQuad(a, b, c, d geom.Vector) *Quad {
// return &Quad{
// a: a,
// b: b,
// c: c,
// d: d,
// }
// }
// // NewSphere returns a *Sphere, pointer to a Sphere with
// // origin origin and radius r.
// func NewSphere(origin geom.Vector, r float64) *Sphere {
// return &Sphere{
// origin: origin,
// r: r,
// }
// }
// // Intersect returns bool that is true if ray intersects
// // the Triangle pointed to by tri.
// // Implementation of MT97 with slight adaptation:
// // 1) Add check if tt >= 0 at the end.
// // 2) Don't bother returning t, u, and v.
// // Source: http://www.graphics.cornell.edu/pubs/1997/MT97.pdf
// func (tri *Triangle) Intersect(ray geom.Ray) bool {
// // find vectors for two edges sharing a
// var edge1 = geom.Sub(tri.b, tri.a)
// var edge2 = geom.Sub(tri.c, tri.a)
// // begin calculating determinant - also used to calculate U parameter
// var pvec = geom.Cross(ray.Direction, edge2)
// // if determinant is near zero, ray lies in plane of triangle
// var det = geom.Dot(edge1, pvec)
// // scip #ifdef TEST_CULL and go straight to #else
// if det > -EPSILON && det < EPSILON {
// return false
// }
// var inv_det = 1.0 / det
// // calculate distance from a to ray origin
// var tvec = geom.Sub(ray.Origin, tri.a)
// // calculate U parameter and test bounds
// var u = geom.Dot(tvec, pvec) * inv_det
// if u < 0.0 || u > 1.0 {
// return false
// }
// // prepare to test V parameter
// var qvec = geom.Cross(tvec, edge1)
// // calculate V parameter and test bounds
// var v = geom.Dot(ray.Direction, qvec) * inv_det
// if v < 0.0 || v > 1.0 {
// return false
// }
// // calculate t, if t >= 0 ray intersects triangle
// var t = geom.Dot(edge2, qvec) * inv_det
// if t >= 0 {
// return true
// }
// return false
// }
// // Intersect returns bool that is true if ray intersects
// // the Quad pointed to by q.
// // Reduce the quad to to two triangles.
// // However first take into consideration whether the quad is concave.
// // In order to evaluate whether the quad is concave we will
// // use that the the dot product of the vectors forming the
// // angle is negative when the angle itself is obtuse.
// // Whether alpha or gamma is obtuse is irrelevant.
// // Same applies to beta and delta.
// func (q *Quad) Intersect(ray geom.Ray) bool {
// var alpha = geom.Dot(geom.Sub(q.a, q.d), geom.Sub(q.b, q.a))
// var gamma = geom.Dot(geom.Sub(q.c, q.b), geom.Sub(q.d, q.c))
// if alpha < 0.0 || gamma < 0.0 {
// return NewTriangle(q.a, q.b, q.c).Intersect(ray) ||
// NewTriangle(q.a, q.c, q.d).Intersect(ray)
// }
// // no check needed since only one angle can be obtuse in a quadrilateral
// return NewTriangle(q.a, q.b, q.d).Intersect(ray) ||
// NewTriangle(q.b, q.c, q.d).Intersect(ray)
// }
// // Intersect returns bool that is true if ray intersects
// // the Sphere pointed to by s.
// // Implementation of basic geometry algorithm.
// // Source: https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection
// func (s *Sphere) Intersect(ray geom.Ray) bool {
// var l = geom.Sub(s.origin, ray.Origin)
// var tca = geom.Dot(l, ray.Direction)
// var d2 = geom.Dot(l, l) + tca*tca
// var r2 = s.r * s.r
// if d2 > r2 {
// return false
// }
// var thc = math.Sqrt(r2 - d2)
// var t0 = tca - thc
// var t1 = tca + thc
// // the ray origin might be inside the sphere
// // that is why we check both intersection points
// if t0 >= 0 || t1 >= 0 {
// return true
// }
// return false
// }
// func main() {
// }

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

package main
-// import (
-// "go-homework/geom"
-// "math"
-// )
-
// const EPSILON = 0.000001
// // Triangle represents a triangle with vertices a, b and c.
// type Triangle struct {
// a, b, c geom.Vector
// }
// // Quad represents a quadrilateral with vertices a, b, c and d.
// type Quad struct {
// a, b, c, d geom.Vector
// }
// // Sphere represents a sphere with origin origin and radius r.
// type Sphere struct {
// origin geom.Vector
// r float64
// }
// // NewTriangle returns a *Triangle, pointer to a Triangle
// // with vertices a, b and c.
// func NewTriangle(a, b, c geom.Vector) *Triangle {
// return &Triangle{
// a: a,
// b: b,
// c: c,
// }
// }
// // NewQuad returns a *Quad, pointer to a Quad with vertices a, b, c and d.
// func NewQuad(a, b, c, d geom.Vector) *Quad {
// return &Quad{
// a: a,
// b: b,
// c: c,
// d: d,
// }
// }
// // NewSphere returns a *Sphere, pointer to a Sphere with
// // origin origin and radius r.
// func NewSphere(origin geom.Vector, r float64) *Sphere {
// return &Sphere{
// origin: origin,
// r: r,
// }
// }
// // Intersect returns bool that is true if ray intersects
// // the Triangle pointed to by tri.
// // Implementation of MT97 with slight adaptation:
// // 1) Add check if tt >= 0 at the end.
// // 2) Don't bother returning t, u, and v.
// // Source: http://www.graphics.cornell.edu/pubs/1997/MT97.pdf
// func (tri *Triangle) Intersect(ray geom.Ray) bool {
// // find vectors for two edges sharing a
// var edge1 = geom.Sub(tri.b, tri.a)
// var edge2 = geom.Sub(tri.c, tri.a)
// // begin calculating determinant - also used to calculate U parameter
// var pvec = geom.Cross(ray.Direction, edge2)
// // if determinant is near zero, ray lies in plane of triangle
// var det = geom.Dot(edge1, pvec)
// // scip #ifdef TEST_CULL and go straight to #else
// if det > -EPSILON && det < EPSILON {
// return false
// }
// var inv_det = 1.0 / det
// // calculate distance from a to ray origin
// var tvec = geom.Sub(ray.Origin, tri.a)
// // calculate U parameter and test bounds
// var u = geom.Dot(tvec, pvec) * inv_det
// if u < 0.0 || u > 1.0 {
// return false
// }
// // prepare to test V parameter
// var qvec = geom.Cross(tvec, edge1)
// // calculate V parameter and test bounds
// var v = geom.Dot(ray.Direction, qvec) * inv_det
// if v < 0.0 || v > 1.0 {
// return false
// }
// // calculate t, if t >= 0 ray intersects triangle
// var t = geom.Dot(edge2, qvec) * inv_det
// if t >= 0 {
// return true
// }
// return false
// }
// // Intersect returns bool that is true if ray intersects
// // the Quad pointed to by q.
// // Reduce the quad to to two triangles.
// // However first take into consideration whether the quad is concave.
// // In order to evaluate whether the quad is concave we will
// // use that the the dot product of the vectors forming the
// // angle is negative when the angle itself is obtuse.
// // Whether alpha or gamma is obtuse is irrelevant.
// // Same applies to beta and delta.
// func (q *Quad) Intersect(ray geom.Ray) bool {
// var alpha = geom.Dot(geom.Sub(q.a, q.d), geom.Sub(q.b, q.a))
// var gamma = geom.Dot(geom.Sub(q.c, q.b), geom.Sub(q.d, q.c))
// if alpha < 0.0 || gamma < 0.0 {
// return NewTriangle(q.a, q.b, q.c).Intersect(ray) ||
// NewTriangle(q.a, q.c, q.d).Intersect(ray)
// }
// // no check needed since only one angle can be obtuse in a quadrilateral
// return NewTriangle(q.a, q.b, q.d).Intersect(ray) ||
// NewTriangle(q.b, q.c, q.d).Intersect(ray)
// }
// // Intersect returns bool that is true if ray intersects
// // the Sphere pointed to by s.
// // Implementation of basic geometry algorithm.
// // Source: https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection
// func (s *Sphere) Intersect(ray geom.Ray) bool {
// var l = geom.Sub(s.origin, ray.Origin)
// var tca = geom.Dot(l, ray.Direction)
// var d2 = geom.Dot(l, l) + tca*tca
// var r2 = s.r * s.r
// if d2 > r2 {
// return false
// }
// var thc = math.Sqrt(r2 - d2)
// var t0 = tca - thc
// var t1 = tca + thc
// // the ray origin might be inside the sphere
// // that is why we check both intersection points
// if t0 >= 0 || t1 >= 0 {
// return true
// }
// return false
// }
// func main() {
// }

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

package main
-// const EPSILON = 0.000001
+const EPSILON = 0.000001
-// // Triangle represents a triangle with vertices a, b and c.
-// type Triangle struct {
+// Triangle represents a triangle with vertices a, b and c.
-// a, b, c geom.Vector
+type Triangle struct {
-// }
+ a, b, c float64
-
+}
-// // Quad represents a quadrilateral with vertices a, b, c and d.
-// type Quad struct {
-// a, b, c, d geom.Vector
-// }
-
-// // Sphere represents a sphere with origin origin and radius r.
-// type Sphere struct {
-// origin geom.Vector
-// r float64
-// }
-
-// // NewTriangle returns a *Triangle, pointer to a Triangle
-// // with vertices a, b and c.
-// func NewTriangle(a, b, c geom.Vector) *Triangle {
-// return &Triangle{
-// a: a,
-// b: b,
-// c: c,
-// }
-// }
-
-// // NewQuad returns a *Quad, pointer to a Quad with vertices a, b, c and d.
-// func NewQuad(a, b, c, d geom.Vector) *Quad {
-// return &Quad{
-// a: a,
-// b: b,
-// c: c,
-// d: d,
-// }
-// }
-
-// // NewSphere returns a *Sphere, pointer to a Sphere with
-// // origin origin and radius r.
-// func NewSphere(origin geom.Vector, r float64) *Sphere {
-// return &Sphere{
-// origin: origin,
-// r: r,
-// }
-// }
-
-// // Intersect returns bool that is true if ray intersects
-// // the Triangle pointed to by tri.
-// // Implementation of MT97 with slight adaptation:
-// // 1) Add check if tt >= 0 at the end.
-// // 2) Don't bother returning t, u, and v.
-// // Source: http://www.graphics.cornell.edu/pubs/1997/MT97.pdf
-// func (tri *Triangle) Intersect(ray geom.Ray) bool {
-// // find vectors for two edges sharing a
-// var edge1 = geom.Sub(tri.b, tri.a)
-// var edge2 = geom.Sub(tri.c, tri.a)
-
-// // begin calculating determinant - also used to calculate U parameter
-// var pvec = geom.Cross(ray.Direction, edge2)
-
-// // if determinant is near zero, ray lies in plane of triangle
-// var det = geom.Dot(edge1, pvec)
-
-// // scip #ifdef TEST_CULL and go straight to #else
-// if det > -EPSILON && det < EPSILON {
-// return false
-// }
-// var inv_det = 1.0 / det
-
-// // calculate distance from a to ray origin
-// var tvec = geom.Sub(ray.Origin, tri.a)
-
-// // calculate U parameter and test bounds
-// var u = geom.Dot(tvec, pvec) * inv_det
-// if u < 0.0 || u > 1.0 {
-// return false
-// }
-
-// // prepare to test V parameter
-// var qvec = geom.Cross(tvec, edge1)
-
-// // calculate V parameter and test bounds
-// var v = geom.Dot(ray.Direction, qvec) * inv_det
-// if v < 0.0 || v > 1.0 {
-// return false
-// }
-
-// // calculate t, if t >= 0 ray intersects triangle
-// var t = geom.Dot(edge2, qvec) * inv_det
-// if t >= 0 {
-// return true
-// }
-// return false
-
-// }
-
-// // Intersect returns bool that is true if ray intersects
-// // the Quad pointed to by q.
-// // Reduce the quad to to two triangles.
-// // However first take into consideration whether the quad is concave.
-// // In order to evaluate whether the quad is concave we will
-// // use that the the dot product of the vectors forming the
-// // angle is negative when the angle itself is obtuse.
-// // Whether alpha or gamma is obtuse is irrelevant.
-// // Same applies to beta and delta.
-// func (q *Quad) Intersect(ray geom.Ray) bool {
-// var alpha = geom.Dot(geom.Sub(q.a, q.d), geom.Sub(q.b, q.a))
-// var gamma = geom.Dot(geom.Sub(q.c, q.b), geom.Sub(q.d, q.c))
-
-// if alpha < 0.0 || gamma < 0.0 {
-// return NewTriangle(q.a, q.b, q.c).Intersect(ray) ||
-// NewTriangle(q.a, q.c, q.d).Intersect(ray)
-// }
-
-// // no check needed since only one angle can be obtuse in a quadrilateral
-// return NewTriangle(q.a, q.b, q.d).Intersect(ray) ||
-// NewTriangle(q.b, q.c, q.d).Intersect(ray)
-// }
-
-// // Intersect returns bool that is true if ray intersects
-// // the Sphere pointed to by s.
-// // Implementation of basic geometry algorithm.
-// // Source: https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection
-// func (s *Sphere) Intersect(ray geom.Ray) bool {
-// var l = geom.Sub(s.origin, ray.Origin)
-// var tca = geom.Dot(l, ray.Direction)
-// var d2 = geom.Dot(l, l) + tca*tca
-// var r2 = s.r * s.r
-// if d2 > r2 {
-// return false
-// }
-// var thc = math.Sqrt(r2 - d2)
-// var t0 = tca - thc
-// var t1 = tca + thc
-// // the ray origin might be inside the sphere
-// // that is why we check both intersection points
-// if t0 >= 0 || t1 >= 0 {
-// return true
-// }
-// return false
-// }
-
-// func main() {
-// }

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

package main
+import "github.com/fmi/go-homework/geom"
const EPSILON = 0.000001
// Triangle represents a triangle with vertices a, b and c.
type Triangle struct {
- a, b, c float64
-}
+ a, b, c geom.Vector
+}

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

package main
-import "github.com/fmi/go-homework/geom"
+import (
+ "github.com/fmi/go-homework/geom"
+ "math"
+)
+
const EPSILON = 0.000001
// Triangle represents a triangle with vertices a, b and c.
type Triangle struct {
a, b, c geom.Vector
+}
+
+// Quad represents a quadrilateral with vertices a, b, c and d.
+type Quad struct {
+ a, b, c, d geom.Vector
+}
+
+// Sphere represents a sphere with origin origin and radius r.
+type Sphere struct {
+ origin geom.Vector
+ r float64
+}
+
+// NewTriangle returns a *Triangle, pointer to a Triangle
+// with vertices a, b and c.
+func NewTriangle(a, b, c geom.Vector) *Triangle {
+ return &Triangle{
+ a: a,
+ b: b,
+ c: c,
+ }
+}
+
+// NewQuad returns a *Quad, pointer to a Quad with vertices a, b, c and d.
+func NewQuad(a, b, c, d geom.Vector) *Quad {
+ return &Quad{
+ a: a,
+ b: b,
+ c: c,
+ d: d,
+ }
+}
+
+// NewSphere returns a *Sphere, pointer to a Sphere with
+// origin origin and radius r.
+func NewSphere(origin geom.Vector, r float64) *Sphere {
+ return &Sphere{
+ origin: origin,
+ r: r,
+ }
+}
+
+// Intersect returns bool that is true if ray intersects
+// the Triangle pointed to by tri.
+// Implementation of MT97 with slight adaptation:
+// 1) Add check if tt >= 0 at the end.
+// 2) Don't bother returning t, u, and v.
+// Source: http://www.graphics.cornell.edu/pubs/1997/MT97.pdf
+func (tri *Triangle) Intersect(ray geom.Ray) bool {
+ // find vectors for two edges sharing a
+ var edge1 = geom.Sub(tri.b, tri.a)
+ var edge2 = geom.Sub(tri.c, tri.a)
+
+ // begin calculating determinant - also used to calculate U parameter
+ var pvec = geom.Cross(ray.Direction, edge2)
+
+ // if determinant is near zero, ray lies in plane of triangle
+ var det = geom.Dot(edge1, pvec)
+
+ // scip #ifdef TEST_CULL and go straight to #else
+ if det > -EPSILON && det < EPSILON {
+ return false
+ }
+ var inv_det = 1.0 / det
+
+ // calculate distance from a to ray origin
+ var tvec = geom.Sub(ray.Origin, tri.a)
+
+ // calculate U parameter and test bounds
+ var u = geom.Dot(tvec, pvec) * inv_det
+ if u < 0.0 || u > 1.0 {
+ return false
+ }
+
+ // prepare to test V parameter
+ var qvec = geom.Cross(tvec, edge1)
+
+ // calculate V parameter and test bounds
+ var v = geom.Dot(ray.Direction, qvec) * inv_det
+ if v < 0.0 || v > 1.0 {
+ return false
+ }
+
+ // calculate t, if t >= 0 ray intersects triangle
+ var t = geom.Dot(edge2, qvec) * inv_det
+ if t >= 0 {
+ return true
+ }
+ return false
+
+}
+
+// Intersect returns bool that is true if ray intersects
+// the Quad pointed to by q.
+// Reduce the quad to to two triangles.
+// However first take into consideration whether the quad is concave.
+// In order to evaluate whether the quad is concave we will
+// use that the the dot product of the vectors forming the
+// angle is negative when the angle itself is obtuse.
+// Whether alpha or gamma is obtuse is irrelevant.
+// Same applies to beta and delta.
+func (q *Quad) Intersect(ray geom.Ray) bool {
+ var alpha = geom.Dot(geom.Sub(q.a, q.d), geom.Sub(q.b, q.a))
+ var gamma = geom.Dot(geom.Sub(q.c, q.b), geom.Sub(q.d, q.c))
+
+ if alpha < 0.0 || gamma < 0.0 {
+ return NewTriangle(q.a, q.b, q.c).Intersect(ray) ||
+ NewTriangle(q.a, q.c, q.d).Intersect(ray)
+ }
+
+ // no check needed since only one angle can be obtuse in a quadrilateral
+ return NewTriangle(q.a, q.b, q.d).Intersect(ray) ||
+ NewTriangle(q.b, q.c, q.d).Intersect(ray)
+}
+
+// Intersect returns bool that is true if ray intersects
+// the Sphere pointed to by s.
+// Implementation of basic geometry algorithm.
+// Source: https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection
+func (s *Sphere) Intersect(ray geom.Ray) bool {
+ var l = geom.Sub(s.origin, ray.Origin)
+ var tca = geom.Dot(l, ray.Direction)
+ var d2 = geom.Dot(l, l) + tca*tca
+ var r2 = s.r * s.r
+ if d2 > r2 {
+ return false
+ }
+ var thc = math.Sqrt(r2 - d2)
+ var t0 = tca - thc
+ var t1 = tca + thc
+ // the ray origin might be inside the sphere
+ // that is why we check both intersection points
+ if t0 >= 0 || t1 >= 0 {
+ return true
+ }
+ return false
+}
+
+func main() {
}

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

package main
import (
- "github.com/fmi/go-homework/geom"
"math"
+
+ "github.com/fmi/go-homework/geom"
)
const EPSILON = 0.000001
// Triangle represents a triangle with vertices a, b and c.
type Triangle struct {
a, b, c geom.Vector
}
// Quad represents a quadrilateral with vertices a, b, c and d.
type Quad struct {
a, b, c, d geom.Vector
}
// Sphere represents a sphere with origin origin and radius r.
type Sphere struct {
origin geom.Vector
r float64
}
// NewTriangle returns a *Triangle, pointer to a Triangle
// with vertices a, b and c.
func NewTriangle(a, b, c geom.Vector) *Triangle {
return &Triangle{
a: a,
b: b,
c: c,
}
}
// NewQuad returns a *Quad, pointer to a Quad with vertices a, b, c and d.
func NewQuad(a, b, c, d geom.Vector) *Quad {
return &Quad{
a: a,
b: b,
c: c,
d: d,
}
}
// NewSphere returns a *Sphere, pointer to a Sphere with
// origin origin and radius r.
func NewSphere(origin geom.Vector, r float64) *Sphere {
return &Sphere{
origin: origin,
r: r,
}
}
// Intersect returns bool that is true if ray intersects
// the Triangle pointed to by tri.
// Implementation of MT97 with slight adaptation:
// 1) Add check if tt >= 0 at the end.
// 2) Don't bother returning t, u, and v.
// Source: http://www.graphics.cornell.edu/pubs/1997/MT97.pdf
func (tri *Triangle) Intersect(ray geom.Ray) bool {
// find vectors for two edges sharing a
var edge1 = geom.Sub(tri.b, tri.a)
var edge2 = geom.Sub(tri.c, tri.a)
// begin calculating determinant - also used to calculate U parameter
var pvec = geom.Cross(ray.Direction, edge2)
// if determinant is near zero, ray lies in plane of triangle
var det = geom.Dot(edge1, pvec)
// scip #ifdef TEST_CULL and go straight to #else
if det > -EPSILON && det < EPSILON {
return false
}
var inv_det = 1.0 / det
// calculate distance from a to ray origin
var tvec = geom.Sub(ray.Origin, tri.a)
// calculate U parameter and test bounds
var u = geom.Dot(tvec, pvec) * inv_det
if u < 0.0 || u > 1.0 {
return false
}
// prepare to test V parameter
var qvec = geom.Cross(tvec, edge1)
// calculate V parameter and test bounds
var v = geom.Dot(ray.Direction, qvec) * inv_det
- if v < 0.0 || v > 1.0 {
+ if v < 0.0 || u+v > 1.0 {
return false
}
// calculate t, if t >= 0 ray intersects triangle
var t = geom.Dot(edge2, qvec) * inv_det
if t >= 0 {
return true
}
return false
}
// Intersect returns bool that is true if ray intersects
// the Quad pointed to by q.
// Reduce the quad to to two triangles.
// However first take into consideration whether the quad is concave.
// In order to evaluate whether the quad is concave we will
// use that the the dot product of the vectors forming the
// angle is negative when the angle itself is obtuse.
// Whether alpha or gamma is obtuse is irrelevant.
// Same applies to beta and delta.
func (q *Quad) Intersect(ray geom.Ray) bool {
var alpha = geom.Dot(geom.Sub(q.a, q.d), geom.Sub(q.b, q.a))
var gamma = geom.Dot(geom.Sub(q.c, q.b), geom.Sub(q.d, q.c))
if alpha < 0.0 || gamma < 0.0 {
return NewTriangle(q.a, q.b, q.c).Intersect(ray) ||
NewTriangle(q.a, q.c, q.d).Intersect(ray)
}
// no check needed since only one angle can be obtuse in a quadrilateral
return NewTriangle(q.a, q.b, q.d).Intersect(ray) ||
NewTriangle(q.b, q.c, q.d).Intersect(ray)
}
// Intersect returns bool that is true if ray intersects
// the Sphere pointed to by s.
// Implementation of basic geometry algorithm.
// Source: https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection
func (s *Sphere) Intersect(ray geom.Ray) bool {
var l = geom.Sub(s.origin, ray.Origin)
var tca = geom.Dot(l, ray.Direction)
- var d2 = geom.Dot(l, l) + tca*tca
+ var d2 = geom.Dot(l, l) - tca*tca
var r2 = s.r * s.r
if d2 > r2 {
return false
}
var thc = math.Sqrt(r2 - d2)
var t0 = tca - thc
var t1 = tca + thc
// the ray origin might be inside the sphere
// that is why we check both intersection points
if t0 >= 0 || t1 >= 0 {
return true
}
return false
}
func main() {
}

Също така, като ти разглеждам домашното попадаш в двете категории за манипулация с точки. Първо, искам да ти намаля с една защото не си минал всички тестове и не заслужаваш пълен брой точки. Но същевременно искам да ти дам една заради добре документирания код. За това оставаш без манипулации :D