Изрязване на невидими ръбове при конструиране на 3D обекти в Live Mathematics
Здравейте, скъпи читатели! Искам да споделя с вас това, което сам научих, а именно как да гарантирам, че при изграждането на триизмерни модели в „Жива математика“ (или „Жива геометрия“, както още се нарича), лицата, които са екранирани от обекта, няма да бъдат изчертани. Тоест, ако моделът е обърнат с лицето към нас, тогава елементите, принадлежащи на това лице (сегменти и точки), ще бъдат видими, но когато обектът се завърти и самият обект закрива това лице (т.е. лицето е зад) - тези сегменти и точки ще изчезнат.
Първо, очевидно е необходимо да се научите как да изграждате сами триизмерни обекти, ако все още не знаете как, тогава сте тук (призми и пирамиди), ако имате нужда от паралелепипед, тогава тук.
Алгоритъмът, за който искам да говоря, се нарича алгоритъм на Робъртс. Искам веднага да отбележа, че в компютърната графика съм чайник, това не е моята област. Току-що успях да реша най-простия проблем, който първоначално не беше най-простият за мен и отне седмица, за да го реша. Затова реших да ви спестя една седмица време. Специалисти - във форумите на 3D - програмисти, тук - обяснение за обикновените хора, на прост език, за същите "манекени" като мен.
Алгоритъмът за създаване на невидимост се основава на следното: представете си обект и наблюдател, който го гледа от някаква точка в пространството, която, разбира се, е извън този обект. Необходимо е да се уточни, че обектът трябва да бъде „изпъкнал“, тоест равнините, към които принадлежат лицата, не трябва да режат обекта. В този случай алгоритъмът работи добре; в противен случай трябва да се приложат допълнителни условия или други методи за прекъсване. Алгоритъмът се основава на следния факт: ако между нормалната към лицетообект и линията на наблюдение, ъгълът е остър, тогава ръбът се вижда, а ако е тъп, тогава не е. На фигурите линията на наблюдение е показана в зелено, нормалите са в червено, които сключват остър ъгъл с линията на наблюдение, а лилавите нормали на съседната фигура правят тъп ъгъл с линията на наблюдателя, така че тези лица не се виждат. Острите ъгли имат положителен косинус, докато тъпите ъгли имат отрицателен косинус. Следователно, ние ще базираме както изчислението, така и конструкцията на този факт.
И така, ще направим следното: изчислим нормалните вектори към всички лица. Винаги има две нормали към равнината, имаме нужда от тази, която гледа „навън“, от обекта, а не „навътре“. Нека дефинираме линията на наблюдение и да определим знака на косинуса на ъгъла между нормалите и линията на наблюдение. Въз основа на тази информация ще формираме коефициентите на видимост-невидимост и ще създадем хомототети на върховете на обекта с посочените коефициенти. Тези точки съществуват само в определена позиция на обекта и ако са свързани чрез сегменти, тогава сегментите ще изчезнат, когато съответните точки изчезнат, и ще се появят обратно, когато обектът се завърти и се появят тези хомотетии.
Е, сега - към точката. Рисувам всичко в детайли, както бих искал да ми бъде обяснено, когато току-що започнах да се задълбочавам в този проблем.
1. Определете броя на лицата на обекта. За правилна пирамида има 4 от тях, за паралелепипед - 6.
2. Изчисляваме нормалите към лицата (по броя на лицата, разбира се). Това ще бъдат нормалите, дефинирани във върха на многоъгълника, и ще ги намерим чрез изчисляване на кръстосаното произведение на съседни ръбове. Тук е важно да не правите грешка с посоката на нормалата, както беше казано по-рано, тя задължително трябва да изглежда „навън“, от обекта. Как може да се постигне това? Правилото на гимлета, известно във физиката и електротехниката, ще помогне тук (за тези, коитопомни), или по следните начини:
Вариант на правилото на gimlet (винт) за векторно произведение по посока на часовниковата стрелка: Ако начертаем векторите така, че техните начала да съвпадат и завъртим първия вектор на множителя по най-късия път към втория вектор на множител и погледнем от другата страна, така че това въртене да е по посока на часовниковата стрелка за нас, векторът на произведението ще бъде насочен далеч от нас (завийте дълбоко в часовника) - но в този случай вие и аз трябва да сме, така да се каже, „вътре“ в обект.
Правило на дясната ръка за кръстосано произведение:
Ако начертаете векторите така, че началото им да съвпадне и завъртите първия вектор на множителя по най-краткия път към втория вектор на множителя, а четирите пръста на дясната ръка в същото време ще показват посоката на въртене (като че ли прегръщате въртящия се цилиндър), тогава изпъкналият палец ще покаже посоката на вектора на произведението (вижте снимката):
С други думи, трябва да покриете нашия обект с дланта си, така че лицето, към което е изградена нормалата, да е отгоре. Тогава един от векторите ще бъде успореден на показалеца, а вторият на палеца. Например:
Тогава кръстосаното произведение на векторите ще бъде записано, както следва:
Това е необходимото нормално. В този запис:
Тук са единичните вектори на избраната основа.
Тоест имаме нужда от координатите на трите върха на това лице по осите и -
, което означава, че те трябва да бъдат дефинирани.
Ако извършим изчислението за кутия, тогава ще трябва да изчислим последните суми (добре или разлики) за всяко лице - тоест 6 пъти. След като направим това, ще имаме 6 нормали.
3. Сега е време да изберете място за вас и мен като наблюдатели - тоест точката за наблюдение. Тук се натъкнах на неприятности. Някои източници препоръчват точка, разположена на оста, а след това нана положителната полуос, след това на отрицателната. А други препоръчват точка с координати (1, 1, 1). Тази точка ми се струва по-правилна, ако искаме да видим три лица на паралелепипеда едновременно. И така, избираме точка (1, 1, 1). Векторът, представящ тази посока, също е (1, 1, 1).
4. Да определим косинуса на ъгъла между нормалата и избраната посока към наблюдателя и дори не самия косинус, а само неговия знак. Всеки си спомня формулата на точковия продукт, която включва този косинус, тогава, ако го изразим от тази формула, получаваме:
- тук в числителя не е просто произведение, а скаларно произведение на вектори.
Както можете да видите, знаменателят съдържа очевидно положително число, така че изобщо не е необходимо да го броите, това няма да повлияе на знака.
Тогава всичко, което е необходимо, е да се определи знакът на скаларното произведение на нормалния вектор и вектора на единичната посока към наблюдателя - или знакът на такова число:
. Ако знакът е положителен, ръбът се вижда; ако е отрицателен, ръбът не се вижда. Нека въведем стойността: , тогава тази стойност е равна на 1, когато лицето е видимо, а ако не се вижда, тогава за такова лице . В тези формули: sgn е операцията за определяне на знака. Връща 1, ако знакът е положителен, и (-1), ако знакът е отрицателен.
5. Е, вече се приближаваме до същността - тоест изчисляването на коефициентите на видимост - невидимостта на ръбовете. Първият въпрос е колко от тези коефициенти трябва да има? Отговорът е следният: техният брой е равен на два пъти броя на ръбовете. Тогава за паралелепипед това е , а за тетраедър - , за правилна призма с петоъгълник в основата - 30, с шестоъгълник в основата - 36 и т.н. Половината от тях са коефициенти на видимост, другата половина са коефициенти на невидимост. Коефициентът на видимост може да бъде равен на 1 (тогава елементът е видим) или недефиниран (тогава не се вижда),и по същия начин, коефициентът на невидимост - може да бъде равен на 1 или да не е определен. Защо, питате вие, тогава имаме нужда както от коефициенти на видимост, така и на невидимост? Оставете невидимото просто да изчезне и това е! Но ние трябва невидимото да бъде начертано, но само тънко, с пунктирана линия ... И за да съществува сегмент, дори и тънък, е необходимо да съществуват неговите предци - точки. С други думи, ако лицето е предно (видимо в момента), тогава всички върхове съществуват, както и сегментите (ръбовете) между тях също съществуват и те са начертани с удебелен шрифт. Но веднага щом завъртим обекта, така че това лице да стане непредно, обратно - и точките на върха трябва да изчезнат, но вместо тях се появяват други точки (на същите места!), И сегментът, който ги свързва - но вече пунктиран.
Например, корен от четна степен на отрицателно число може да не бъде дефиниран. Оттук и формулите за коефициентите на видимост:
Ясно е, че ако две съседни лица са невидими, то ръбът между тях също е невидим. След това получаваме корен от (-1) и коефициентът на видимост не е дефиниран, а коефициентът на невидимост е 1 - което е, което ни трябва. Ако поне едно от двете съседни лица е видимо, тогава факторът на видимост е равен на 1 и ръбът е видим, докато факторът на невидимост е недефиниран.
6. Сега всъщност трябва да започнем да рисуваме ръбовете. Ръбът е сегмент, който свързва точки - върхове. При нас, ако обектът вече е построен, значи вече има върхове. Но ще ни трябват други точки за нашите понякога видими, понякога невидими ръбове. Да обиколим обекта в една посока, например обратно на часовниковата стрелка. Започваме от точка A. Маркираме точка D като център на хомотетията и във връх A създаваме нова точка с невидим коефициент на хомотетия - A’. Свързваме D и A с тънък сегмент или пунктирана линия. След това създаваме втората хомотетия на точка А, но скоефициент видим - А", и съединете тази точка с точка D с дебел, преден, сегмент. Просто гледайте внимателно кои точки свързвате. Ако няколко точки са на едно и също място, трябва да щракнете с мишката, за да изберете желаната точка. Така че, заобикаляйки горната основа на обекта, рисуваме тънки и дебели сегменти за всички ръбове. По същия начин правим за долната основа, а след това за страничните ребра. И ура - проработи!