Author Topic: Region inside region  (Read 4686 times)

0 Members and 1 Guest are viewing this topic.

Lupo76

  • Bull Frog
  • Posts: 343
Region inside region
« on: December 06, 2014, 11:45:29 AM »
Hello everyone,
I tried several solutions but I can never reach my goal.  :cry:

I have two regions (Region1 and Region2).
I need a function that is able to emit T, when Region1 is completely within Region2.
I could use the Subtract command but is too slow!

Do you have any advice?
« Last Edit: December 06, 2014, 11:59:03 AM by Lupo76 »

Lee Mac

  • Seagull
  • Posts: 12928
  • London, England
Re: Region inside region
« Reply #1 on: December 06, 2014, 12:35:03 PM »
My suggestions would have been to either:
  • Union Region1 with Region2 and return T if the area of Region2 is unchanged
or
  • Subtract Region1 from Region2 and return T if the new area of Region2 equals the old area minus the area of Region1
or
  • Intersect Region1 & Region2 and return T if the area of the intersection equals the area of Region1.

Lupo76

  • Bull Frog
  • Posts: 343
Re: Region inside region
« Reply #2 on: December 06, 2014, 01:03:06 PM »
Hello Lee Mac,
thanks for your answer.
unfortunately Boolean operations are too slow.
I have to do this check hundreds of regions  :-(

ymg

  • Guest
Re: Region inside region
« Reply #3 on: December 06, 2014, 02:25:31 PM »
Lupo76,

You could test for intersections of each segment of polyline 1 against polyline 2.

not too sure it would be any faster than above mentionned method though.  :?

Maybe first test the bounding box of polyline 1 against polyline 2, and do the intersections
or boolean test only if the bb test pass.

ymg

mkweaver

  • Bull Frog
  • Posts: 352
Re: Region inside region
« Reply #4 on: December 06, 2014, 02:40:16 PM »
Have you tried doing the boolean operations with active-x (vla-boolean obj1 acsubtraction obj2) instead of with the commands?  Active-x tends to be much faster than with command.

Mike

Lee Mac

  • Seagull
  • Posts: 12928
  • London, England
Re: Region inside region
« Reply #5 on: December 06, 2014, 02:56:56 PM »
Maybe first test the bounding box of polyline 1 against polyline 2, and do the intersections
or boolean test only if the bb test pass.

Good idea ymg - perhaps the following could be an initial draft of such a function:

Code - Auto/Visual Lisp: [Select]
  1. ;; Returns T if region 1 is entirely inside region 2
  2. (defun insideregion-p ( rg1 rg2 / a b c d e r )
  3.     (vla-getboundingbox rg1 'a 'b)
  4.     (vla-getboundingbox rg2 'c 'd)
  5.     (and
  6.         (apply 'and
  7.             (apply 'mapcar
  8.                 (cons '<=
  9.                     (mapcar 'vlax-safearray->list (list c a b d))
  10.                 )
  11.             )
  12.         )
  13.         (progn
  14.             (setq e (vla-copy rg2))
  15.             (vla-boolean e acunion (vla-copy rg1))
  16.             (setq r (equal (vla-get-area rg2) (vla-get-area e) 1e-8))
  17.             (vla-delete e)
  18.             r
  19.         )
  20.     )
  21. )

Test program:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / a b )
  2.     (if
  3.         (and
  4.             (princ "\nSelect 1st region: ")
  5.             (setq a (ssget "_+.:E:S" '((0 . "REGION"))))
  6.             (princ "\nSelect 1st region: ")
  7.             (setq b (ssget "_+.:E:S" '((0 . "REGION"))))
  8.         )
  9.         (if (insideregion-p
  10.                 (vlax-ename->vla-object (ssname a 0))
  11.                 (vlax-ename->vla-object (ssname b 0))
  12.             )
  13.             (princ "\n1st region is entirely INSIDE 2nd region.")
  14.             (princ "\n1st region is partially or entirely OUTSIDE 2nd region.")
  15.         )
  16.     )
  17.     (princ)
  18. )

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1454
  • Marco
Re: Region inside region
« Reply #6 on: December 07, 2014, 04:34:07 AM »
Just an idea for a new approach if the regions have straight sides:

if area of r1 is less of area r2 > ssget "_CP" with r1 vertex and see if r2 is selected...

mailmaverick

  • Bull Frog
  • Posts: 495
Re: Region inside region
« Reply #7 on: December 07, 2014, 06:44:34 AM »
Just an idea for a new approach if the regions have straight sides:

if area of r1 is less of area r2 > ssget "_CP" with r1 vertex and see if r2 is selected...

Excellent idea Marc !!!

I think Marc's code would be fastest.


Lee Mac

  • Seagull
  • Posts: 12928
  • London, England
Re: Region inside region
« Reply #8 on: December 07, 2014, 06:48:01 AM »
if area of r1 is less of area r2 > ssget "_CP" with r1 vertex and see if r2 is selected...

A good idea, but this method would return a false positive if region 1 partially overlaps region 2...

Stefan

  • Bull Frog
  • Posts: 319
  • The most I miss IRL is the Undo button
Re: Region inside region
« Reply #9 on: December 07, 2014, 07:41:17 AM »
Another method is to compare area of intersection against area of original regions.
This way you can verify if r1 is inside r2 or vice versa.
This will return nil or a list in which first element is the region containing the other region.
Code - Auto/Visual Lisp: [Select]
  1. (defun reg_inside (r1 r2 / a1 a2 a r)
  2.   (vla-boolean (setq r (vla-copy r1)) acintersection (vla-copy r2))
  3.   (setq a1 (vla-get-area r1)
  4.         a2 (vla-get-area r2)
  5.         a  (vla-get-area r )
  6.         )
  7.   (vla-delete r)
  8.   (cond
  9.     ((equal a a1 1e-8) (list r2 r1))
  10.     ((equal a a2 1e-8) (list r1 r2))
  11.   )
  12. )

@Lupo76: How do you intend to compare hundreds of regions? What is the expected result?
« Last Edit: December 07, 2014, 07:44:40 AM by Stefan »

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Region inside region
« Reply #10 on: December 07, 2014, 08:03:34 AM »
Another idea for a 'pre-check': compare the areas of the regions before performing any boolean operations. Region 1 cannot be completely inside region 2 if its area is too big.

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Region inside region
« Reply #11 on: December 07, 2014, 08:07:49 AM »
Using Marc'Antonio Alessi's suggestion is problematic if the original regions have 'islands'.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1454
  • Marco
Re: Region inside region
« Reply #12 on: December 07, 2014, 03:06:24 PM »
if area of r1 is less of area r2 > ssget "_CP" with r1 vertex and see if r2 is selected...

A good idea, but this method would return a false positive if region 1 partially overlaps region 2...
Lee, I assumed that r1 is internal or partially overlaps r2 so:   (pseudo code)
Code: [Select]
(if area of r1 is less of area r2
  (progn
    ssget "_CP" with r2 vertex and see if r1 is selected... if false r1 is external
    ssget "_CP" with r1 vertex and see if r2 is selected... if true regions overlaps
         if false > "Region1 is completely within Region2"
   )
)

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1454
  • Marco
Re: Region inside region
« Reply #13 on: December 07, 2014, 03:07:00 PM »
Using Marc'Antonio Alessi's suggestion is problematic if the original regions have 'islands'.
have you an example?

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Region inside region
« Reply #14 on: December 07, 2014, 04:49:21 PM »
Using Marc'Antonio Alessi's suggestion is problematic if the original regions have 'islands'.
have you an example?
If you subtract a region from another region, the result can be a new region with an island or hole at its center. Inside that hole a different region may be located that does not at any point overlap the region containing the hole.
« Last Edit: December 07, 2014, 04:52:57 PM by roy_043 »