Решение на Пресичания от Слави Боянов

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

Към профила на Слави Боянов

Резултати

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

Код

package main
import (
"github.com/fmi/go-homework/geom"
"math"
)
type vector geom.Vector
const eps float64 = 1e-7
func newVector(x, y, z float64) vector {
return vector(geom.NewVector(x, y, z))
}
func vectorFromTo(
origin point,
destination point,
) vector {
return newVector(
destination.X-origin.X,
destination.Y-origin.Y,
destination.Z-origin.Z,
)
}
func (self vector) dot(other vector) float64 {
return self.X*other.X + self.Y*other.Y + self.Z*other.Z
}
func (self vector) cross(other vector) vector {
return newVector(
self.Y*other.Z-self.Z*other.Y,
self.Z*other.X-self.X*other.Z,
self.X*other.Y-self.Y*other.X,
)
}
func (self vector) scale(scalar float64) vector {
return newVector(
self.X*scalar,
self.Y*scalar,
self.Z*scalar,
)
}
func (self vector) length() float64 {
return math.Sqrt(self.dot(self))
}
func (self vector) project(on vector) vector {
return on.scale(self.dot(on) / on.dot(on))
}
func (self vector) sameDirection(as vector) bool {
return self.dot(as) >= 0
}
func (self vector) subtract(other vector) vector {
return newVector(
self.X-other.X,
self.Y-other.Y,
self.Z-other.Z,
)
}
type point geom.Vector
func newPoint(x, y, z float64) point {
return point(geom.NewVector(x, y, z))
}
func (self point) translate(with vector) point {
return newPoint(
self.X+with.X,
self.Y+with.Y,
self.Z+with.Z,
)
}
func (self point) squareDistance(to point) float64 {
vec := vectorFromTo(self, to)
return vec.dot(vec)
}
func deconstruct(ray geom.Ray) (point, vector) {
return point(ray.Origin), vector(ray.Direction)
}
type plane struct {
normal vector
member point
}
func newPlane(x, y, z point) plane {
coVector1 := vectorFromTo(x, y)
coVector2 := vectorFromTo(x, z)
return plane{
normal: coVector1.cross(coVector2),
member: x,
}
}
func (self plane) intersectWith(ray geom.Ray) (
intersects bool,
intersection point,
) {
origin, direction := deconstruct(ray)
denom := self.normal.dot(direction)
if -eps < denom && denom < eps {
return
}
originToPlane := vectorFromTo(
origin,
self.member,
)
scalar := originToPlane.dot(self.normal) / denom
intersects = scalar >= 0
if intersects {
intersection = origin.translate(direction.scale(scalar))
}
return
}
type triangle struct {
a, b, c point
p plane
}
func newTriangle(a, b, c point) triangle {
return triangle{
a: a,
b: b,
c: c,
p: newPlane(a, b, c),
}
}
func NewTriangle(a, b, c geom.Vector) triangle {
return newTriangle(
point(a),
point(b),
point(c),
)
}
func (self triangle) area() float64 {
return self.p.normal.length() / 2
}
func (self triangle) contains(p point) bool {
pab, pbc, pac := newTriangle(p, self.a, self.b),
newTriangle(p, self.c, self.b),
newTriangle(p, self.a, self.c)
return (pab.area() + pbc.area() + pac.area() - self.area()) < 1e-7
}
func (self triangle) Intersect(ray geom.Ray) bool {
intersects, intersection := self.p.intersectWith(ray)
if !intersects {
return false
}
return self.contains(intersection)
}
type quad struct {
firstTri, secondTri triangle
}
func NewQuad(a, b, c, d geom.Vector) (result quad) {
result = quad{
firstTri: NewTriangle(a, b, c),
secondTri: NewTriangle(a, c, d),
}
if result.firstTri.contains(point(d)) ||
result.secondTri.contains(point(b)) {
result = quad{
firstTri: NewTriangle(a, b, d),
secondTri: NewTriangle(b, c, d),
}
}
return
}
func (self quad) Intersect(ray geom.Ray) bool {
return self.firstTri.Intersect(ray) ||
self.secondTri.Intersect(ray)
}
type sphere struct {
center point
radiusSquare float64
}
func NewSphere(center geom.Vector, radius float64) sphere {
return sphere{
center: point(center),
radiusSquare: radius * radius,
}
}
func (self sphere) Intersect(ray geom.Ray) bool {
origin, direction := deconstruct(ray)
if self.center.squareDistance(origin) <= self.radiusSquare {
return true
}
originToCenterPoint := vectorFromTo(
origin,
self.center,
)
projection := originToCenterPoint.project(direction)
if !projection.sameDirection(direction) {
return false
}
closestPoint := origin.translate(projection)
return self.center.squareDistance(closestPoint) <= self.radiusSquare
}

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

PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.003s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.003s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s
PASS
ok  	_/tmp/d20181122-57-wytmh0	0.002s

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

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

+package main
+
+import (
+ "github.com/fmi/go-homework/geom"
+ "math"
+)
+
+type vector geom.Vector
+
+func newVector(x, y, z float64) vector {
+ return vector(geom.NewVector(x, y, z))
+}
+
+func vectorFromTo(
+ origin point,
+ destination point,
+) vector {
+ return newVector(
+ destination.X-origin.X,
+ destination.Y-origin.Y,
+ destination.Z-origin.Z,
+ )
+}
+
+func (self vector) dot(other vector) float64 {
+ return self.X*other.X + self.Y*other.Y + self.Z*other.Z
+}
+
+func (self vector) cross(other vector) vector {
+ return newVector(
+ self.Y*other.Z-self.Z*other.Y,
+ self.Z*other.X-self.X*other.Z,
+ self.X*other.Y-self.Y*other.X,
+ )
+}
+
+func (self vector) scale(scalar float64) vector {
+ return newVector(
+ self.X*scalar,
+ self.Y*scalar,
+ self.Z*scalar,
+ )
+}
+
+func (self vector) length() float64 {
+ return math.Sqrt(self.dot(self))
+}
+
+func (self vector) project(on vector) vector {
+ return on.scale(self.dot(on) / on.dot(on))
+}
+
+func (self vector) sameDirection(as vector) bool {
+ return self.dot(as) > 0
+}
+
+func (self vector) subtract(other vector) vector {
+ return newVector(
+ self.X-other.X,
+ self.Y-other.Y,
+ self.Z-other.Z,
+ )
+}
+
+type point geom.Vector
+
+func newPoint(x, y, z float64) point {
+ return point(geom.NewVector(x, y, z))
+}
+
+func (self point) translate(with vector) point {
+ return newPoint(
+ self.X+with.X,
+ self.Y+with.Y,
+ self.Z+with.Z,
+ )
+}
+
+func (self point) squareDistance(to point) float64 {
+ vec := vectorFromTo(self, to)
+ return vec.dot(vec)
+}
+
+func deconstruct(ray geom.Ray) (point, vector) {
+ return point(ray.Origin), vector(ray.Direction)
+}
+
+type plane struct {
+ normal vector
+ member point
+}
+
+func newPlane(x, y, z point) plane {
+ coVector1 := vectorFromTo(x, y)
+ coVector2 := vectorFromTo(x, z)
+ return plane{
+ normal: coVector1.cross(coVector2),
+ member: x,
+ }
+}
+
+func (self plane) intersectWith(ray geom.Ray) (
+ intersects bool,
+ intersection point,
+) {
+ origin, direction := deconstruct(ray)
+ originToPlane := vectorFromTo(
+ origin,
+ self.member,
+ )
+ scalar := direction.dot(self.normal) /
+ originToPlane.dot(self.normal)
+ intersects = (scalar > 0)
+ if intersects {
+ intersection = origin.translate(
+ direction.scale(scalar),
+ )
+ }
+ return
+}
+
+type triangle struct {
+ a, b, c point
+ p plane
+}
+
+func newTriangle(a, b, c point) triangle {
+ return triangle{
+ a: a,
+ b: b,
+ c: c,
+ p: newPlane(a, b, c),
+ }
+}
+
+func NewTriangle(a, b, c geom.Vector) triangle {
+ return newTriangle(
+ point(a),
+ point(b),
+ point(c),
+ )
+}
+
+func (self triangle) area() float64 {
+ return self.p.normal.length() / 2
+}
+
+func (self triangle) contains(p point) bool {
+
+ pab, pbc, pac := newTriangle(p, self.a, self.b),
+ newTriangle(p, self.c, self.b),
+ newTriangle(p, self.a, self.c)
+ return (pab.area() + pbc.area() + pac.area() - self.area()) < 1e-7
+}
+
+func (self triangle) Intersect(ray geom.Ray) bool {
+ intersects, intersection := self.p.intersectWith(ray)
+ if !intersects {
+ return false
+ }
+
+ return self.contains(intersection)
+}
+
+type quad struct {
+ firstTri, secondTri triangle
+}
+
+func NewQuad(a, b, c, d geom.Vector) (result quad) {
+ result = quad{
+ firstTri: NewTriangle(a, b, c),
+ secondTri: NewTriangle(a, c, d),
+ }
+ if result.firstTri.contains(point(d)) ||
+ result.secondTri.contains(point(b)) {
+
+ result = quad{
+ firstTri: NewTriangle(a, b, d),
+ secondTri: NewTriangle(b, c, d),
+ }
+ }
+ return
+}
+
+func (self quad) Intersect(ray geom.Ray) bool {
+ return self.firstTri.Intersect(ray) ||
+ self.secondTri.Intersect(ray)
+}
+
+type sphere struct {
+ center point
+ radiusSquare float64
+}
+
+func NewSphere(center geom.Vector, radius float64) sphere {
+ return sphere{
+ center: point(center),
+ radiusSquare: radius * radius,
+ }
+}
+
+func (self sphere) Intersect(ray geom.Ray) bool {
+ origin, direction := deconstruct(ray)
+ if self.center.squareDistance(origin) <= self.radiusSquare {
+ return true
+ }
+
+ originToCenterPoint := vectorFromTo(
+ origin,
+ self.center,
+ )
+
+ projection := originToCenterPoint.project(direction)
+
+ if !projection.sameDirection(direction) {
+ return false
+ }
+
+ closestPoint := origin.translate(projection)
+
+ return self.center.squareDistance(closestPoint) <= self.radiusSquare
+}
+
+func main() {
+ a, b, c := geom.NewVector(-1, -1, 0), geom.NewVector(1, -1, 0), geom.NewVector(1, 1, 0)
+ prim := NewTriangle(a, b, c)
+ ray := geom.NewRay(geom.NewVector(0, 0, 1), geom.NewVector(0, 0, -1))
+ _ = prim.Intersect(ray)
+}

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

package main
import (
"github.com/fmi/go-homework/geom"
"math"
)
type vector geom.Vector
func newVector(x, y, z float64) vector {
return vector(geom.NewVector(x, y, z))
}
func vectorFromTo(
origin point,
destination point,
) vector {
return newVector(
destination.X-origin.X,
destination.Y-origin.Y,
destination.Z-origin.Z,
)
}
func (self vector) dot(other vector) float64 {
return self.X*other.X + self.Y*other.Y + self.Z*other.Z
}
func (self vector) cross(other vector) vector {
return newVector(
self.Y*other.Z-self.Z*other.Y,
self.Z*other.X-self.X*other.Z,
self.X*other.Y-self.Y*other.X,
)
}
func (self vector) scale(scalar float64) vector {
return newVector(
self.X*scalar,
self.Y*scalar,
self.Z*scalar,
)
}
func (self vector) length() float64 {
return math.Sqrt(self.dot(self))
}
func (self vector) project(on vector) vector {
return on.scale(self.dot(on) / on.dot(on))
}
func (self vector) sameDirection(as vector) bool {
return self.dot(as) > 0
}
func (self vector) subtract(other vector) vector {
return newVector(
self.X-other.X,
self.Y-other.Y,
self.Z-other.Z,
)
}
type point geom.Vector
func newPoint(x, y, z float64) point {
return point(geom.NewVector(x, y, z))
}
func (self point) translate(with vector) point {
return newPoint(
self.X+with.X,
self.Y+with.Y,
self.Z+with.Z,
)
}
func (self point) squareDistance(to point) float64 {
vec := vectorFromTo(self, to)
return vec.dot(vec)
}
func deconstruct(ray geom.Ray) (point, vector) {
return point(ray.Origin), vector(ray.Direction)
}
type plane struct {
normal vector
member point
}
func newPlane(x, y, z point) plane {
coVector1 := vectorFromTo(x, y)
coVector2 := vectorFromTo(x, z)
return plane{
normal: coVector1.cross(coVector2),
member: x,
}
}
func (self plane) intersectWith(ray geom.Ray) (
intersects bool,
intersection point,
) {
origin, direction := deconstruct(ray)
originToPlane := vectorFromTo(
origin,
self.member,
)
scalar := direction.dot(self.normal) /
originToPlane.dot(self.normal)
intersects = (scalar > 0)
if intersects {
intersection = origin.translate(
direction.scale(scalar),
)
}
return
}
type triangle struct {
a, b, c point
p plane
}
func newTriangle(a, b, c point) triangle {
return triangle{
a: a,
b: b,
c: c,
p: newPlane(a, b, c),
}
}
func NewTriangle(a, b, c geom.Vector) triangle {
return newTriangle(
point(a),
point(b),
point(c),
)
}
func (self triangle) area() float64 {
return self.p.normal.length() / 2
}
func (self triangle) contains(p point) bool {
pab, pbc, pac := newTriangle(p, self.a, self.b),
newTriangle(p, self.c, self.b),
newTriangle(p, self.a, self.c)
return (pab.area() + pbc.area() + pac.area() - self.area()) < 1e-7
}
func (self triangle) Intersect(ray geom.Ray) bool {
intersects, intersection := self.p.intersectWith(ray)
if !intersects {
return false
}
return self.contains(intersection)
}
type quad struct {
firstTri, secondTri triangle
}
func NewQuad(a, b, c, d geom.Vector) (result quad) {
result = quad{
firstTri: NewTriangle(a, b, c),
secondTri: NewTriangle(a, c, d),
}
if result.firstTri.contains(point(d)) ||
result.secondTri.contains(point(b)) {
result = quad{
firstTri: NewTriangle(a, b, d),
secondTri: NewTriangle(b, c, d),
}
}
return
}
func (self quad) Intersect(ray geom.Ray) bool {
return self.firstTri.Intersect(ray) ||
self.secondTri.Intersect(ray)
}
type sphere struct {
center point
radiusSquare float64
}
func NewSphere(center geom.Vector, radius float64) sphere {
return sphere{
center: point(center),
radiusSquare: radius * radius,
}
}
func (self sphere) Intersect(ray geom.Ray) bool {
origin, direction := deconstruct(ray)
if self.center.squareDistance(origin) <= self.radiusSquare {
return true
}
originToCenterPoint := vectorFromTo(
origin,
self.center,
)
projection := originToCenterPoint.project(direction)
if !projection.sameDirection(direction) {
return false
}
closestPoint := origin.translate(projection)
return self.center.squareDistance(closestPoint) <= self.radiusSquare
}
-func main() {
- a, b, c := geom.NewVector(-1, -1, 0), geom.NewVector(1, -1, 0), geom.NewVector(1, 1, 0)
- prim := NewTriangle(a, b, c)
- ray := geom.NewRay(geom.NewVector(0, 0, 1), geom.NewVector(0, 0, -1))
- _ = prim.Intersect(ray)
-}

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

package main
import (
"github.com/fmi/go-homework/geom"
"math"
)
type vector geom.Vector
+const eps float64 = 1e-7
+
func newVector(x, y, z float64) vector {
return vector(geom.NewVector(x, y, z))
}
func vectorFromTo(
origin point,
destination point,
) vector {
return newVector(
destination.X-origin.X,
destination.Y-origin.Y,
destination.Z-origin.Z,
)
}
func (self vector) dot(other vector) float64 {
return self.X*other.X + self.Y*other.Y + self.Z*other.Z
}
func (self vector) cross(other vector) vector {
return newVector(
self.Y*other.Z-self.Z*other.Y,
self.Z*other.X-self.X*other.Z,
self.X*other.Y-self.Y*other.X,
)
}
func (self vector) scale(scalar float64) vector {
return newVector(
self.X*scalar,
self.Y*scalar,
self.Z*scalar,
)
}
func (self vector) length() float64 {
return math.Sqrt(self.dot(self))
}
func (self vector) project(on vector) vector {
return on.scale(self.dot(on) / on.dot(on))
}
func (self vector) sameDirection(as vector) bool {
- return self.dot(as) > 0
+ return self.dot(as) >= 0
}
func (self vector) subtract(other vector) vector {
return newVector(
self.X-other.X,
self.Y-other.Y,
self.Z-other.Z,
)
}
type point geom.Vector
func newPoint(x, y, z float64) point {
return point(geom.NewVector(x, y, z))
}
func (self point) translate(with vector) point {
return newPoint(
self.X+with.X,
self.Y+with.Y,
self.Z+with.Z,
)
}
func (self point) squareDistance(to point) float64 {
vec := vectorFromTo(self, to)
return vec.dot(vec)
}
func deconstruct(ray geom.Ray) (point, vector) {
return point(ray.Origin), vector(ray.Direction)
}
type plane struct {
normal vector
member point
}
func newPlane(x, y, z point) plane {
coVector1 := vectorFromTo(x, y)
coVector2 := vectorFromTo(x, z)
return plane{
normal: coVector1.cross(coVector2),
member: x,
}
}
func (self plane) intersectWith(ray geom.Ray) (
intersects bool,
intersection point,
) {
origin, direction := deconstruct(ray)
+ denom := self.normal.dot(direction)
+ if denom > eps {
+ return
+ }
originToPlane := vectorFromTo(
origin,
self.member,
)
- scalar := direction.dot(self.normal) /
- originToPlane.dot(self.normal)
- intersects = (scalar > 0)
+ scalar := originToPlane.dot(self.normal) / denom
+ intersects = scalar >= 0
if intersects {
- intersection = origin.translate(
- direction.scale(scalar),
- )
+ intersection = origin.translate(direction.scale(scalar))
}
return
}
type triangle struct {
a, b, c point
p plane
}
func newTriangle(a, b, c point) triangle {
return triangle{
a: a,
b: b,
c: c,
p: newPlane(a, b, c),
}
}
func NewTriangle(a, b, c geom.Vector) triangle {
return newTriangle(
point(a),
point(b),
point(c),
)
}
func (self triangle) area() float64 {
return self.p.normal.length() / 2
}
func (self triangle) contains(p point) bool {
pab, pbc, pac := newTriangle(p, self.a, self.b),
newTriangle(p, self.c, self.b),
newTriangle(p, self.a, self.c)
return (pab.area() + pbc.area() + pac.area() - self.area()) < 1e-7
}
func (self triangle) Intersect(ray geom.Ray) bool {
intersects, intersection := self.p.intersectWith(ray)
if !intersects {
return false
}
return self.contains(intersection)
}
type quad struct {
firstTri, secondTri triangle
}
func NewQuad(a, b, c, d geom.Vector) (result quad) {
result = quad{
firstTri: NewTriangle(a, b, c),
secondTri: NewTriangle(a, c, d),
}
if result.firstTri.contains(point(d)) ||
result.secondTri.contains(point(b)) {
result = quad{
firstTri: NewTriangle(a, b, d),
secondTri: NewTriangle(b, c, d),
}
}
return
}
func (self quad) Intersect(ray geom.Ray) bool {
return self.firstTri.Intersect(ray) ||
self.secondTri.Intersect(ray)
}
type sphere struct {
center point
radiusSquare float64
}
func NewSphere(center geom.Vector, radius float64) sphere {
return sphere{
center: point(center),
radiusSquare: radius * radius,
}
}
func (self sphere) Intersect(ray geom.Ray) bool {
origin, direction := deconstruct(ray)
if self.center.squareDistance(origin) <= self.radiusSquare {
return true
}
originToCenterPoint := vectorFromTo(
origin,
self.center,
)
projection := originToCenterPoint.project(direction)
if !projection.sameDirection(direction) {
return false
}
closestPoint := origin.translate(projection)
return self.center.squareDistance(closestPoint) <= self.radiusSquare
-}
-
+}

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

package main
import (
"github.com/fmi/go-homework/geom"
"math"
)
type vector geom.Vector
const eps float64 = 1e-7
func newVector(x, y, z float64) vector {
return vector(geom.NewVector(x, y, z))
}
func vectorFromTo(
origin point,
destination point,
) vector {
return newVector(
destination.X-origin.X,
destination.Y-origin.Y,
destination.Z-origin.Z,
)
}
func (self vector) dot(other vector) float64 {
return self.X*other.X + self.Y*other.Y + self.Z*other.Z
}
func (self vector) cross(other vector) vector {
return newVector(
self.Y*other.Z-self.Z*other.Y,
self.Z*other.X-self.X*other.Z,
self.X*other.Y-self.Y*other.X,
)
}
func (self vector) scale(scalar float64) vector {
return newVector(
self.X*scalar,
self.Y*scalar,
self.Z*scalar,
)
}
func (self vector) length() float64 {
return math.Sqrt(self.dot(self))
}
func (self vector) project(on vector) vector {
return on.scale(self.dot(on) / on.dot(on))
}
func (self vector) sameDirection(as vector) bool {
return self.dot(as) >= 0
}
func (self vector) subtract(other vector) vector {
return newVector(
self.X-other.X,
self.Y-other.Y,
self.Z-other.Z,
)
}
type point geom.Vector
func newPoint(x, y, z float64) point {
return point(geom.NewVector(x, y, z))
}
func (self point) translate(with vector) point {
return newPoint(
self.X+with.X,
self.Y+with.Y,
self.Z+with.Z,
)
}
func (self point) squareDistance(to point) float64 {
vec := vectorFromTo(self, to)
return vec.dot(vec)
}
func deconstruct(ray geom.Ray) (point, vector) {
return point(ray.Origin), vector(ray.Direction)
}
type plane struct {
normal vector
member point
}
func newPlane(x, y, z point) plane {
coVector1 := vectorFromTo(x, y)
coVector2 := vectorFromTo(x, z)
return plane{
normal: coVector1.cross(coVector2),
member: x,
}
}
func (self plane) intersectWith(ray geom.Ray) (
intersects bool,
intersection point,
) {
origin, direction := deconstruct(ray)
denom := self.normal.dot(direction)
- if denom > eps {
+ if -eps < denom && denom < eps {
return
}
originToPlane := vectorFromTo(
origin,
self.member,
)
scalar := originToPlane.dot(self.normal) / denom
intersects = scalar >= 0
if intersects {
intersection = origin.translate(direction.scale(scalar))
}
return
}
type triangle struct {
a, b, c point
p plane
}
func newTriangle(a, b, c point) triangle {
return triangle{
a: a,
b: b,
c: c,
p: newPlane(a, b, c),
}
}
func NewTriangle(a, b, c geom.Vector) triangle {
return newTriangle(
point(a),
point(b),
point(c),
)
}
func (self triangle) area() float64 {
return self.p.normal.length() / 2
}
func (self triangle) contains(p point) bool {
pab, pbc, pac := newTriangle(p, self.a, self.b),
newTriangle(p, self.c, self.b),
newTriangle(p, self.a, self.c)
return (pab.area() + pbc.area() + pac.area() - self.area()) < 1e-7
}
func (self triangle) Intersect(ray geom.Ray) bool {
intersects, intersection := self.p.intersectWith(ray)
if !intersects {
return false
}
return self.contains(intersection)
}
type quad struct {
firstTri, secondTri triangle
}
func NewQuad(a, b, c, d geom.Vector) (result quad) {
result = quad{
firstTri: NewTriangle(a, b, c),
secondTri: NewTriangle(a, c, d),
}
if result.firstTri.contains(point(d)) ||
result.secondTri.contains(point(b)) {
result = quad{
firstTri: NewTriangle(a, b, d),
secondTri: NewTriangle(b, c, d),
}
}
return
}
func (self quad) Intersect(ray geom.Ray) bool {
return self.firstTri.Intersect(ray) ||
self.secondTri.Intersect(ray)
}
type sphere struct {
center point
radiusSquare float64
}
func NewSphere(center geom.Vector, radius float64) sphere {
return sphere{
center: point(center),
radiusSquare: radius * radius,
}
}
func (self sphere) Intersect(ray geom.Ray) bool {
origin, direction := deconstruct(ray)
if self.center.squareDistance(origin) <= self.radiusSquare {
return true
}
originToCenterPoint := vectorFromTo(
origin,
self.center,
)
projection := originToCenterPoint.project(direction)
if !projection.sameDirection(direction) {
return false
}
closestPoint := origin.translate(projection)
return self.center.squareDistance(closestPoint) <= self.radiusSquare
-}
+}
+