Решение на Пресичания от Николай Лазаров

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

Към профила на Николай Лазаров

Резултати

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

Код

package main
import "github.com/fmi/go-homework/geom"
const EPSILON = 1e-7
type Triangle struct {
a, b, c geom.Vector
}
type Quad struct {
a, b, c, d geom.Vector
}
type Sphere struct {
origin geom.Vector
radius float64
}
func abs(f float64) float64 {
if f < 0 {
return -f
}
return f
}
func normal(a *geom.Vector, b *geom.Vector) geom.Vector {
return geom.NewVector(
a.Y*b.Z-a.Z*b.Y,
a.Z*b.X-a.X*b.Z,
a.X*b.Y-a.Y*b.X,
)
}
func diff(a *geom.Vector, b *geom.Vector) geom.Vector {
return geom.NewVector(
a.X-b.X,
a.Y-b.Y,
a.Z-b.Z,
)
}
func scalar(a *geom.Vector, b *geom.Vector) float64 {
return a.X*b.X + a.Y*b.Y + a.Z*b.Z
}
func orthogonal(a *geom.Vector, b *geom.Vector) bool {
return abs(scalar(a, b)) < EPSILON
}
func add(a *geom.Vector, b *geom.Vector) geom.Vector {
return geom.NewVector(
a.X+b.X,
a.Y+b.Y,
a.Z+b.Z,
)
}
func mult(t float64, a *geom.Vector) geom.Vector {
return geom.NewVector(
t*a.X,
t*a.Y,
t*a.Z,
)
}
func (t Triangle) Intersect(ray geom.Ray) bool {
v1 := diff(&t.b, &t.a)
v2 := diff(&t.c, &t.a)
n := normal(&v1, &v2)
d := scalar(&n, &t.a)
if orthogonal(&ray.Direction, &n) {
// check if ray is outside the plane
if abs(scalar(&n, &ray.Origin)-d) >= EPSILON {
return false
}
// TODO: check if ray crosses triangle
return false
} else {
// compute intersection point
param := (d - scalar(&n, &ray.Origin)) / scalar(&n, &ray.Direction)
if param < 0 {
// ray is pointing away
return false
}
tmp := mult(param, &ray.Direction) // thank you golang
intersection := add(&ray.Origin, &tmp)
v3 := diff(&intersection, &t.a)
// compute dot products
dot11 := scalar(&v1, &v1)
dot12 := scalar(&v1, &v2)
dot13 := scalar(&v1, &v3)
dot22 := scalar(&v2, &v2)
dot23 := scalar(&v2, &v3)
// compute barycentric coordinates
inv_denom := 1 / (dot11*dot22 - dot12*dot12)
u := (dot22*dot13 - dot12*dot23) * inv_denom
v := (dot11*dot23 - dot12*dot13) * inv_denom
// check if point is in triangle
return u >= 0 && v >= 0 && (u+v) <= 1
}
}
func (q Quad) Intersect(ray geom.Ray) bool {
t1 := NewTriangle(q.a, q.b, q.c)
t2 := NewTriangle(q.a, q.c, q.d)
t3 := NewTriangle(q.d, q.a, q.b)
t4 := NewTriangle(q.d, q.b, q.c)
return (t1.Intersect(ray) || t2.Intersect(ray)) && (t3.Intersect(ray) || t4.Intersect(ray))
}
func (s Sphere) Intersect(ray geom.Ray) bool {
v := diff(&s.origin, &ray.Origin)
// check if the ray starts from the sphere
if scalar(&v, &v) <= s.radius*s.radius {
return true
}
t := scalar(&v, &ray.Direction) / scalar(&ray.Direction, &ray.Direction)
if t < 0 {
// ray is pointing away
return false
}
tmp := mult(t, &ray.Direction) // thank you golang
projection := add(&ray.Origin, &tmp)
d := diff(&projection, &s.origin)
distance_squared := scalar(&d, &d)
return distance_squared <= s.radius*s.radius
}
func NewTriangle(a, b, c geom.Vector) Triangle {
return Triangle{
a: a,
b: b,
c: c,
}
}
func NewQuad(a, b, c, d geom.Vector) Quad {
return Quad{
a: a,
b: b,
c: c,
d: d,
}
}
func NewSphere(origin geom.Vector, r float64) Sphere {
return Sphere{
origin: origin,
radius: r,
}
}

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

PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s
PASS
ok  	_/tmp/d20181122-57-14d9132	0.002s

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

Николай обнови решението на 18.11.2018 19:15 (преди 9 месеца)

+package main
+
+import "github.com/fmi/go-homework/geom"
+
+const EPSILON = 0.00001
+
+type Triangle struct {
+ a, b, c geom.Vector
+}
+
+type Quad struct {
+ a, b, c, d geom.Vector
+}
+
+type Sphere struct {
+ origin geom.Vector
+ radius float64
+}
+
+func abs(f float64) float64 {
+ if f < 0 {
+ return -f
+ }
+ return f
+}
+
+func normal(a *geom.Vector, b *geom.Vector) geom.Vector {
+ return geom.NewVector(
+ a.Y*b.Z-a.Z*b.Y,
+ a.Z*b.X-a.X*b.Z,
+ a.X*b.Y-a.Y*b.X,
+ )
+}
+
+func diff(a *geom.Vector, b *geom.Vector) geom.Vector {
+ return geom.NewVector(
+ a.X-b.X,
+ a.Y-b.Y,
+ a.Z-b.Z,
+ )
+}
+
+func scalar(a *geom.Vector, b *geom.Vector) float64 {
+ return a.X*b.X + a.Y*b.Y + a.Z*b.Z
+}
+
+func orthogonal(a *geom.Vector, b *geom.Vector) bool {
+ return abs(scalar(a, b)) < EPSILON
+}
+
+func add(a *geom.Vector, b *geom.Vector) geom.Vector {
+ return geom.NewVector(
+ a.X+b.X,
+ a.Y+b.Y,
+ a.Z+b.Z,
+ )
+}
+
+func mult(t float64, a *geom.Vector) geom.Vector {
+ return geom.NewVector(
+ t*a.X,
+ t*a.Y,
+ t*a.Z,
+ )
+}
+
+func (t Triangle) Intersect(ray geom.Ray) bool {
+ v1 := diff(&t.b, &t.a)
+ v2 := diff(&t.c, &t.a)
+ n := normal(&v1, &v2)
+ d := scalar(&n, &t.a)
+
+ if orthogonal(&ray.Direction, &n) {
+ // check if ray is outside the plane
+ if abs(scalar(&n, &ray.Origin)-d) >= EPSILON {
+ return false
+ }
+
+ // TODO: check if ray crosses triangle
+ return false
+ } else {
+ // compute intersection point
+ param := (d - scalar(&n, &ray.Origin)) / scalar(&n, &ray.Direction)
+
+ if param < 0 {
+ // ray is pointing away
+ return false
+ }
+
+ tmp := mult(param, &ray.Direction) // thank you golang
+ intersection := add(&ray.Origin, &tmp)
+ v3 := diff(&intersection, &t.a)
+
+ // compute dot products
+ dot11 := scalar(&v1, &v1)
+ dot12 := scalar(&v1, &v2)
+ dot13 := scalar(&v1, &v3)
+ dot22 := scalar(&v2, &v2)
+ dot23 := scalar(&v2, &v3)
+
+ // compute barycentric coordinates
+ inv_denom := 1 / (dot11*dot22 - dot12*dot12)
+ u := (dot22*dot13 - dot12*dot23) * inv_denom
+ v := (dot11*dot23 - dot12*dot13) * inv_denom
+
+ // check if point is in triangle
+ return u >= 0 && v >= 0 && (u+v) <= 1
+ }
+}
+
+func (q Quad) Intersect(ray geom.Ray) bool {
+ t1 := NewTriangle(q.a, q.b, q.c)
+ t2 := NewTriangle(q.a, q.c, q.d)
+ t3 := NewTriangle(q.a, q.b, q.d)
+ return t1.Intersect(ray) || t2.Intersect(ray) || t3.Intersect(ray)
+}
+
+func (s Sphere) Intersect(ray geom.Ray) bool {
+ v := diff(&s.origin, &ray.Origin)
+
+ // check if the ray starts from the sphere
+ if scalar(&v, &v) <= s.radius*s.radius {
+ return true
+ }
+
+ t := scalar(&v, &ray.Direction) / scalar(&ray.Direction, &ray.Direction)
+
+ if t < 0 {
+ // ray is pointing away
+ return false
+ }
+
+ tmp := mult(t, &ray.Direction) // thank you golang
+ projection := add(&ray.Origin, &tmp)
+
+ d := diff(&projection, &s.origin)
+ distance_squared := scalar(&d, &d)
+
+ return distance_squared <= s.radius*s.radius
+}
+
+func NewTriangle(a, b, c geom.Vector) Triangle {
+ return Triangle{
+ a: a,
+ b: b,
+ c: c,
+ }
+}
+
+func NewQuad(a, b, c, d geom.Vector) Quad {
+ return Quad{
+ a: a,
+ b: b,
+ c: c,
+ d: d,
+ }
+}
+
+func NewSphere(origin geom.Vector, r float64) Sphere {
+ return Sphere{
+ origin: origin,
+ radius: r,
+ }
+}

Николай обнови решението на 20.11.2018 15:00 (преди 9 месеца)

package main
import "github.com/fmi/go-homework/geom"
const EPSILON = 0.00001
type Triangle struct {
a, b, c geom.Vector
}
type Quad struct {
a, b, c, d geom.Vector
}
type Sphere struct {
origin geom.Vector
radius float64
}
func abs(f float64) float64 {
if f < 0 {
return -f
}
return f
}
func normal(a *geom.Vector, b *geom.Vector) geom.Vector {
return geom.NewVector(
a.Y*b.Z-a.Z*b.Y,
a.Z*b.X-a.X*b.Z,
a.X*b.Y-a.Y*b.X,
)
}
func diff(a *geom.Vector, b *geom.Vector) geom.Vector {
return geom.NewVector(
a.X-b.X,
a.Y-b.Y,
a.Z-b.Z,
)
}
func scalar(a *geom.Vector, b *geom.Vector) float64 {
return a.X*b.X + a.Y*b.Y + a.Z*b.Z
}
func orthogonal(a *geom.Vector, b *geom.Vector) bool {
return abs(scalar(a, b)) < EPSILON
}
func add(a *geom.Vector, b *geom.Vector) geom.Vector {
return geom.NewVector(
a.X+b.X,
a.Y+b.Y,
a.Z+b.Z,
)
}
func mult(t float64, a *geom.Vector) geom.Vector {
return geom.NewVector(
t*a.X,
t*a.Y,
t*a.Z,
)
}
func (t Triangle) Intersect(ray geom.Ray) bool {
v1 := diff(&t.b, &t.a)
v2 := diff(&t.c, &t.a)
n := normal(&v1, &v2)
d := scalar(&n, &t.a)
if orthogonal(&ray.Direction, &n) {
// check if ray is outside the plane
if abs(scalar(&n, &ray.Origin)-d) >= EPSILON {
return false
}
// TODO: check if ray crosses triangle
return false
} else {
// compute intersection point
param := (d - scalar(&n, &ray.Origin)) / scalar(&n, &ray.Direction)
if param < 0 {
// ray is pointing away
return false
}
tmp := mult(param, &ray.Direction) // thank you golang
intersection := add(&ray.Origin, &tmp)
v3 := diff(&intersection, &t.a)
// compute dot products
dot11 := scalar(&v1, &v1)
dot12 := scalar(&v1, &v2)
dot13 := scalar(&v1, &v3)
dot22 := scalar(&v2, &v2)
dot23 := scalar(&v2, &v3)
// compute barycentric coordinates
inv_denom := 1 / (dot11*dot22 - dot12*dot12)
u := (dot22*dot13 - dot12*dot23) * inv_denom
v := (dot11*dot23 - dot12*dot13) * inv_denom
// check if point is in triangle
return u >= 0 && v >= 0 && (u+v) <= 1
}
}
func (q Quad) Intersect(ray geom.Ray) bool {
t1 := NewTriangle(q.a, q.b, q.c)
t2 := NewTriangle(q.a, q.c, q.d)
- t3 := NewTriangle(q.a, q.b, q.d)
- return t1.Intersect(ray) || t2.Intersect(ray) || t3.Intersect(ray)
+ return t1.Intersect(ray) || t2.Intersect(ray)
}
func (s Sphere) Intersect(ray geom.Ray) bool {
v := diff(&s.origin, &ray.Origin)
// check if the ray starts from the sphere
if scalar(&v, &v) <= s.radius*s.radius {
return true
}
t := scalar(&v, &ray.Direction) / scalar(&ray.Direction, &ray.Direction)
if t < 0 {
// ray is pointing away
return false
}
tmp := mult(t, &ray.Direction) // thank you golang
projection := add(&ray.Origin, &tmp)
d := diff(&projection, &s.origin)
distance_squared := scalar(&d, &d)
return distance_squared <= s.radius*s.radius
}
func NewTriangle(a, b, c geom.Vector) Triangle {
return Triangle{
a: a,
b: b,
c: c,
}
}
func NewQuad(a, b, c, d geom.Vector) Quad {
return Quad{
a: a,
b: b,
c: c,
d: d,
}
}
func NewSphere(origin geom.Vector, r float64) Sphere {
return Sphere{
origin: origin,
radius: r,
}
}

Николай обнови решението на 20.11.2018 18:18 (преди 9 месеца)

package main
import "github.com/fmi/go-homework/geom"
const EPSILON = 0.00001
type Triangle struct {
a, b, c geom.Vector
}
type Quad struct {
a, b, c, d geom.Vector
}
type Sphere struct {
origin geom.Vector
radius float64
}
func abs(f float64) float64 {
if f < 0 {
return -f
}
return f
}
func normal(a *geom.Vector, b *geom.Vector) geom.Vector {
return geom.NewVector(
a.Y*b.Z-a.Z*b.Y,
a.Z*b.X-a.X*b.Z,
a.X*b.Y-a.Y*b.X,
)
}
func diff(a *geom.Vector, b *geom.Vector) geom.Vector {
return geom.NewVector(
a.X-b.X,
a.Y-b.Y,
a.Z-b.Z,
)
}
func scalar(a *geom.Vector, b *geom.Vector) float64 {
return a.X*b.X + a.Y*b.Y + a.Z*b.Z
}
func orthogonal(a *geom.Vector, b *geom.Vector) bool {
return abs(scalar(a, b)) < EPSILON
}
func add(a *geom.Vector, b *geom.Vector) geom.Vector {
return geom.NewVector(
a.X+b.X,
a.Y+b.Y,
a.Z+b.Z,
)
}
func mult(t float64, a *geom.Vector) geom.Vector {
return geom.NewVector(
t*a.X,
t*a.Y,
t*a.Z,
)
}
func (t Triangle) Intersect(ray geom.Ray) bool {
v1 := diff(&t.b, &t.a)
v2 := diff(&t.c, &t.a)
n := normal(&v1, &v2)
d := scalar(&n, &t.a)
if orthogonal(&ray.Direction, &n) {
// check if ray is outside the plane
if abs(scalar(&n, &ray.Origin)-d) >= EPSILON {
return false
}
// TODO: check if ray crosses triangle
return false
} else {
// compute intersection point
param := (d - scalar(&n, &ray.Origin)) / scalar(&n, &ray.Direction)
if param < 0 {
// ray is pointing away
return false
}
tmp := mult(param, &ray.Direction) // thank you golang
intersection := add(&ray.Origin, &tmp)
v3 := diff(&intersection, &t.a)
// compute dot products
dot11 := scalar(&v1, &v1)
dot12 := scalar(&v1, &v2)
dot13 := scalar(&v1, &v3)
dot22 := scalar(&v2, &v2)
dot23 := scalar(&v2, &v3)
// compute barycentric coordinates
inv_denom := 1 / (dot11*dot22 - dot12*dot12)
u := (dot22*dot13 - dot12*dot23) * inv_denom
v := (dot11*dot23 - dot12*dot13) * inv_denom
// check if point is in triangle
return u >= 0 && v >= 0 && (u+v) <= 1
}
}
func (q Quad) Intersect(ray geom.Ray) bool {
t1 := NewTriangle(q.a, q.b, q.c)
t2 := NewTriangle(q.a, q.c, q.d)
- return t1.Intersect(ray) || t2.Intersect(ray)
+
+ t3 := NewTriangle(q.d, q.a, q.b)
+ t4 := NewTriangle(q.d, q.b, q.c)
+
+
+ return (t1.Intersect(ray) || t2.Intersect(ray)) && (t3.Intersect(ray) || t4.Intersect(ray))
}
func (s Sphere) Intersect(ray geom.Ray) bool {
v := diff(&s.origin, &ray.Origin)
// check if the ray starts from the sphere
if scalar(&v, &v) <= s.radius*s.radius {
return true
}
t := scalar(&v, &ray.Direction) / scalar(&ray.Direction, &ray.Direction)
if t < 0 {
// ray is pointing away
return false
}
tmp := mult(t, &ray.Direction) // thank you golang
projection := add(&ray.Origin, &tmp)
d := diff(&projection, &s.origin)
distance_squared := scalar(&d, &d)
return distance_squared <= s.radius*s.radius
}
func NewTriangle(a, b, c geom.Vector) Triangle {
return Triangle{
a: a,
b: b,
c: c,
}
}
func NewQuad(a, b, c, d geom.Vector) Quad {
return Quad{
a: a,
b: b,
c: c,
d: d,
}
}
func NewSphere(origin geom.Vector, r float64) Sphere {
return Sphere{
origin: origin,
radius: r,
}
-}
+}

Николай обнови решението на 21.11.2018 11:30 (преди 9 месеца)

package main
import "github.com/fmi/go-homework/geom"
-const EPSILON = 0.00001
+const EPSILON = 1e-7
type Triangle struct {
a, b, c geom.Vector
}
type Quad struct {
a, b, c, d geom.Vector
}
type Sphere struct {
origin geom.Vector
radius float64
}
func abs(f float64) float64 {
if f < 0 {
return -f
}
return f
}
func normal(a *geom.Vector, b *geom.Vector) geom.Vector {
return geom.NewVector(
a.Y*b.Z-a.Z*b.Y,
a.Z*b.X-a.X*b.Z,
a.X*b.Y-a.Y*b.X,
)
}
func diff(a *geom.Vector, b *geom.Vector) geom.Vector {
return geom.NewVector(
a.X-b.X,
a.Y-b.Y,
a.Z-b.Z,
)
}
func scalar(a *geom.Vector, b *geom.Vector) float64 {
return a.X*b.X + a.Y*b.Y + a.Z*b.Z
}
func orthogonal(a *geom.Vector, b *geom.Vector) bool {
return abs(scalar(a, b)) < EPSILON
}
func add(a *geom.Vector, b *geom.Vector) geom.Vector {
return geom.NewVector(
a.X+b.X,
a.Y+b.Y,
a.Z+b.Z,
)
}
func mult(t float64, a *geom.Vector) geom.Vector {
return geom.NewVector(
t*a.X,
t*a.Y,
t*a.Z,
)
}
func (t Triangle) Intersect(ray geom.Ray) bool {
v1 := diff(&t.b, &t.a)
v2 := diff(&t.c, &t.a)
n := normal(&v1, &v2)
d := scalar(&n, &t.a)
if orthogonal(&ray.Direction, &n) {
// check if ray is outside the plane
if abs(scalar(&n, &ray.Origin)-d) >= EPSILON {
return false
}
// TODO: check if ray crosses triangle
return false
} else {
// compute intersection point
param := (d - scalar(&n, &ray.Origin)) / scalar(&n, &ray.Direction)
if param < 0 {
// ray is pointing away
return false
}
tmp := mult(param, &ray.Direction) // thank you golang
intersection := add(&ray.Origin, &tmp)
v3 := diff(&intersection, &t.a)
// compute dot products
dot11 := scalar(&v1, &v1)
dot12 := scalar(&v1, &v2)
dot13 := scalar(&v1, &v3)
dot22 := scalar(&v2, &v2)
dot23 := scalar(&v2, &v3)
// compute barycentric coordinates
inv_denom := 1 / (dot11*dot22 - dot12*dot12)
u := (dot22*dot13 - dot12*dot23) * inv_denom
v := (dot11*dot23 - dot12*dot13) * inv_denom
// check if point is in triangle
return u >= 0 && v >= 0 && (u+v) <= 1
}
}
func (q Quad) Intersect(ray geom.Ray) bool {
t1 := NewTriangle(q.a, q.b, q.c)
t2 := NewTriangle(q.a, q.c, q.d)
t3 := NewTriangle(q.d, q.a, q.b)
t4 := NewTriangle(q.d, q.b, q.c)
return (t1.Intersect(ray) || t2.Intersect(ray)) && (t3.Intersect(ray) || t4.Intersect(ray))
}
func (s Sphere) Intersect(ray geom.Ray) bool {
v := diff(&s.origin, &ray.Origin)
// check if the ray starts from the sphere
if scalar(&v, &v) <= s.radius*s.radius {
return true
}
t := scalar(&v, &ray.Direction) / scalar(&ray.Direction, &ray.Direction)
if t < 0 {
// ray is pointing away
return false
}
tmp := mult(t, &ray.Direction) // thank you golang
projection := add(&ray.Origin, &tmp)
d := diff(&projection, &s.origin)
distance_squared := scalar(&d, &d)
return distance_squared <= s.radius*s.radius
}
func NewTriangle(a, b, c geom.Vector) Triangle {
return Triangle{
a: a,
b: b,
c: c,
}
}
func NewQuad(a, b, c, d geom.Vector) Quad {
return Quad{
a: a,
b: b,
c: c,
d: d,
}
}
func NewSphere(origin geom.Vector, r float64) Sphere {
return Sphere{
origin: origin,
radius: r,
}
}