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

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

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

Резултати

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

Код

package main
import (
"math"
"github.com/fmi/go-homework/geom"
)
type Triangle struct {
A, B, C geom.Vector
}
func NewTriangle(a, b, c geom.Vector) Triangle {
return Triangle{
A: a,
B: b,
C: c,
}
}
func (triangle Triangle) Intersect(ray geom.Ray) bool {
epsilon := 0.0000001
var edge1, edge2 geom.Vector
edge1 = Sub(triangle.B, triangle.A)
edge2 = Sub(triangle.C, triangle.A)
crossProduct := Cross(edge1, edge2)
dir := Sub(ray.Direction, ray.Origin)
dotProduct := Dot(crossProduct, dir)
if math.Abs(dotProduct) < epsilon {
return false
}
diff := Sub(ray.Origin, triangle.A)
a := -1 * Dot(crossProduct, diff)
if a/dotProduct < 0.0 {
return false
}
intersectPoint := Add(ray.Origin, Mul(dir, a/dotProduct))
aa := Dot(edge1, edge1)
ab := Dot(edge1, edge2)
bb := Dot(edge2, edge2)
w := Sub(intersectPoint, triangle.A)
wa := Dot(w, edge1)
wb := Dot(w, edge2)
quadraticDiff := ab*ab - aa*bb
intersectedSide := (ab*wb - bb*wa) / quadraticDiff
if intersectedSide < 0.0 || intersectedSide > 1.0 {
return false
}
intersectedArea := (ab*wa - aa*wb) / quadraticDiff
if intersectedArea < 0.0 || (intersectedSide+intersectedArea) > 1.0 {
return false
}
return true
}
type Quad struct {
A, B, C, D geom.Vector
}
func NewQuad(a, b, c, d geom.Vector) Quad {
return Quad{
A: a,
B: b,
C: c,
D: d,
}
}
func (quad Quad) Intersect(ray geom.Ray) bool {
var firstTriangle Triangle
var secondTriangle Triangle
if S3(quad.A, quad.C, quad.B)*S3(quad.A, quad.C, quad.D) < 0.0 {
firstTriangle = NewTriangle(quad.A, quad.B, quad.C)
secondTriangle = NewTriangle(quad.A, quad.D, quad.C)
} else {
firstTriangle = NewTriangle(quad.B, quad.D, quad.C)
secondTriangle = NewTriangle(quad.B, quad.D, quad.A)
}
return firstTriangle.Intersect(ray) || secondTriangle.Intersect(ray)
}
type Sphere struct {
origin geom.Vector
R float64
}
func NewSphere(origin geom.Vector, r float64) Sphere {
return Sphere{
origin: origin,
R: r,
}
}
func (sphere Sphere) Intersect(ray geom.Ray) bool {
if ray.Origin.X == ray.Direction.X && ray.Origin.Y == ray.Direction.Y {
if ray.Origin.Z < ray.Direction.Z {
ray.Direction.Z = math.MaxFloat64
} else {
ray.Direction.Z = -1 * math.MaxFloat64
}
} else if ray.Origin.X == ray.Direction.X && ray.Origin.Z == ray.Direction.Z {
if ray.Origin.Y < ray.Direction.Y {
ray.Direction.Y = math.MaxFloat64
} else {
ray.Direction.Y = -1 * math.MaxFloat64
}
} else if ray.Origin.Y == ray.Direction.Y && ray.Origin.Z == ray.Direction.Z {
if ray.Origin.X < ray.Direction.X {
ray.Direction.X = math.MaxFloat64
} else {
ray.Direction.X = -1 * math.MaxFloat64
}
}
L := Sub(sphere.origin, ray.Origin)
tca := Dot(L, ray.Direction)
if tca < 0 {
return false
}
d2 := Dot(L, L) - tca*tca
if d2 > sphere.R {
return false
}
thc := math.Sqrt(sphere.R - d2)
t0 := tca - thc
t1 := tca + thc
if t0 > t1 {
t0, t1 = t1, t0
}
if t0 < 0 {
t0 = t1
if t0 < 0 {
return false
}
}
return true
}
func Dot(first, second geom.Vector) float64 {
return first.X*second.X + first.Y*second.Y + first.Z*second.Z
}
func Cross(first, second geom.Vector) geom.Vector {
return geom.Vector{
first.Y*second.Z - first.Z*second.Y,
first.Z*second.X - first.X*second.Z,
first.X*second.Y - first.Y*second.X,
}
}
func Abs(vektor geom.Vector) geom.Vector {
return geom.Vector{math.Abs(vektor.X), math.Abs(vektor.Y), math.Abs(vektor.Z)}
}
func Add(first, second geom.Vector) geom.Vector {
return geom.Vector{first.X + second.X, first.Y + second.Y, first.Z + second.Z}
}
func Sub(first, second geom.Vector) geom.Vector {
return geom.Vector{first.X - second.X, first.Y - second.Y, first.Z - second.Z}
}
func Mul(vektor geom.Vector, number float64) geom.Vector {
return geom.Vector{number * vektor.X, number * vektor.Y, number * vektor.Z}
}
func S3(A, B, C geom.Vector) float64 {
return S2(A, B) + S2(B, C) + S2(C, A)
}
func S2(A, B geom.Vector) float64 {
crossProduct := Cross(A, B)
return crossProduct.X * crossProduct.Y * crossProduct.Z / 3.0
}
func main() {
//EMPTY BODY
}

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

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

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

Кристиан обнови решението на 19.11.2018 20:40 (преди 9 месеца)

+package main
+
+import (
+ "math"
+
+ "github.com/fmi/go-homework/geom"
+)
+
+type Triangle struct {
+ A, B, C geom.Vector
+}
+
+type Quad struct {
+ A, B, C, D geom.Vector
+}
+
+type Sphere struct {
+ origin geom.Vector
+ R float64
+}
+
+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,
+ R: r,
+ }
+}
+
+func Dot(first, second geom.Vector) float64 {
+ return first.X*second.X + first.Y*second.Y + first.Z*second.Z
+}
+
+func Cross(first, second geom.Vector) geom.Vector {
+ return geom.Vector{
+ first.Y*second.Z - first.Z*second.Y,
+ first.Z*second.X - first.X*second.Z,
+ first.X*second.Y - first.Y*second.X,
+ }
+}
+
+func Abs(vektor geom.Vector) geom.Vector {
+ return geom.Vector{math.Abs(vektor.X), math.Abs(vektor.Y), math.Abs(vektor.Z)}
+}
+
+func Add(first, second geom.Vector) geom.Vector {
+ return geom.Vector{first.X + second.X, first.Y + second.Y, first.Z + second.Z}
+}
+
+func Sub(first, second geom.Vector) geom.Vector {
+ return geom.Vector{first.X - second.X, first.Y - second.Y, first.Z - second.Z}
+}
+
+func Mul(vektor geom.Vector, number float64) geom.Vector {
+ return geom.Vector{number * vektor.X, number * vektor.Y, number * vektor.Z}
+}
+
+func (triangle Triangle) Intersect(ray geom.Ray) bool {
+ epsiolon := 0.0000001
+
+ var edge1, edge2 geom.Vector
+ edge1 = Sub(triangle.B, triangle.A) // u
+ edge2 = Sub(triangle.C, triangle.A) // v
+ crossProduct := Cross(edge1, edge2) // n
+ if crossProduct.X == 0.0 && crossProduct.Y == 0.0 && crossProduct.Z == 0.0 {
+ return false
+ }
+
+ rayDirectrion := Sub(ray.Direction, ray.Origin)
+ diff := Sub(ray.Origin, triangle.A)
+ a := -Dot(crossProduct, diff)
+ b := Dot(crossProduct, rayDirectrion)
+
+ if math.Abs(b) < epsiolon {
+ if a == 0 {
+ return true
+ } else {
+ return false
+ }
+ }
+
+ if a/b < 0.0 {
+ return false
+ }
+
+ intersectPoint := Add(ray.Origin, Mul(rayDirectrion, a/b))
+ aa := Dot(edge1, edge1)
+ ab := Dot(edge1, edge2)
+ bb := Dot(edge2, edge2)
+ w := Sub(intersectPoint, triangle.A)
+ wa := Dot(w, edge1)
+ wb := Dot(w, edge2)
+ quadraticDiff := ab*ab - aa*bb
+ intersectedSide := (ab*wa - aa*wb) / quadraticDiff
+
+ if intersectedSide < 0.0 || intersectedSide > 1.0 {
+ return false
+ }
+
+ intersectedArea := (ab*wa - aa*wb) / quadraticDiff
+
+ if intersectedArea < 0.0 || (intersectedSide+intersectedArea) > 1.0 {
+ return false
+ }
+
+ return true
+}
+
+func (quad Quad) Intersect(ray geom.Ray) bool {
+ firstTriangle := NewTriangle(quad.A, quad.B, quad.C)
+ secondTriangle := NewTriangle(quad.C, quad.D, quad.A)
+ return firstTriangle.Intersect(ray) || secondTriangle.Intersect(ray)
+}
+
+func (sphere Sphere) Intersect(ray geom.Ray) bool {
+ L := Sub(sphere.origin, ray.Origin)
+ tca := Dot(L, ray.Direction)
+
+ if tca < 0 {
+ return false
+ }
+
+ d2 := Dot(L, L) - tca*tca
+ if d2 > sphere.R {
+ return false
+ }
+ thc := math.Sqrt(sphere.R - d2)
+ t0 := tca - thc
+ t1 := tca + thc
+ if t0 > t1 {
+ t0, t1 = t1, t0
+ }
+
+ if t0 < 0 {
+ t0 = t1
+ if t0 < 0 {
+ return false
+ }
+ }
+
+ return true
+}
+
+func main() {
+ //EMPTY BODY
+}

Кристиан обнови решението на 20.11.2018 11:27 (преди 9 месеца)

package main
import (
"math"
- "github.com/fmi/go-homework/geom"
+ "github.com/fmi/go-homework/geom"
)
type Triangle struct {
A, B, C geom.Vector
}
-type Quad struct {
- A, B, C, D geom.Vector
-}
-
-type Sphere struct {
- origin geom.Vector
- R float64
-}
-
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,
- R: r,
- }
-}
-
-func Dot(first, second geom.Vector) float64 {
- return first.X*second.X + first.Y*second.Y + first.Z*second.Z
-}
-
-func Cross(first, second geom.Vector) geom.Vector {
- return geom.Vector{
- first.Y*second.Z - first.Z*second.Y,
- first.Z*second.X - first.X*second.Z,
- first.X*second.Y - first.Y*second.X,
- }
-}
-
-func Abs(vektor geom.Vector) geom.Vector {
- return geom.Vector{math.Abs(vektor.X), math.Abs(vektor.Y), math.Abs(vektor.Z)}
-}
-
-func Add(first, second geom.Vector) geom.Vector {
- return geom.Vector{first.X + second.X, first.Y + second.Y, first.Z + second.Z}
-}
-
-func Sub(first, second geom.Vector) geom.Vector {
- return geom.Vector{first.X - second.X, first.Y - second.Y, first.Z - second.Z}
-}
-
-func Mul(vektor geom.Vector, number float64) geom.Vector {
- return geom.Vector{number * vektor.X, number * vektor.Y, number * vektor.Z}
-}
-
func (triangle Triangle) Intersect(ray geom.Ray) bool {
epsiolon := 0.0000001
var edge1, edge2 geom.Vector
edge1 = Sub(triangle.B, triangle.A) // u
edge2 = Sub(triangle.C, triangle.A) // v
crossProduct := Cross(edge1, edge2) // n
if crossProduct.X == 0.0 && crossProduct.Y == 0.0 && crossProduct.Z == 0.0 {
return false
}
rayDirectrion := Sub(ray.Direction, ray.Origin)
diff := Sub(ray.Origin, triangle.A)
a := -Dot(crossProduct, diff)
b := Dot(crossProduct, rayDirectrion)
if math.Abs(b) < epsiolon {
if a == 0 {
return true
} else {
return false
}
}
if a/b < 0.0 {
return false
}
intersectPoint := Add(ray.Origin, Mul(rayDirectrion, a/b))
aa := Dot(edge1, edge1)
ab := Dot(edge1, edge2)
bb := Dot(edge2, edge2)
w := Sub(intersectPoint, triangle.A)
wa := Dot(w, edge1)
wb := Dot(w, edge2)
quadraticDiff := ab*ab - aa*bb
intersectedSide := (ab*wa - aa*wb) / quadraticDiff
if intersectedSide < 0.0 || intersectedSide > 1.0 {
return false
}
intersectedArea := (ab*wa - aa*wb) / quadraticDiff
if intersectedArea < 0.0 || (intersectedSide+intersectedArea) > 1.0 {
return false
}
return true
}
+type Quad struct {
+ A, B, C, D geom.Vector
+}
+
+func NewQuad(a, b, c, d geom.Vector) Quad {
+ return Quad{
+ A: a,
+ B: b,
+ C: c,
+ D: d,
+ }
+}
+
func (quad Quad) Intersect(ray geom.Ray) bool {
firstTriangle := NewTriangle(quad.A, quad.B, quad.C)
secondTriangle := NewTriangle(quad.C, quad.D, quad.A)
return firstTriangle.Intersect(ray) || secondTriangle.Intersect(ray)
}
+type Sphere struct {
+ origin geom.Vector
+ R float64
+}
+
+func NewSphere(origin geom.Vector, r float64) Sphere {
+ return Sphere{
+ origin: origin,
+ R: r,
+ }
+}
+
func (sphere Sphere) Intersect(ray geom.Ray) bool {
L := Sub(sphere.origin, ray.Origin)
tca := Dot(L, ray.Direction)
if tca < 0 {
return false
}
d2 := Dot(L, L) - tca*tca
if d2 > sphere.R {
return false
}
thc := math.Sqrt(sphere.R - d2)
t0 := tca - thc
t1 := tca + thc
if t0 > t1 {
t0, t1 = t1, t0
}
if t0 < 0 {
t0 = t1
if t0 < 0 {
return false
}
}
return true
+}
+
+func Dot(first, second geom.Vector) float64 {
+ return first.X*second.X + first.Y*second.Y + first.Z*second.Z
+}
+
+func Cross(first, second geom.Vector) geom.Vector {
+ return geom.Vector{
+ first.Y*second.Z - first.Z*second.Y,
+ first.Z*second.X - first.X*second.Z,
+ first.X*second.Y - first.Y*second.X,
+ }
+}
+
+func Abs(vektor geom.Vector) geom.Vector {
+ return geom.Vector{math.Abs(vektor.X), math.Abs(vektor.Y), math.Abs(vektor.Z)}
+}
+
+func Add(first, second geom.Vector) geom.Vector {
+ return geom.Vector{first.X + second.X, first.Y + second.Y, first.Z + second.Z}
+}
+
+func Sub(first, second geom.Vector) geom.Vector {
+ return geom.Vector{first.X - second.X, first.Y - second.Y, first.Z - second.Z}
+}
+
+func Mul(vektor geom.Vector, number float64) geom.Vector {
+ return geom.Vector{number * vektor.X, number * vektor.Y, number * vektor.Z}
}
func main() {
//EMPTY BODY
}

Кристиан обнови решението на 20.11.2018 11:43 (преди 9 месеца)

package main
import (
"math"
"github.com/fmi/go-homework/geom"
)
type Triangle struct {
A, B, C geom.Vector
}
func NewTriangle(a, b, c geom.Vector) Triangle {
return Triangle{
A: a,
B: b,
C: c,
}
}
func (triangle Triangle) Intersect(ray geom.Ray) bool {
epsiolon := 0.0000001
var edge1, edge2 geom.Vector
- edge1 = Sub(triangle.B, triangle.A) // u
- edge2 = Sub(triangle.C, triangle.A) // v
- crossProduct := Cross(edge1, edge2) // n
+ edge1 = Sub(triangle.B, triangle.A)
+ edge2 = Sub(triangle.C, triangle.A)
+ crossProduct := Cross(edge1, edge2)
if crossProduct.X == 0.0 && crossProduct.Y == 0.0 && crossProduct.Z == 0.0 {
return false
}
rayDirectrion := Sub(ray.Direction, ray.Origin)
diff := Sub(ray.Origin, triangle.A)
a := -Dot(crossProduct, diff)
b := Dot(crossProduct, rayDirectrion)
if math.Abs(b) < epsiolon {
if a == 0 {
return true
} else {
return false
}
}
if a/b < 0.0 {
return false
}
intersectPoint := Add(ray.Origin, Mul(rayDirectrion, a/b))
aa := Dot(edge1, edge1)
ab := Dot(edge1, edge2)
bb := Dot(edge2, edge2)
w := Sub(intersectPoint, triangle.A)
wa := Dot(w, edge1)
wb := Dot(w, edge2)
quadraticDiff := ab*ab - aa*bb
intersectedSide := (ab*wa - aa*wb) / quadraticDiff
if intersectedSide < 0.0 || intersectedSide > 1.0 {
return false
}
intersectedArea := (ab*wa - aa*wb) / quadraticDiff
if intersectedArea < 0.0 || (intersectedSide+intersectedArea) > 1.0 {
return false
}
return true
}
type Quad struct {
A, B, C, D geom.Vector
}
func NewQuad(a, b, c, d geom.Vector) Quad {
return Quad{
A: a,
B: b,
C: c,
D: d,
}
}
func (quad Quad) Intersect(ray geom.Ray) bool {
firstTriangle := NewTriangle(quad.A, quad.B, quad.C)
secondTriangle := NewTriangle(quad.C, quad.D, quad.A)
return firstTriangle.Intersect(ray) || secondTriangle.Intersect(ray)
}
type Sphere struct {
origin geom.Vector
R float64
}
func NewSphere(origin geom.Vector, r float64) Sphere {
return Sphere{
origin: origin,
R: r,
}
}
func (sphere Sphere) Intersect(ray geom.Ray) bool {
L := Sub(sphere.origin, ray.Origin)
tca := Dot(L, ray.Direction)
if tca < 0 {
return false
}
d2 := Dot(L, L) - tca*tca
if d2 > sphere.R {
return false
}
thc := math.Sqrt(sphere.R - d2)
t0 := tca - thc
t1 := tca + thc
if t0 > t1 {
t0, t1 = t1, t0
}
if t0 < 0 {
t0 = t1
if t0 < 0 {
return false
}
}
return true
}
func Dot(first, second geom.Vector) float64 {
return first.X*second.X + first.Y*second.Y + first.Z*second.Z
}
func Cross(first, second geom.Vector) geom.Vector {
return geom.Vector{
first.Y*second.Z - first.Z*second.Y,
first.Z*second.X - first.X*second.Z,
first.X*second.Y - first.Y*second.X,
}
}
func Abs(vektor geom.Vector) geom.Vector {
return geom.Vector{math.Abs(vektor.X), math.Abs(vektor.Y), math.Abs(vektor.Z)}
}
func Add(first, second geom.Vector) geom.Vector {
return geom.Vector{first.X + second.X, first.Y + second.Y, first.Z + second.Z}
}
func Sub(first, second geom.Vector) geom.Vector {
return geom.Vector{first.X - second.X, first.Y - second.Y, first.Z - second.Z}
}
func Mul(vektor geom.Vector, number float64) geom.Vector {
return geom.Vector{number * vektor.X, number * vektor.Y, number * vektor.Z}
}
func main() {
//EMPTY BODY
-}
+}

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

package main
import (
"math"
"github.com/fmi/go-homework/geom"
)
type Triangle struct {
A, B, C geom.Vector
}
func NewTriangle(a, b, c geom.Vector) Triangle {
return Triangle{
A: a,
B: b,
C: c,
}
}
func (triangle Triangle) Intersect(ray geom.Ray) bool {
epsiolon := 0.0000001
var edge1, edge2 geom.Vector
edge1 = Sub(triangle.B, triangle.A)
edge2 = Sub(triangle.C, triangle.A)
crossProduct := Cross(edge1, edge2)
if crossProduct.X == 0.0 && crossProduct.Y == 0.0 && crossProduct.Z == 0.0 {
return false
}
rayDirectrion := Sub(ray.Direction, ray.Origin)
diff := Sub(ray.Origin, triangle.A)
a := -Dot(crossProduct, diff)
b := Dot(crossProduct, rayDirectrion)
if math.Abs(b) < epsiolon {
if a == 0 {
return true
} else {
return false
}
}
if a/b < 0.0 {
return false
}
intersectPoint := Add(ray.Origin, Mul(rayDirectrion, a/b))
aa := Dot(edge1, edge1)
ab := Dot(edge1, edge2)
bb := Dot(edge2, edge2)
w := Sub(intersectPoint, triangle.A)
wa := Dot(w, edge1)
wb := Dot(w, edge2)
quadraticDiff := ab*ab - aa*bb
intersectedSide := (ab*wa - aa*wb) / quadraticDiff
if intersectedSide < 0.0 || intersectedSide > 1.0 {
return false
}
intersectedArea := (ab*wa - aa*wb) / quadraticDiff
if intersectedArea < 0.0 || (intersectedSide+intersectedArea) > 1.0 {
return false
}
return true
}
type Quad struct {
A, B, C, D geom.Vector
}
func NewQuad(a, b, c, d geom.Vector) Quad {
return Quad{
A: a,
B: b,
C: c,
D: d,
}
}
func (quad Quad) Intersect(ray geom.Ray) bool {
- firstTriangle := NewTriangle(quad.A, quad.B, quad.C)
- secondTriangle := NewTriangle(quad.C, quad.D, quad.A)
+ var firstTriangle Triangle
+ var secondTriangle Triangle
+
+ if areIntersect(quad.A, quad.C, quad.B, quad.D) {
+ firstTriangle = NewTriangle(quad.A, quad.B, quad.C)
+ secondTriangle = NewTriangle(quad.C, quad.D, quad.A)
+ } else {
+ firstTriangle = NewTriangle(quad.A, quad.B, quad.D)
+ secondTriangle = NewTriangle(quad.C, quad.B, quad.D)
+ }
+
return firstTriangle.Intersect(ray) || secondTriangle.Intersect(ray)
}
type Sphere struct {
origin geom.Vector
R float64
}
func NewSphere(origin geom.Vector, r float64) Sphere {
return Sphere{
origin: origin,
R: r,
}
}
func (sphere Sphere) Intersect(ray geom.Ray) bool {
L := Sub(sphere.origin, ray.Origin)
tca := Dot(L, ray.Direction)
if tca < 0 {
return false
}
d2 := Dot(L, L) - tca*tca
if d2 > sphere.R {
return false
}
thc := math.Sqrt(sphere.R - d2)
t0 := tca - thc
t1 := tca + thc
if t0 > t1 {
t0, t1 = t1, t0
}
if t0 < 0 {
t0 = t1
if t0 < 0 {
return false
}
}
return true
}
func Dot(first, second geom.Vector) float64 {
return first.X*second.X + first.Y*second.Y + first.Z*second.Z
}
func Cross(first, second geom.Vector) geom.Vector {
return geom.Vector{
first.Y*second.Z - first.Z*second.Y,
first.Z*second.X - first.X*second.Z,
first.X*second.Y - first.Y*second.X,
}
}
func Abs(vektor geom.Vector) geom.Vector {
return geom.Vector{math.Abs(vektor.X), math.Abs(vektor.Y), math.Abs(vektor.Z)}
}
func Add(first, second geom.Vector) geom.Vector {
return geom.Vector{first.X + second.X, first.Y + second.Y, first.Z + second.Z}
}
func Sub(first, second geom.Vector) geom.Vector {
return geom.Vector{first.X - second.X, first.Y - second.Y, first.Z - second.Z}
}
func Mul(vektor geom.Vector, number float64) geom.Vector {
return geom.Vector{number * vektor.X, number * vektor.Y, number * vektor.Z}
+}
+
+func areIntersect(P0, P1, Q0, Q1 geom.Vector) bool {
+ DP := Sub(P1, P0)
+ DQ := Sub(Q1, Q0)
+ PQ := Sub(Q0, P0)
+
+ a := Dot(DP, DP)
+ b := Dot(DP, DQ)
+ c := Dot(DQ, DQ)
+ d := Dot(DP, PQ)
+ e := Dot(DQ, PQ)
+
+ DD := a*c - b*b
+ tt := (b*e - c*d) / DD
+ uu := (a*e - b*d) / DD
+
+ if tt < 0.0 || tt > 1.0 || uu < 0.0 || uu > 1.0 {
+ return false
+ }
+
+ Ptt := Add(P0, Mul(DP, tt))
+ Quu := Add(Q0, Mul(DQ, uu))
+ tempVector := Sub(Quu, Ptt)
+ Dist := math.Sqrt(tempVector.X*tempVector.X + tempVector.Y + tempVector.Y + tempVector.Z*tempVector.Z)
+
+ return Dist < 1.0E-12
}
func main() {
//EMPTY BODY
}

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

package main
import (
"math"
"github.com/fmi/go-homework/geom"
)
type Triangle struct {
A, B, C geom.Vector
}
func NewTriangle(a, b, c geom.Vector) Triangle {
return Triangle{
A: a,
B: b,
C: c,
}
}
-
func (triangle Triangle) Intersect(ray geom.Ray) bool {
- epsiolon := 0.0000001
-
+ epsilon := 0.0000001
var edge1, edge2 geom.Vector
edge1 = Sub(triangle.B, triangle.A)
edge2 = Sub(triangle.C, triangle.A)
crossProduct := Cross(edge1, edge2)
- if crossProduct.X == 0.0 && crossProduct.Y == 0.0 && crossProduct.Z == 0.0 {
+ dir := Sub(ray.Direction, ray.Origin)
+ dotProduct := Dot(crossProduct, dir)
+
+ if math.Abs(dotProduct) < epsilon {
return false
}
- rayDirectrion := Sub(ray.Direction, ray.Origin)
diff := Sub(ray.Origin, triangle.A)
- a := -Dot(crossProduct, diff)
- b := Dot(crossProduct, rayDirectrion)
+ a := -1 * Dot(crossProduct, diff)
- if math.Abs(b) < epsiolon {
- if a == 0 {
- return true
- } else {
- return false
- }
- }
-
- if a/b < 0.0 {
+ if a/dotProduct < 0.0 {
return false
}
- intersectPoint := Add(ray.Origin, Mul(rayDirectrion, a/b))
+ intersectPoint := Add(ray.Origin, Mul(dir, a/dotProduct))
aa := Dot(edge1, edge1)
ab := Dot(edge1, edge2)
bb := Dot(edge2, edge2)
w := Sub(intersectPoint, triangle.A)
wa := Dot(w, edge1)
wb := Dot(w, edge2)
quadraticDiff := ab*ab - aa*bb
- intersectedSide := (ab*wa - aa*wb) / quadraticDiff
-
+ intersectedSide := (ab*wb - bb*wa) / quadraticDiff
if intersectedSide < 0.0 || intersectedSide > 1.0 {
return false
}
-
intersectedArea := (ab*wa - aa*wb) / quadraticDiff
-
if intersectedArea < 0.0 || (intersectedSide+intersectedArea) > 1.0 {
return false
}
-
return true
}
type Quad struct {
A, B, C, D geom.Vector
}
func NewQuad(a, b, c, d geom.Vector) Quad {
return Quad{
A: a,
B: b,
C: c,
D: d,
}
}
func (quad Quad) Intersect(ray geom.Ray) bool {
var firstTriangle Triangle
var secondTriangle Triangle
- if areIntersect(quad.A, quad.C, quad.B, quad.D) {
+ if S3(quad.A, quad.C, quad.B)*S3(quad.A, quad.C, quad.D) < 0.0 {
firstTriangle = NewTriangle(quad.A, quad.B, quad.C)
- secondTriangle = NewTriangle(quad.C, quad.D, quad.A)
+ secondTriangle = NewTriangle(quad.A, quad.D, quad.C)
} else {
- firstTriangle = NewTriangle(quad.A, quad.B, quad.D)
- secondTriangle = NewTriangle(quad.C, quad.B, quad.D)
+ firstTriangle = NewTriangle(quad.B, quad.D, quad.C)
+ secondTriangle = NewTriangle(quad.B, quad.D, quad.A)
}
return firstTriangle.Intersect(ray) || secondTriangle.Intersect(ray)
}
type Sphere struct {
origin geom.Vector
R float64
}
func NewSphere(origin geom.Vector, r float64) Sphere {
return Sphere{
origin: origin,
R: r,
}
}
-
func (sphere Sphere) Intersect(ray geom.Ray) bool {
L := Sub(sphere.origin, ray.Origin)
tca := Dot(L, ray.Direction)
-
if tca < 0 {
return false
}
-
d2 := Dot(L, L) - tca*tca
if d2 > sphere.R {
return false
}
thc := math.Sqrt(sphere.R - d2)
t0 := tca - thc
t1 := tca + thc
if t0 > t1 {
t0, t1 = t1, t0
}
-
if t0 < 0 {
t0 = t1
if t0 < 0 {
return false
}
}
-
return true
}
-
func Dot(first, second geom.Vector) float64 {
return first.X*second.X + first.Y*second.Y + first.Z*second.Z
}
-
func Cross(first, second geom.Vector) geom.Vector {
return geom.Vector{
first.Y*second.Z - first.Z*second.Y,
first.Z*second.X - first.X*second.Z,
first.X*second.Y - first.Y*second.X,
}
}
-
func Abs(vektor geom.Vector) geom.Vector {
return geom.Vector{math.Abs(vektor.X), math.Abs(vektor.Y), math.Abs(vektor.Z)}
}
-
func Add(first, second geom.Vector) geom.Vector {
return geom.Vector{first.X + second.X, first.Y + second.Y, first.Z + second.Z}
}
-
func Sub(first, second geom.Vector) geom.Vector {
return geom.Vector{first.X - second.X, first.Y - second.Y, first.Z - second.Z}
}
-
func Mul(vektor geom.Vector, number float64) geom.Vector {
return geom.Vector{number * vektor.X, number * vektor.Y, number * vektor.Z}
}
-
func areIntersect(P0, P1, Q0, Q1 geom.Vector) bool {
DP := Sub(P1, P0)
DQ := Sub(Q1, Q0)
PQ := Sub(Q0, P0)
-
a := Dot(DP, DP)
b := Dot(DP, DQ)
c := Dot(DQ, DQ)
d := Dot(DP, PQ)
e := Dot(DQ, PQ)
-
DD := a*c - b*b
tt := (b*e - c*d) / DD
uu := (a*e - b*d) / DD
-
if tt < 0.0 || tt > 1.0 || uu < 0.0 || uu > 1.0 {
return false
}
-
Ptt := Add(P0, Mul(DP, tt))
Quu := Add(Q0, Mul(DQ, uu))
tempVector := Sub(Quu, Ptt)
Dist := math.Sqrt(tempVector.X*tempVector.X + tempVector.Y + tempVector.Y + tempVector.Z*tempVector.Z)
-
return Dist < 1.0E-12
}
+func S3(A, B, C geom.Vector) float64 {
+ return S2(A, B) + S2(B, C) + S2(C, A)
+}
+
+func S2(A, B geom.Vector) float64 {
+ crossProduct := Cross(A, B)
+ return crossProduct.X * crossProduct.Y * crossProduct.Z / 3.0
+}
+
func main() {
//EMPTY BODY
-}
+}

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

package main
import (
"math"
"github.com/fmi/go-homework/geom"
)
type Triangle struct {
A, B, C geom.Vector
}
func NewTriangle(a, b, c geom.Vector) Triangle {
return Triangle{
A: a,
B: b,
C: c,
}
}
func (triangle Triangle) Intersect(ray geom.Ray) bool {
epsilon := 0.0000001
var edge1, edge2 geom.Vector
edge1 = Sub(triangle.B, triangle.A)
edge2 = Sub(triangle.C, triangle.A)
crossProduct := Cross(edge1, edge2)
dir := Sub(ray.Direction, ray.Origin)
dotProduct := Dot(crossProduct, dir)
if math.Abs(dotProduct) < epsilon {
return false
}
diff := Sub(ray.Origin, triangle.A)
a := -1 * Dot(crossProduct, diff)
if a/dotProduct < 0.0 {
return false
}
intersectPoint := Add(ray.Origin, Mul(dir, a/dotProduct))
aa := Dot(edge1, edge1)
ab := Dot(edge1, edge2)
bb := Dot(edge2, edge2)
w := Sub(intersectPoint, triangle.A)
wa := Dot(w, edge1)
wb := Dot(w, edge2)
quadraticDiff := ab*ab - aa*bb
intersectedSide := (ab*wb - bb*wa) / quadraticDiff
if intersectedSide < 0.0 || intersectedSide > 1.0 {
return false
}
intersectedArea := (ab*wa - aa*wb) / quadraticDiff
if intersectedArea < 0.0 || (intersectedSide+intersectedArea) > 1.0 {
return false
}
return true
}
type Quad struct {
A, B, C, D geom.Vector
}
func NewQuad(a, b, c, d geom.Vector) Quad {
return Quad{
A: a,
B: b,
C: c,
D: d,
}
}
func (quad Quad) Intersect(ray geom.Ray) bool {
var firstTriangle Triangle
var secondTriangle Triangle
if S3(quad.A, quad.C, quad.B)*S3(quad.A, quad.C, quad.D) < 0.0 {
firstTriangle = NewTriangle(quad.A, quad.B, quad.C)
secondTriangle = NewTriangle(quad.A, quad.D, quad.C)
} else {
firstTriangle = NewTriangle(quad.B, quad.D, quad.C)
secondTriangle = NewTriangle(quad.B, quad.D, quad.A)
}
return firstTriangle.Intersect(ray) || secondTriangle.Intersect(ray)
}
type Sphere struct {
origin geom.Vector
R float64
}
func NewSphere(origin geom.Vector, r float64) Sphere {
return Sphere{
origin: origin,
R: r,
}
}
func (sphere Sphere) Intersect(ray geom.Ray) bool {
+ if ray.Origin.X == ray.Direction.X && ray.Origin.Y == ray.Direction.Y {
+ if ray.Origin.Z < ray.Direction.Z {
+ ray.Direction.Z = math.MaxFloat64
+ } else {
+ ray.Direction.Z = -1 * math.MaxFloat64
+ }
+ } else if ray.Origin.X == ray.Direction.X && ray.Origin.Z == ray.Direction.Z {
+ if ray.Origin.Y < ray.Direction.Y {
+ ray.Direction.Y = math.MaxFloat64
+ } else {
+ ray.Direction.Y = -1 * math.MaxFloat64
+ }
+ } else if ray.Origin.Y == ray.Direction.Y && ray.Origin.Z == ray.Direction.Z {
+ if ray.Origin.X < ray.Direction.X {
+ ray.Direction.X = math.MaxFloat64
+ } else {
+ ray.Direction.X = -1 * math.MaxFloat64
+ }
+ }
+
L := Sub(sphere.origin, ray.Origin)
tca := Dot(L, ray.Direction)
if tca < 0 {
return false
}
d2 := Dot(L, L) - tca*tca
if d2 > sphere.R {
return false
}
thc := math.Sqrt(sphere.R - d2)
t0 := tca - thc
t1 := tca + thc
if t0 > t1 {
t0, t1 = t1, t0
}
if t0 < 0 {
t0 = t1
if t0 < 0 {
return false
}
}
return true
}
func Dot(first, second geom.Vector) float64 {
return first.X*second.X + first.Y*second.Y + first.Z*second.Z
}
func Cross(first, second geom.Vector) geom.Vector {
return geom.Vector{
first.Y*second.Z - first.Z*second.Y,
first.Z*second.X - first.X*second.Z,
first.X*second.Y - first.Y*second.X,
}
}
func Abs(vektor geom.Vector) geom.Vector {
return geom.Vector{math.Abs(vektor.X), math.Abs(vektor.Y), math.Abs(vektor.Z)}
}
func Add(first, second geom.Vector) geom.Vector {
return geom.Vector{first.X + second.X, first.Y + second.Y, first.Z + second.Z}
}
func Sub(first, second geom.Vector) geom.Vector {
return geom.Vector{first.X - second.X, first.Y - second.Y, first.Z - second.Z}
}
func Mul(vektor geom.Vector, number float64) geom.Vector {
return geom.Vector{number * vektor.X, number * vektor.Y, number * vektor.Z}
-}
-func areIntersect(P0, P1, Q0, Q1 geom.Vector) bool {
- DP := Sub(P1, P0)
- DQ := Sub(Q1, Q0)
- PQ := Sub(Q0, P0)
- a := Dot(DP, DP)
- b := Dot(DP, DQ)
- c := Dot(DQ, DQ)
- d := Dot(DP, PQ)
- e := Dot(DQ, PQ)
- DD := a*c - b*b
- tt := (b*e - c*d) / DD
- uu := (a*e - b*d) / DD
- if tt < 0.0 || tt > 1.0 || uu < 0.0 || uu > 1.0 {
- return false
- }
- Ptt := Add(P0, Mul(DP, tt))
- Quu := Add(Q0, Mul(DQ, uu))
- tempVector := Sub(Quu, Ptt)
- Dist := math.Sqrt(tempVector.X*tempVector.X + tempVector.Y + tempVector.Y + tempVector.Z*tempVector.Z)
- return Dist < 1.0E-12
}
func S3(A, B, C geom.Vector) float64 {
return S2(A, B) + S2(B, C) + S2(C, A)
}
func S2(A, B geom.Vector) float64 {
crossProduct := Cross(A, B)
return crossProduct.X * crossProduct.Y * crossProduct.Z / 3.0
}
func main() {
//EMPTY BODY
}