Пресичания
- Краен срок:
- 21.11.2018 17:00
- Точки:
- 10
Срокът за предаване на решения е отминал
За това домашно ще трябва да избършете праха от знанията си по аналитична геометрия и да опитате да ги приложите в истинс... виртуалния свят на 3D графиката. Една от важните задачи за създаването на реалистични изображения е да се разбере дали даден лъч пресича фигура в триизмерното пространство. Както започвате да се усещате - ще ви накараме да я решите няколко пъти.
Като начало приемете, че имате за даденост следните типове:
type Vector struct {
X, Y, Z float64
}
Vector
е триизмерния вектор (X, Y, Z)
. В тази задача той може да дефинира точка с координати (X, Y, Z) или вектор-посока. Посоката е вектор с начало (0,0,0) и край (X, Y, Z).
type Ray struct {
Origin Vector
Direction Vector
}
Ray
е лъч, определен от своето начало Origin
и посока Direction
. Точките на един лъч могат да се зададат със следното параметрично уравнение:
където
Тези типове са дефинирани в пакета github.com/fmi/go-homework/geom. Можете да видите документацията му на godoc.com.
От вас ще се иска да напишете функции създаващи триъгълник, четириъгълник и сфера, които да удовлетворяват интерфейса
type Intersectable interface {
Intersect(ray Ray) bool
}
Метода Intersect(ray Ray) bool
връща истина само когато лъча ray
пресича съответния обект в пространството.
Пример за пресичане:
Пример за липса на пресичане:
Триъгълник
Напишете функция от вида
func NewTriangle(a, b, c geom.Vector) Triangle
която връща триъгълник в пространството, определен от върховете си в точките a
, b
, и c
. Не е необходимо типа ви да се нарича Triangle
. Може да има всякакво име, стига да отговаря на интерфейса Intersectable
. Разбира се, Triangle
е хубаво име за този тип. Може да върнете и указател (*Triangle
, *T
или други) ако това е по - смислено за вашия тип.
Четириъгълник
Функцията за създаване на четириъгълник трябва да е от следния вид
func NewQuad(a, b, c, d geom.Vector) Quad
Отново, не е необходимо типа ви да се казва Quad
. Просто трябва да отговаря на интерфейса Intersectable
.
Забележка: точките a
, b
, c
и d
ще са в една равнина. Няма да даваме нищо друго на функцията в нашите тестове, така че няма нужда да проверявате за това.
Сфера
Подобно на другите, функцията за създаване на сфера която трябва да напишете е
func NewSphere(origin geom.Vector, r float64) Sphere
Тук origin
е центъра на сферата, а r
е нейния радиус.
Пример
a, b, c := geom.NewVector(-1, -1, 0), geom.NewVector(1, -1, 0), geom.NewVector(0, 1, 0)
tr := NewTriangle(a, b, c)
ray := geom.NewRay(geom.NewVector(0, 0, -1), geom.NewVector(0, 0, 1))
if tr.Intersect(ray) {
fmt.Println("ray intersects tr")
}
Уточнения
Вашите обекти трябва да се пресичат и от двете им страни. Т.е. не трябва да правите back face culling.
Крайните ръбове, дефиниращи фигурите, са част от нея и съответно трябва да връщат true
за пресичания.
Как да използвам Vector
, Ray
и Intersectable
?
За тази задача ще позволим използването на пакет извън стандартната библиотека - github.com/fmi/go-homework/geom
. Той ще е наличен по време на изпълнението на тестовете на сайта ни. Недейте да го копирате в домашните си или на други места. Не се опитвайте да го предавате като част от домашното ви. Просто го използвайте във вашето решение. За удобство в пакета са добавени функциите NewVector
и NewRay
.