I do not know anything about AI.
Confining myself to the programming part relating to lines and cubes (3d geometry), purely out of academic interest.
We can use any of the functions hb_jsonEncode(), hb_ValToExp(), ValToPrgExp() of FW_ValToExp().
All these functions convert array to string making it easy for comparision.
The above samples test whether the line a2 starts and ends at two vertices of the cube a1 and also inform the vertex numbers. In these samples, the conversion function is called 8 x 2 x 2 = 32 times.
Following samples have the same functionality but call the conversion function only 3 times.
- Code: Select all Expand view RUN
function CubeAndLine1()
local aCube := { { 0, 0, 0 }, { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 },;
{ 1, 1, 0 }, { 1, 0, 1 }, { 0, 1, 1 }, { 1, 1, 1 } }
local aLine := { { 0, 0, 0 }, { 1, 1, 1 } }
local cCube, ch, nVertex
cCube := hb_jsonEncode( aCube )
ch := Left( cCube, 1 )
if ( nVertex := NumAt( ch, Left( cCube, At( hb_jsonEncode( aLine[ 1 ] ), cCube ) - 1 ) ) ) > 0
? "aLine starts at Vertex No: " + Str( nVertex, 2, 0 ) + " of the Cube"
else
? "Start of aLine is not at any vertex of the cube"
endif
if ( nVertex := NumAt( ch, Left( cCube, At( hb_jsonEncode( aLine[ 2 ] ), cCube ) - 1 ) ) ) > 0
? "aLine ends at Vertex No: " + Str( nVertex, 2, 0 ) + " of the Cube"
else
? "End of aLine is not at any vertex of the cube"
endif
return nil
/*
// function NumAt() is from hbct.lib.
// In case hbct.lib is not linked, we can use this function
//
static function NumAt( c, cStr )
local nAt := 0
local nCount := 0
do while ( nAt := hb_At( c, cStr, nAt + 1 ) ) > 0
nCount++
enddo
return nCount
*/
Another variant:
- Code: Select all Expand view RUN
function CubeAndLine2()
local aCube := { { 0, 0, 0 }, { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 },;
{ 1, 1, 0 }, { 1, 0, 1 }, { 0, 1, 1 }, { 1, 1, 1 } }
local aLine := { { 0, 0, 0 }, { 1, 1, 1 } }
local cCube, pt
cCube := hb_ValToExp( aCube )
if ( pt := hb_ValToExp( aLine[ 1 ] ) ) $ cCube
? "aLine starts at Vertex: " + pt + " of the Cube"
else
? "Start of aLine is not at any vertex of the cube"
endif
if ( pt := hb_ValToExp( aLine[ 2 ] ) ) $ cCube
? "aLine ends at Vertex: " + pt + " of the Cube"
else
? "End of aLine is not at any vertex of the cube"
endif
return nil
This logic works not only for cube/cuboid but also for any solid having any number of vertices.
I do not thik this is required.
Still for academic interest, if one likes to know if a Line is completely inside a cube/cuboid, this sample answers the question:
- Code: Select all Expand view RUN
function LineInCube()
local aCube := { { 0, 0, 0 }, { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 },;
{ 1, 1, 0 }, { 1, 0, 1 }, { 0, 1, 1 }, { 1, 1, 1 } }
local aLine := { { 0.1, 0.2, 0.8 }, { 0.6, 0.4, 0.3 } }
local aMin := Array( 3 )
local aMax := Array( 3 )
local c
AEval( aCube, { |aVertex|
local n
for n := 1 to 3
if aMin[ n ] == nil .or. aMin[ n ] > aVertex[ n ]
aMin[ n ] := aVertex[ n ]
endif
if aMax[ n ] == nil .or. aMax[ n ] < aVertex[ n ]
aMax[ n ] := aVertex[ n ]
endif
next
return nil
} )
if IsPointInside( aLine[ 1 ], aMin, aMax )
c := "Line starts inside the cube and "
if IsPointInside( aLine[ 2 ], aMin, aMax )
c += "ends inside the cube"
else
c += "ends outside the cube"
endif
else
c := "Line starts outside the cube and "
if IsPointInside( aLine[ 2 ], aMin, aMax )
c += "ends inside the cube"
else
c += "ends outside the cube"
endif
endif
? c
return nil
function IsPointInside( aPoint, aMin, aMax )
return ( aPoint[ 1 ] >= aMin[ 1 ] .and. aPoint[ 1 ] <= aMax[ 1 ] .and. ;
aPoint[ 2 ] >= aMin[ 2 ] .and. aPoint[ 2 ] <= aMax[ 2 ] .and. ;
aPoint[ 3 ] >= aMin[ 3 ] .and. aPoint[ 3 ] <= aMax[ 3 ] )
Now, this logic can be extended to check if a small cube/cuboid is fully enclosed by another larger cube/cuboid.
Logic: Check if both the min and max points of the small cube are in between the min and max points of the larger cube.
This logic works even with more complex solids with any number of vertices, but with one big exception.
Exception:
This logic works only if the larger solid is completely convex (convex at every vertex) and fails in case of concave solids.