Render.ru

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

aly8

Активный участник
Рейтинг
10
#1
Всем кому интересна задача о пересечении двух объектов предлагаю объединить усилия.
Есть небольшой задел, в виде решенной задачи о пересечении двух треугольников:


Код:
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
может быть удастся реализовать нормальный булеан (если это в принципе возможно)
 
Сверху