-
задался вопросом построения сферы типа Geosphere (Gsphere) в 3DMax'е извел тонну бумаги и замучал в усмерть гугл, но так ни к чему и не пришел скорее всего я не правильно задавал вопрос =)
была конечно мысль начать с Октаэра после чего построить вершины в центре каждой грани... привести растояние от центра до новой вершины к радиусу сферы и перестроить грани... не то. по экватору остается все те же 4 ребра
-
была также мысль вычислить угловой размер грани но как их разместить по поверхности сферы не понятно
т.е. если я изволю 12 граней по экватору угловой размер грани будет равен 30 градусам это дает нам еще 4 параллели (по две в направлении от экватора к каждому полюсу) сколько граней должно быть на первой от экватора параллели? каково угловое расстояние между экватором и первой параллелью что-то я сомневаюьс в 30 градусах, скорее - 30 * sqrt(3) / 2 градусов... но тоже не факт.
-
вот что насочинял по поводу вершин n - количество слоев на которое будем делить сферу вдоль вертикальной оси, он же уровень детализации R - радиус сферы α - угловой размер хорды грани (тот, который желаем) α = π / n l - длина грани на экваторе l = 2 * π * R * α / π = 2 * R * α P - номер параллели по направлению от экватора к северному полюсу (0 - экватор, n /2 - северный полюс, -n / 2 - южный полюс) M - количество граней на паралелли P M = round(cos(α * P) * 2 * π * R / l) l' - длина грани на параллели P (значение контрольное, на практике ненужное)
прогнал я все это дело через calc и в целом доволен результатами в частности - при любом из опробованых n, последняя перед полюсом параллель имеет шесть граней (тестировалось для n от 10 и выше)
теперь осталось разобраться с триангуляцией всей этой хренотени =)
-
Ты продолжай разговаривать.. Кому то - как снотворное, однозначно.
-
Я бы помог, но бошка не варит совершенно. На Jeer внимания не обращяй, он зол сегодня. практика показывать решение своих же задач весьма полезна.
-
Не знаю, что за геосфера в 3DMAX, поэтому не уверен, то или не то... У меня была задача о разбиении сферы на правильные треугольники. На входе - радиус, координаты центра сферы и желаемая длина ребра треугольников. На выходе - список координат узлов и список треугольников. Нужно?
-
Вот код. Выходные данные хранятся в массивах gs_n_tris : longint; //кол-во треуг. gs_n_nodes : longint; //кол-во узлов gs_node : array of TPoint3D; //коордианты узлов gs_tri : array of array [1..3] of longint; //список треугольников. Узлы всегда обходятся против часовой стрелки Пользуйтесь! unit GridderSphere;
interface
uses Math;
const pi2 = 0.5*pi;
pi5 = 0.4*pi;
pi6 = pi/6;
pi10 = 0.2*pi;
gs_eps = 1e-10;
dvapi =2*pi;
type
TGeoCords = record
lat, lon : double;
end;
TPoint3D = record
x,y,z : double;
End;
var
gs_n_tris : longint;
gs_n_nodes : longint;
gs_node : array of TPoint3D;
gs_nodep : array [1..12] of TGeoCords;
gs_tri : array of array [1..3] of longint;
procedure FormSphere(const cx,cy,cz,rad,h : double);
implementation
procedure FormSphere(const cx,cy,cz,rad,h : double);
var i,nt,nn : longint;
tlevel : longint;
dtemp : double;
ind : array of array of longint;
edge : array [1..30] of array of longint;
n_edges : longint;
ed1,ed2,ed3 : array of longint;
function GetWPoint(pq1,pq2 : TPoint3d; w: double): TPoint3d;
var w1,tt:double;
r,r1,r2: TPoint3d;
begin
w1:=1-w;
r1.x:=pq1.x-cx;
r1.y:=pq1.y-cy;
r1.z:=pq1.z-cz;
r2.x:=pq2.x-cx;
r2.y:=pq2.y-cy;
r2.z:=pq2.z-cz;
r.x:=w*r2.x+w1*r1.x;
r.y:=w*r2.y+w1*r1.y;
r.z:=w*r2.z+w1*r1.z;
tt:=rad/sqrt(sqr(r.x)+sqr(r.y)+sqr(r.z));
r.x:=r.x*tt;
r.y:=r.y*tt;
r.z:=r.z*tt;
r.x:=cx+r.x;
r.y:=cy+r.y;
r.z:=cz+r.z;
Result:=r;
end;
function GetCoords(const ln,lt : double): TPoint3D;
var p : tpoint3d;
rr : double;
begin
rr:=rad*cos(lt);
p.x:=cx+rr*cos(ln);
p.y:=cy+rr*sin(ln);
p.z:=cz+rad*sin(lt);
Result:=p;
end;
procedure TesselateEdge(n1,n2:longint);
var i:longint;
begin
inc(n_edges);
edge[n_edges]:=nil;
SetLength(edge[n_edges],tlevel+1);
edge[n_edges][0]:=n1;
edge[n_edges][tlevel]:=n2;
for i:=1 to tlevel-1 do
begin
inc(nn);
edge[n_edges][i]:=nn;
gs_node[nn]:=GetWPoint(gs_node[n1],gs_node[n2],i/tlevel);
end;
end;
procedure TesselateTriangle(const n1,n2,n3 : longint);
var i,j,e1,e2,e3: longint;
function getEdge(const nn1,nn2:longint): longint;
var i: longint;
begin
for i:=1 to 30 do
begin
if (edge[i][0]=nn1) and (edge[i][tlevel]=nn2) then
begin
Result:=i;
exit;
end;
if (edge[i][0]=nn2) and (edge[i][tlevel]=nn1) then
begin
Result:=-i;
exit;
end;
end;
end;
begin
e1:=GetEdge(n1,n2);
e2:=GetEdge(n1,n3);
e3:=GetEdge(n2,n3);
if e1>0 then
for i:=0 to tlevel do
ed1[i]:=edge[e1][i]
else
for i:=0 to tlevel do
ed1[i]:=edge[-e1][tlevel-i];
if e2>0 then
for i:=0 to tlevel do
ed2[i]:=edge[e2][i]
else
for i:=0 to tlevel do
ed2[i]:=edge[-e2][tlevel-i];
if e3>0 then
for i:=0 to tlevel do
ed3[i]:=edge[e3][i]
else
for i:=0 to tlevel do
ed3[i]:=edge[-e3][tlevel-i];
for i:=2 to tlevel-1 do
for j:=1 to i-1 do
begin
inc(nn);
gs_node[nn]:=GetWPoint(gs_node[ed1[i]],gs_node[ed2[i]],j/i);
ind[i,j]:=nn;
end;
for i:=0 to tlevel do
ind[i,0]:=ed1[i];
for i:=1 to tlevel do
ind[i,i]:=ed2[i];
for i:=1 to tlevel-1 do
ind[tlevel,i]:=ed3[i];
for i:=0 to tlevel-1 do
begin
for j:=0 to i do
begin
inc(nt);
gs_tri[nt][1]:=ind[i,j];
gs_tri[nt][2]:=ind[i+1,j];
gs_tri[nt][3]:=ind[i+1,j+1];
end;
for j:=0 to i-1 do
begin
inc(nt);
gs_tri[nt][1]:=ind[i,j];
gs_tri[nt][2]:=ind[i+1,j+1];
gs_tri[nt][3]:=ind[i,j+1];
end;
end;
end;
begin
gs_n_tris :=0;
gs_n_nodes :=0;
gs_node :=nil;
gs_tri :=nil;
dtemp:=0.95*rad;
tlevel:=ceil(dtemp/h);
gs_n_tris := 20*sqr(tlevel);
gs_n_nodes := 10*sqr(tlevel)+2;
SetLength(gs_node,gs_n_nodes+1);
SetLength(gs_tri,gs_n_tris+1);
nt:=0;
nn:=12;
ind:=nil;
SetLength(ind,tlevel+1);
for i:=0 to tlevel do
SetLength(ind[i],i+1);
gs_nodep[1].lat:=pi2;
gs_nodep[1].lon:=0;
gs_nodep[2].lat:=-pi2;
gs_nodep[2].lon:=0;
for i:=0 to 4 do
begin
gs_nodep[i+3].lon:=i*pi5;
gs_nodep[i+3].lat:=pi6;
end;
for i:=0 to 4 do
begin
gs_nodep[i+8].lon:=i*pi5+pi10;
gs_nodep[i+8].lat:=-pi6;
end;
for i:=1 to 12 do
gs_node[i]:=GetCoords(gs_nodep[i].lon,gs_nodep[i].lat);
n_edges:=0;
TesselateEdge(1,3);
TesselateEdge(1,4);
TesselateEdge(1,5);
TesselateEdge(1,6);
TesselateEdge(1,7);
TesselateEdge(2,8);
TesselateEdge(2,9);
TesselateEdge(2,10);
TesselateEdge(2,11);
TesselateEdge(2,12);
TesselateEdge(3,12);
TesselateEdge(3,8);
TesselateEdge(4,8);
TesselateEdge(4,9);
TesselateEdge(5,9);
TesselateEdge(5,10);
TesselateEdge(6,10);
TesselateEdge(6,11);
TesselateEdge(7,11);
TesselateEdge(7,12);
TesselateEdge(3,4);
TesselateEdge(4,5);
TesselateEdge(5,6);
TesselateEdge(6,7);
TesselateEdge(3,7);
TesselateEdge(8,9);
TesselateEdge(9,10);
TesselateEdge(10,11);
TesselateEdge(11,12);
TesselateEdge(8,12);
ed1:=nil;
ed2:=nil;
ed3:=nil;
SetLength(ed1,tlevel+1);
SetLength(ed2,tlevel+1);
SetLength(ed3,tlevel+1);
TesselateTriangle(1,7,3);
TesselateTriangle(1,6,7);
TesselateTriangle(1,5,6);
TesselateTriangle(1,4,5);
TesselateTriangle(1,3,4);
TesselateTriangle(6,11,7);
TesselateTriangle(7,11,12);
TesselateTriangle(7,12,3);
TesselateTriangle(3,12,8);
TesselateTriangle(3,8,4);
TesselateTriangle(4,8,9);
TesselateTriangle(4,9,5);
TesselateTriangle(5,9,10);
TesselateTriangle(5,10,6);
TesselateTriangle(6,10,11);
TesselateTriangle(2,12,11);
TesselateTriangle(2,8,12);
TesselateTriangle(2,9,8);
TesselateTriangle(2,10,9);
TesselateTriangle(2,11,10);
end;
end.
-
> Franzy (18.02.10 14:55) [5]
да я думаю, что это
в целом слегка продвинулся для полосы треугольников, где нижний ряд вершин плотнее, чем верхний ряд вершин, нижние треугольники строятся довольно просто нижнее ребро образуют две соседнии вершины, вертикальные ребра строятся к вершине, которая ближе всего и находится дальше, либо над левой нижней вершиной... запутано получилось.
возьмем два соседних ряда (параллели) вешин H1,H2,H3,H4,H5,H6 L1,L2,L3,L4,L5,L6,L7,L8,L9 в верхнем (H) ряду вершины будут расположены с интервалом 60 градусов в нижнем - 40
один из рядов начинается не с нуля а с половины промежутка чтоб избежать появления явного шва пусть это будет... ну, скажем, нижний ряд
построим треугольник от вершины L7 положение L7 = 6 * 40 + 20 = 260 градусов положение L8 = 7 * 40 + 20 = 300 градусов какая вершина из верхнего ряда лучшим образом подойдет для завершения данного треугольника Ответ: та, чье положение в ряду >= 260 градусам, и та что ближе всего к этому значению поскольку ряд не имеет смещения, можно вычислить положение нашей вершины оно равно ceil(260 / 60) * 60 = 300 что соответствует вершине H6 проверим? предыдущая вершина H5 имеет положение 240 градусов и явно не подходит значит наш треугольник образуется вершинами L7-L8-H6
но как быть с обратным ему рядом? вот с этим я пока не разобрался
-
> Franzy (18.02.10 15:08) [6]
анализирую, при беглом осмотре смутил лишь участок с предварительно прописаными входными данными функции
TesselateEdge(1,3);
TesselateEdge(1,4);
...
TesselateEdge(11,12);
TesselateEdge(8,12);
-
Идея алгоритма проста: берется икосаэдр (20-гранник из правильных треугольников) и каждая его грань делится на 4, 9, 16 ... и т.д. - сколько нужно - треугольников. Причем узлы при этом проецируются на поверхность сферы. Получается очень красиво и аккуратно. Автокад со своими сферами курит в сторонке. Если смущает 20 команд по разбитию каждого ребра и каждой грани икосаэдра, можешь попробовать засунуть их в цикл. В один скорее всего не получится, придется использовать 4-5. На мой взгляд, овчинка выделки не стоит. Так вполне наглядно и, главное, надежно.
-
-
я, наверное, не понимаю проблемы, но вот такое решение
на шаре прочерчиваем параллели, на каждой параллели берем сколь угодно равноотстоящих точек и получаем прямоугольники с вершинами на параллелях шара. Устремляя колво параллелей и точек на каждой в бесконечность имеем шар.
-
> [11] 12 © (24.02.10 16:37)
это не будет геосфера.
-
> это не будет геосфера.
а как будет? В инете поискал определение - чего-то не то выдает > Вот картинка > http://slil.ru/28669800
это - геосфера? Если да, то в чем разница?
-
> [13] 12 © (25.02.10 09:22) > это - геосфера? Если да, то в чем разница?
Где там прямоугольники??
-
> Где там прямоугольники??
нет их там. Там треугольники. т.е. геосфера - это то, что состоит из треугольников? если так, то прямоугольник это 2 треугольника..
-
> [15] 12 © (25.02.10 16:00)
из равносторонних.
-
> в чем разница?
в том, что геосфера не имеет явного сгущения абсолютно не нужных вершин у полюсов
-
спасибо товарищу Franzy идею я понял и насколько я понял, в принципе можно взять любой правильный многогранник, грани которого образованы равнобедренными треугольниками (да хоть бы и тетраэдр) разбить каждую грань на N-ое количество подобных треугольников и равноудалить вершины от центра сферы хорошая, годная методика
-
Таких многранников ровно три: тетраэдр, октаэдр и икосаэдр. И, кстати, не обольщайтесь: треугольники в моей сфере не правильные, а только близки к ним, хотя и весьма сильно. Это на плоскости если правильный треугольник поделить на 4 равных треугольника они тоже будут правильными. У сферической геометрии свои законы.
-
Совершенно верно, поэтому тесселяцию нужно делать перед сферизацией. Тогда, если исходный многогранник правильный, то и получившиеся треугольники будут правильными.
-
Нет, не будут. Они исказятся при проекции.
|