1. Пользоваться форумом на планшетах и телефонах стало удобнее благодаря Tapatalk

Угол между полигонами

Тема в разделе "MAXScript", создана пользователем kolts, 6 авг 2011.

Модераторы: Savin Denis
  1. kolts

    kolts Активный участник

    С нами с:
    05.02.2008
    Сообщения:
    448
    Симпатии:
    0
    Баллы:
    17
    Кто знает как найти угол между полигонами если между ними больше 180 градусов. Если меньше проблем нет, находим угол между нормалями Acos(dot n1 n2). Потом от 180 отнимаем полученое. Но если между полигонами больше 180 градусов не знаю как найти
     
  2. JBond

    JBond Знаток

    С нами с:
    17.06.2009
    Сообщения:
    451
    Симпатии:
    5
    Баллы:
    37
    может найти острый угол и отнять от 360 ?
     
  3. kolts

    kolts Активный участник

    С нами с:
    05.02.2008
    Сообщения:
    448
    Симпатии:
    0
    Баллы:
    17
    Суть в том что полигонов много и мне надо находить углы между ними. Между какими то угол меньше 180 между какими то больше. Если бы была одна пара то конечно я бы так и сделал.
     
  4. JBond

    JBond Знаток

    С нами с:
    17.06.2009
    Сообщения:
    451
    Симпатии:
    5
    Баллы:
    37
    Можно определить в каком квадранте лежит второй вектор относительно первого.
    Если он лежит в области где угол будет тупым поменять его знак, вычилить арккс дот продакт и прибавить 180гр
     
  5. kolts

    kolts Активный участник

    С нами с:
    05.02.2008
    Сообщения:
    448
    Симпатии:
    0
    Баллы:
    17
    Но как это сделать? Не представляю как. Дело в том что если между полигонами 270 между нормалями 90, если между полигонами 90 то между нормалями тоже 90. Короче говоря надо как то понять что угол больше 180 а найти угол уже дело техники.
     
  6. JBond

    JBond Знаток

    С нами с:
    17.06.2009
    Сообщения:
    451
    Симпатии:
    5
    Баллы:
    37
    Я бы попробовал проверить по знаку координат в векторе
    в первом квадранте = +X +Y
    во втором = -X + Y
    в третьем = -X - Y
    в четвертом = +X - Y
    *************************************************************
    у нас есть два вектора A и B

    создаем функцию
    fn ZoneCheck varVector =

    ( If (varVector.x > 0 )&&(varVector.y > 0 ) then b = 1
    ----------------------------- b = 2
    ----------------------------- b = 3
    ----------------------------- b = 4
    return b
    )
    проверяем в каком квадранте и A и B .
    Потом проверяем соотношение зоны вектора B к зоне вектора A.

    if VectorZoneCheck(A) ==1 then if VectorZoneCheck(B) == 2 do Acos(dot normolizeA normolizeB) elseif VectorZoneCheck(B) == 4 do ( Acos(dot normolizeA -normolizeB) + 180)

    Тут получается что если фукнция вернула для ZC(A)=1 иZC(B) =2 угол гарантировано до 180гр, если A=1 и B=4 то угол больше 180 в любом случае.
    Остается вариант ZC(A)=1 и ZC(B) =3 тут все зависит от положения векторов в каких то случаях он может быть больше 180 в каких то нет.


    Для этого варианта можно проверить так - нормализовать оба вектора и вектору A поменять знак .Тогда он станет лежать тоже в квадранте 3 .
    Затем проверяем его координату Y если она больше координаты вектора B значит угол между ними больше 180 если нет то меньше

    Надеюсь в этом есть смысл:)
     

    Вложения:

    • 2394257.jpg
      2394257.jpg
      Размер файла:
      65,7 КБ
      Просмотров:
      54
  7. igorznag

    igorznag Знаток

    С нами с:
    23.04.2010
    Сообщения:
    1.255
    Симпатии:
    172
    Баллы:
    65
    kolts
    Условия:
    1. Полигоны должны иметь одно общее ребро (Edge).
    2. Полигоны должны быть плоскими (planar) и выпуклыми (convex).
    Выпуклый многоугольник (полигон) это многоугольник без самопересечений такой, что каждый внутренний угол которого не более 180 градусов.
    Если эти условия соблюдаются для твоего случая, тогда попробуй так:
    Код:
    rollout igorznag_get_angle "Get angle" width:160 height:60
    (
    edittext text_angle "" pos:[5,5] width:145
    button btn_apply "Get angle" pos:[50,30]
    
    fn get_angle obj face_index1 face_index2=
    (
    if(classof obj == Editable_Poly)then
    (
    fes1=(polyOp.getFaceEdges obj face_index1) as bitarray;
    fes2=(polyOp.getFaceEdges obj face_index2) as bitarray;
    fes=fes1*fes2;
    if(fes.numberSet==1)then
    (
    fes=fes as array; fe=fes[1];
    evs=polyOp.getEdgeVerts obj fe; ev=polyOp.getVert obj evs[1]
    fc=polyop.getFaceCenter obj face_index1; v=fc-ev
    n1=polyop.GetFaceNormal obj  face_index1; n2=polyop.getFaceNormal obj face_index2;
    d=dot v n2; a=acos(dot n1 n2);
    if(d>0)then a=180+a  else a=180-a
    return a;
    )))--fn get_angle
    
    on btn_apply pressed do
    (
    text_angle.text="";
    if(classof $ == Editable_Poly)then
    (
    faces=(polyop.getFaceSelection $) as array
    if(faces.count==2)then
    (
    text_angle.text=(get_angle $ faces[1] faces[2]) as string
    ))))
    createdialog igorznag_get_angle style:#(#style_titlebar, #style_border, #style_sysmenu,#style_minimizebox)
    1. Запусти скрипт.
    2. Выдели 2 полигона, для которых соблюдаются условия.
    3. Нажми кнопку "Get angle".
    Объект должен быть Editable Poly (без модификаторов).
     
  8. kolts

    kolts Активный участник

    С нами с:
    05.02.2008
    Сообщения:
    448
    Симпатии:
    0
    Баллы:
    17
    Работает только надо поменять "if(d>0)then a=180+a else a=180-a" на "if(d>0)then a=180-a else a=180+a" Большое спасибо. В принципе мне это нужно для правильных сеток, поэтому условия будут соблюдены.
    Вообще мне интересно сделать нормальный чамфер в максе. Пока накатал вот такой

    Код:
    macroScript QuadChamf
        category:"Kolts"
        toolTip:"Quadchamfer"
    (
        rollout QuadChamferRol "QuadChamfer" width:129 height:110
        (
            fn SelectInvert obj subobj = 
            (
                local cursel = #{}--current selected subobjects
                if( subobj == 1) --subobject level verts
                do
                (
                cursel = polyop.getvertselection obj
                polyop.setvertselection obj #{1..(polyop.getnumverts obj)}
                polyop.setvertselection obj ((polyop.getvertselection obj) - cursel)
                cursel = polyop.getvertselection obj
                return cursel
                )
                if( subobj == 2) --subobject level edges
                do
                (
                    cursel = polyop.getEdgeSelection obj
                    polyop.setEdgeSelection obj #{1..(polyop.getNumEdges obj)}
                    polyop.setEdgeSelection obj ((polyop.getEdgeSelection obj) - cursel)
                    cursel = polyop.getEdgeSelection obj
                    return cursel
                )
                if( subobj == 4) --subobject level edges
                do
                (
                    cursel = polyop.getFaceSelection obj
                    polyop.setFaceSelection obj #{1..(polyop.getNumFaces obj)}
                    polyop.setFaceSelection obj ((polyop.getFaceSelection obj) - cursel)
                    cursel = polyop.getFaceSelection obj
                    return cursel
                )
            )
    
            fn quadChamferfunc obj ChamferAmount ChamferSegments =
        (
            local NumFaces = polyop.getnumfaces obj
            local A = polyop.GetEdgeSelection obj
            undo "Quad chamfer" on
            (
                obj.edgeChamferSegments = 1
                polyop.chamferEdges obj A ChamferAmount
                polyop.Setfaceselection obj #{(NumFaces+1)..(polyop.getnumfaces obj)}
                obj.EditablePoly.tessellate #Face
                local A = polyop.getedgeselection obj
                setfaceselection obj #{1..NumFaces}
                polyop.setEdgeSelection obj (polyop.getEdgesUsingFace obj (polyop.getFaceSelection obj))
                local B = polyop.getEdgeSelection obj
                polyop.setEdgeSelection obj (A - B)
                C = polyop.getVertsUsingEdge obj (polyop.getEdgeSelection obj)
                obj.Remove ()
                local D = polyop.getnumedges obj
                polyop.setvertSelection obj C        
                obj.Remove selLevel: #Vertex
                 SelectInvert obj 4  --invert selected faces
                obj.EditablePoly.ConvertSelection #Face #Edge
                SelectInvert obj 2    --invert selected edges
                obj.EditablePoly.SelectEdgeLoop ()
                SelectInvert obj 4    --invert selected faces
                obj.EditablePoly.ConvertSelection #Face #Edge
                obj.EditablePoly.SelectEdgeLoop ()
                SelectInvert obj 2
                PolyToolsModeling.SetFlow false
                obj.EditablePoly.ConvertSelection #Edge #Vertex
                obj.EditablePoly.ShrinkSelection selLevel: #Vertex
                PolyToolsModeling.SetFlowVertex()
                PolyToolsModeling.SetFlowVertex()
                if(ChamferSegments == 3) do (
                polyop.chamferEdges obj (polyop.getEdgeSelection obj) (ChamferAmount/3)
                PolyToolsModeling.SetFlow false
                PolyToolsModeling.SetFlowVertex()
                )
                redrawViews()
            )    
        )
                spinner ChamferAmountspn "Amount" pos:[14,17] width:79 height:16 range:[0,1000,0]
                button ChamferBtn "Chamfer" pos:[24,72] width:67 height:22
                spinner Segmentsspn "Segs" pos:[25,42] width:67 height:16 range:[2,3,2] type:#integer
                local flag = 0
                on ChamferBtn pressed do
                (
                    flag = 0
                    if (classof $ == Editable_Poly and subobjectlevel == 2)  do flag = 2
                    local EdgeSel = polyop.getedgeselection $                
                    if EdgeSel.numberset == 0 do flag = 1
                    if flag == 2 do
                    quadChamferfunc $ ChamferAmountspn.value Segmentsspn.value
                )
            )
    
        createdialog QuadChamferRol
    )
    Пока несерьезно, думаю переделать и жду помощи. Какие есть идеи насчет этого
     
Модераторы: Savin Denis

Поделиться этой страницей