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

пересечение двух объектов

Тема в разделе "MAXScript", создана пользователем aly8, 15 сен 2009.

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

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

    С нами с:
    22.12.2005
    Сообщения:
    31
    Симпатии:
    0
    Баллы:
    10
    Всем кому интересна задача о пересечении двух объектов предлагаю объединить усилия.
    Есть небольшой задел, в виде решенной задачи о пересечении двух треугольников:


    Код:
    rollout testFaceCollision "testFaceCollision" width:400 
    (
    	button create01 "Create" width:100 align:#center
    	group "Parameters T1"
    	(
    		label lblt0 "M1 [x1, y1, z1], M2 [x2, y2, z2], M3 [x3, y3, z3]" align:#center
    		label lblt1 "-------------------------------------" align:#center
    		spinner x1 "x1  " width:100	range:[-1000.0,1000.0,-5.9] type:#float align:#right across:3
    		spinner y1 "y1" width:100  range:[-1000.0,1000.0,-8.5] type:#float align:#right
    		spinner z1 "z1 " width:100 range:[-1000.0,1000.0,12.5] type:#float   align:#right 
    		label lblt2 "-------------------------------------" align:#center
    		spinner x2 "x2  " width:100	range:[-1000.0,1000.0,-9.4] type:#float align:#right across:3
    		spinner y2 "y2" width:100  range:[-1000.0,1000.0,-12.7] type:#float align:#right
    		spinner z2 "z2 " width:100 range:[-1000.0,1000.0,3.8] type:#float   align:#right 
    		label lblt3 "-------------------------------------" align:#center
    		spinner x3 "x3  " width:100	range:[-1000.0,1000.0,-4.3] type:#float align:#right across:3
    		spinner y3 "y3" width:100  range:[-1000.0,1000.0,-11.2] type:#float align:#right
    		spinner z3 "z3 " width:100 range:[-1000.0,1000.0,10.2] type:#float   align:#right 
    	)		
    	group "Parameters T2"
    	(
    		label lblt4 "A [a1, b1, c1], B [a2, b2, c2], C [a3, b3, c3]" align:#center
    		label lblt5 "-------------------------------------" align:#center
    		spinner a1 "a1  " width:100	range:[-1000.0,1000.0,-10.3] type:#float align:#right across:3
    		spinner b1 "b1" width:100  range:[-1000.0,1000.0,-3.8] type:#float align:#right
    		spinner c1 "c1 " width:100 range:[-1000.0,1000.0,14.0] type:#float   align:#right 
    		label lblt6 "-------------------------------------" align:#center
    		spinner a2 "a2  " width:100	range:[-1000.0,1000.0,-8.8] type:#float align:#right across:3
    		spinner b2 "b2" width:100  range:[-1000.0,1000.0,-9.8] type:#float align:#right
    		spinner c2 "c2 " width:100 range:[-1000.0,1000.0,7.7] type:#float   align:#right 
    		label lblt7 "-------------------------------------" align:#center
    		spinner a3 "a3  " width:100	range:[-1000.0,1000.0,-2.2] type:#float align:#right across:3
    		spinner b3 "b3" width:100  range:[-1000.0,1000.0,-5.5] type:#float align:#right
    		spinner c3 "c3 " width:100 range:[-1000.0,1000.0,3.3] type:#float   align:#right 
    	)	
    --**********************
    fn createM =
    (
    	try(delete objects)catch()
    	local vert_array = #(), face_array = #(), 
    			v1 = [x1.value, y1.value, z1.value], 
    			v2 = [x2.value, y2.value, z2.value], 
    			v3 = [x3.value, y3.value, z3.value]
    	local v11 = [a1.value, b1.value, c1.value],
    			v22 = [a2.value, b2.value, c2.value],
    			v33 = [a3.value, b3.value, c3.value]	
    	vert_array = #(v1,v2,v3,v11,v22,v33)
    	face_array = #([1,2,3], [4,5,6])
    
    	local m = mesh vertices:vert_array faces:face_array
    	m.name = uniquename "triag"
    	)
    --*********************
    fn createOneVector startV endV theCol = 
    (
    	local theThicness = 0.1
    	local theV = endV - startV
    	local theDir = normalize theV
    	local theH = length theV
    	local cyl = cylinder pos:startV dir: theDir height: (0.9*theH) radius:(theThicness/5.0) name: (uniquename "Vector")
    	local con = cone pos:(startV + 0.9*theV) dir: theDir height: (0.1*theH) radius1:(theThicness/2.0) name: (uniquename "VectorArrow")
    	cyl.wirecolor = theCol
    	con.wirecolor = theCol
    	)
    --*********************	
    fn createOneText thePos theText theCol = 
    (
    	local textSize = 0.6
    	local theVS = getViewSize()
    	local theRay = mapScreenToWorldRay (theVS/2.0)
    	local t = text text:theText size:textSize pos: thePos dir: -theRay.dir 
    	t.wirecolor = theCol
    	)
    fn createText = 
    (
    	createOneText [x1.value, y1.value, z1.value] "M1" red
    	createOneText [x2.value, y2.value, z2.value] "M2" red
    	createOneText [x3.value, y3.value, z3.value] "M3" red
    	
    	createOneText [a1.value, b1.value, c1.value] "A" red
    	createOneText [a2.value, b2.value, c2.value] "B" red
    	createOneText [a3.value, b3.value, c3.value] "C" red
    	)
    --************************	
    fn PointInFace P1 P2 P3 P = 
    (
    	local vec1 = P2 - P1
    	local vec2 = P3 - P1
    	local squareFace = (length(cross vec1 vec2))/2.0
    -----
    	local vec3 = P1 - P
    	local vec4 = P2 - P
    	local squareFace1 = (length(cross vec3 vec4))/2.0
    -----
    	local vec5 = P2 - P
    	local vec6 = P3 - P
    	local squareFace2 = (length(cross vec5 vec6))/2.0
    ----
    	local vec7 = P3 - P
    	local vec8 = P1 - P
    	local squareFace3 = (length(cross vec7 vec8))/2.0
    	
    local sumArea = squareFace1 + squareFace2 + squareFace3
    if sumArea <= 1.000001*squareFace then return(true) else return(false)
    	
    	)	
    --************************	
    fn createVectors =
    (
    local A = [a1.value, b1.value, c1.value], 
    		B = [a2.value, b2.value, c2.value], 
    		C = [a3.value, b3.value, c3.value],
    		M1 = [x1.value, y1.value, z1.value],
    		M2 = [x2.value, y2.value, z2.value],
    		M3 = [x3.value, y3.value, z3.value]
    	
    local N1 = cross (B-A) (C-A),
    		N2 = N1/(length N1),
    		cent1 = (A+B+C)/3.0
    local N3 = cross (M2-M1) (M3-M1),
    		N4 = N3/(length N3),
    		cent2 = (M1+M2+M3)/3.0
    	
    createOneVector cent1 (cent1 + N2) blue
    createOneVector cent2 (cent2 + N4) blue
    createOneVector [0,0,0] A green
    createOneVector [0,0,0] B green
    createOneVector [0,0,0] C green
    createOneVector [0,0,0] M1 green
    createOneVector [0,0,0] M2 green
    createOneVector [0,0,0] M3 green
    	)
    --************************	
    fn findInterLinePlane planeP1 planeP2 planeP3 lineP1 lineP2 = 
    (
    	local n = cross (planeP2-planeP1) (planeP3-planeP1)
    	local normalPlane = n/(length n)
    
    local V = planeP1 - lineP1,
    		D = dot normalPlane V,
    		W = lineP2 - lineP1,
    		theE = dot normalPlane W
    local thePos = if theE != 0 then lineP1 + W*D/theE else (lineP1 + lineP2)/2.0
    	
    local LengthPos = length (lineP1 - thePos) + length (lineP2 - thePos)
    local lengthLine = 1.000001*length(lineP1 - lineP2)
    
    if (LengthPos <= lengthLine) and (PointInFace planeP1 planeP2 planeP3 thePos == true) then return(thePos) else return(undefined)
    	)
    --************************	
    fn findTriagInter = 
    (
    local A = [a1.value, b1.value, c1.value], 
    		B = [a2.value, b2.value, c2.value], 
    		C = [a3.value, b3.value, c3.value],
    		M1 = [x1.value, y1.value, z1.value],
    		M2 = [x2.value, y2.value, z2.value],
    		M3 = [x3.value, y3.value, z3.value]
    if findInterLinePlane A B C M1 M2 != undefined do point pos: (findInterLinePlane A B C M1 M2) size:1
    if findInterLinePlane A B C M1 M3 != undefined do point pos: (findInterLinePlane A B C M1 M3) size:1
    if findInterLinePlane A B C M2 M3 != undefined do point pos: (findInterLinePlane A B C M2 M3) size:1
    ----
    if findInterLinePlane M1 M2 M3 A B != undefined do point pos: (findInterLinePlane M1 M2 M3 A B) size:1
    if findInterLinePlane M1 M2 M3 A C != undefined do point pos: (findInterLinePlane M1 M2 M3 A C) size:1
    if findInterLinePlane M1 M2 M3 B C != undefined do point pos: (findInterLinePlane M1 M2 M3 B C) size:1
    
    local thePoints = $Point* as array
    if thePoints.count == 2 do createOneVector thePoints[1].pos thePoints[2].pos red
    	)
    --************************	
    fn theAllFunc = 
    (
    	createM()
    	createText()
    	createVectors()
    	findTriagInter()
    	)
    	
    --************************
    	
    on create01 pressed do theAllFunc()	
    --------------------------------	
    on x1 changed val do theAllFunc()
    on y1 changed val do theAllFunc()
    on z1 changed val do theAllFunc()
    on x2 changed val do theAllFunc()
    on y2 changed val do theAllFunc()
    on z2 changed val do theAllFunc()
    on x3 changed val do theAllFunc()
    on y3 changed val do theAllFunc()
    on z3 changed val do theAllFunc()
    ---------------------------------
    on a1 changed val do theAllFunc()
    on b1 changed val do theAllFunc()
    on c1 changed val do theAllFunc()
    on a2 changed val do theAllFunc()
    on b2 changed val do theAllFunc()
    on c2 changed val do theAllFunc()
    on a3 changed val do theAllFunc()	
    on b3 changed val do theAllFunc()
    on c3 changed val do theAllFunc()
    )--end rollout
    createDialog testFaceCollision 
    
    вот что нашел в интернете: http://algolist.manual.ru/maths/geom/intersect/lineplain3d.php
    может быть удастся реализовать нормальный булеан (если это в принципе возможно)
     
Модераторы: Savin Denis

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