Jump to content

Wall Collision Question


aquila
 Share

Recommended Posts

As you can see at the picture, i have a white room. In this room there are 2 People, the green circles. They can't see each other as you can see, because the red line is going through the wall.

At the moment I have the coordinates of the two circles and I use a little bit of maths to get the coords of the red line. Then I check with _GDIPlus_GetPixel all the pixels from the red line, if it's black. Now the Problem: If there are 5 persons, i can't check them all each other, it is too slow. It tooks 300ms i think and this is tooo much, because the persons should move and if they move every 300ms, it looks like laggy. Now, is there another way maybe? Maybe drawing a line btwn the two circles and check if the line gets cuttet by a black pixel or something like that.

thx,

aquila

post-32742-12649488435112_thumb.jpg

Edited by aquila
Link to comment
Share on other sites

idea is not bad, but won't change anything, still too slow. the methode is a bad choice :D

I think i use 2 scripts now.

One by moving the persons and one who checks the collision.

Edited by aquila
Link to comment
Share on other sites

I will exit the loop if it detects a black pixel, yep. I know that whould be a rly different but thx for the question. The room is not always the same shape.

I also read the pixel colors into an array of the full map. This gives a little bit more speed.

Link to comment
Share on other sites

Your problem is hidden object removal in vector graphics.

Determine the edges of the room and walls: either they are given, computable or use a dichotomic horizontal then vertical test with your GetPixel thing. This step is fast if the room has a fixed shape for some time. If its always changing (i.e. the wall is in fact a moving thing), then things get a bit more messy/slow.

Once you have everything in cartesian coordinates, split your room into quadrants (by continuation of the wall's edges). Separate the (green) points into 3 groups, one for each free quadrant (noone can be "inside" the wall). Obvious facts: points can see other points in the same group. Points in the quadrant opposite to the wall can see everybody. See/be seen is equivalent.

Now the only question that needs to be sorted out is for points in quadrant adjacent to the wall. In you schema, that means N-E and S-W quadrants. At this point polar coordinates will be faster. It will remind you basic trigonometry and show that it can be of actual use in simple problems.

For each point in one quadrant (choose either N-E or S-W, it doesn't matter) compute the angle from this point to the wall vertex. Then compute the angle of the line to every point in the other quadrant (S-W or N-E, resp) and check it's within the wall'vertex angle. You don't have to compute the angle measure itself, a Sin or Cos will do.

It's much longer to describe than to draw and code. The resulting code will be way faster than any pixel color test, and can easily scale to more walls and a decent crowd. Obviously, if you have 10000 "people" in your "room" then it will take some time.

Edit: typo very --> every

BTW, if you only need to assert visibility for a limited number of points, then you can find it faster to drop the quadrant separation altogether.

Edited by jchd

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Addendum:

It's likely that some standard graphics subsystem would offer such hidden line/object removal for 3-D graphics implemented in a very efficient way. I really don't know if it's available, commonly installed, easy to use but perhaps users proficient with graphics subsystems can comment on this. Even if that sounds a bit like "killing a fly with a nuke" in the case at hand, it can be useful for future reference.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Addendum:

It's likely that some standard graphics subsystem would offer such hidden line/object removal for 3-D graphics implemented in a very efficient way. I really don't know if it's available, commonly installed, easy to use but perhaps users proficient with graphics subsystems can comment on this. Even if that sounds a bit like "killing a fly with a nuke" in the case at hand, it can be useful for future reference.

Without having tried, could you simply test if the line defining a wall intersects with the red line?

If the red line is

x = Ay + K

and a wall is

x = By + L

then at the intersection

y = (K-L)/(B-A)

and if that is beyond the wall ends (or B = A) then no collision. Then try the next wall etc.

EDIT: In the L-shaped example you gave then if it doesn't intersect with one wall then it doesn't intersect with the other of course, so you only need to test one wall.

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Without having tried, could you simply test if the line defining a wall intersects with the red line?

Correct, but I don't see how this is "simpler" than computing and comparing only the Sin (or Cos) of the point-to-point and point-to-wall-corner angles. Going affine in this case doesn't gives us more information (at least for the OP problem) and needs slightly more computations.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Correct, but I don't see how this is "simpler" than computing and comparing only the Sin (or Cos) of the point-to-point and point-to-wall-corner angles. Going affine in this case doesn't gives us more information (at least for the OP problem) and needs slightly more computations.

I don't know but at the moment I am unconvinced that calculating the wall angles is simpler. Maybe you can give an example calculataion which shows me?

EDIT:

I've thought about it and I agree that angles could be simpler, though I would use Tangents.

Assuming the L_shaped room.

The corner of the wall is at coordinate A,B

The higher person is at C,D

The lower person is at G,F

If (D-E)/(C-E) < (D-G)/(C-A) then $Visible = True.

Does that look right?

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

I don't know but at the moment I am unconvinced that calculating the wall angles is simpler. Maybe you can give an example calculataion which shows me?

EDIT:

I've thought about it and I agree that angles could be simpler, though I would use Tangents.

Tangent means calculating both sides, which we don't need. Give me 1 hour, finish diner, clean everything, put kids to bed and I'll be back with a bit of code and, if I find the path to a graphic program that may be hidden somewhere, draw a schema.

In the meantime, maybe a winged user :ahem: could take the first relay... He must still know his trig and log tables by heart!

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

  • Moderators

jchd,

Stop trying to drag me into this - you threw down the gauntlet and martin picked it up! :

martin,

To explain - we both came up with the same solution - only he typed faster, thank goodness! :huggles:

M23

P.S. Happy to act as an impartial judge in this duel if both parties agree..... :D

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

jchd,

Stop trying to drag me into this - you threw down the gauntlet and martin picked it up! :D

martin,

To explain - we both came up with the same solution - only he typed faster, thank goodness! :huggles:

M23

P.S. Happy to act as an impartial judge in this duel if both parties agree..... :D

? is "he" me or him?

Well I didn't see it as a duel, just a discussion; I am interested to see the simplest and faster method. At the moment I can't see how you can get simpler or faster than

If (D-E)/(C-E) < (D-G)/(C-A) then $Visible = True

but I am happy to be shown.

If tangents require knowing 2 sides but Sins and Cos's don't then I have forgotten more than I realised :

BTW if the note about log tables was a dig about M23's age then please look the other way while I hide my slide rule.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Stop trying to drag me into this - you threw down the gauntlet and martin picked it up! :

Just like flattery, cowardise will take you everywhere!:huggles:

I simply hoped you would draw something. I just have paint on this business machine and it simply has an extra T at the end.

P.S. Happy to act as an impartial judge in this duel if both parties agree..... :D

Hence no duel, no engagement, no risk. You seem to have a comfortable life! Keep your appointments low in view of this.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

  • Moderators

martin,

"he" was jchd.

I know it is not a duel, but it seemed like a fun idea - and I am genuinely interested in which method is the faster. :D

I do still have my slide rules - when I did my Aeronautical Engineering finals in 19## we were specifically forbidden to use calulators as they were considered too expensive for the average student. We had 2 of the first batch of HP35s in the department - anchored to very large concrete blocks - and they were gifts from either Hewlett or Packard (whichever had been an old student). I can remember solving my sextic (sp? sixth order differential) stability equations on them when it would have taken days on the Fortran mainframe we had. Do you remember the Reverse Polish Notation that HP used to use? Nearly as bad as SREs! :huggles:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Whats the G :D

And why do I get the funny feeling this is not completely reliable? Probably my code though.

#include <GDIPlus.au3>
_GDIPlus_Startup()
OnAutoItExitRegister("_ClearGdip")

HotKeySet("{ENTER}", "_DrawRoom")

Global $hGUI = GUICreate("Testing window", 600, 600)
Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)

Global $hPen = _GDIPlus_PenCreate(0xFFFFFFFF, 100)

Global $aPeople[3][2] = [[2, _GDIPlus_PenCreate(0xFF00FF00, 30)], [0, 0], [0, 0]]

GUISetState()

While 1
    Switch GUIGetMsg()
        Case -3
            Exit
    EndSwitch
WEnd

Func _DrawRoom()
    _GDIPlus_GraphicsClear($hGraphic)
    _GDIPlus_GraphicsDrawLine($hGraphic, 100, 100, 100, 500, $hPen)
    _GDIPlus_GraphicsDrawLine($hGraphic, 100, 150, 500, 150, $hPen)
    $aPeople[1][0] = Random(70, 130, 1)
    $aPeople[1][1] = Random(70, 480, 1)

    $aPeople[2][0] = Random(70, 480, 1)
    $aPeople[2][1] = Random(70, 130, 1)

    _GDIPlus_GraphicsDrawArc($hGraphic, $aPeople[1][0], $aPeople[1][1], 10, 10, 0, 360, $aPeople[0][1])
    _GDIPlus_GraphicsDrawArc($hGraphic, $aPeople[2][0], $aPeople[2][1], 10, 10, 0, 360, $aPeople[0][1])

    $hTimer = TimerInit()
    ConsoleWrite("Martins: " & _Martins() & " :: Time: " & TimerDiff($hTimer) & @CRLF)
EndFunc

Func _Martins()
    Local $A = 150
    Local $B = 150
    Local $C = $aPeople[1][0]
    Local $D = $aPeople[1][1]
    Local $E = $aPeople[2][0]
    Local $F = $aPeople[2][1]

    If ($D-$E)/($C-$E) < ($D-$E)/($C-$A) then Return True
    Return False
EndFunc

Func _ClearGdip()
    _GDIPlus_Shutdown()
EndFunc
Link to comment
Share on other sites

I do still have my slide rules - when I did my Aeronautical Engineering finals in 19## we were specifically forbidden to use calulators as they were considered too expensive for the average student. We had 2 of the first batch of HP35s in the department - anchored to very large concrete blocks - and they were gifts from either Hewlett or Packard (whichever had been an old student). I can remember solving my sextic (sp? sixth order differential) stability equations on them when it would have taken days on the Fortran mainframe we had. Do you remember the Reverse Polish Notation that HP used to use? Nearly as bad as SREs! :D

Stop diverting me in this non-duel, and trying to draw tears from my eyes about the good old time. AFAIK HP still uses RPN and does its best trying to resurrect the notation:

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

And why do I get the funny feeling this is not completely reliable? Probably my code though.

If ($D-$E)/($C-$E) < ($D-$E)/($C-$A) then Return True

Mat, you're mixing X and Y coordinates here.

Also, there is no invokation of your functions.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Whats the G :D

And why do I get the funny feeling this is not completely reliable? Probably my code though.

#include <GDIPlus.au3>
_GDIPlus_Startup()
OnAutoItExitRegister("_ClearGdip")

HotKeySet("{ENTER}", "_DrawRoom")

Global $hGUI = GUICreate("Testing window", 600, 600)
Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)

Global $hPen = _GDIPlus_PenCreate(0xFFFFFFFF, 100)

Global $aPeople[3][2] = [[2, _GDIPlus_PenCreate(0xFF00FF00, 30)], [0, 0], [0, 0]]

GUISetState()

While 1
    Switch GUIGetMsg()
        Case -3
            Exit
    EndSwitch
WEnd

Func _DrawRoom()
    _GDIPlus_GraphicsClear($hGraphic)
    _GDIPlus_GraphicsDrawLine($hGraphic, 100, 100, 100, 500, $hPen)
    _GDIPlus_GraphicsDrawLine($hGraphic, 100, 150, 500, 150, $hPen)
    $aPeople[1][0] = Random(70, 130, 1)
    $aPeople[1][1] = Random(70, 480, 1)

    $aPeople[2][0] = Random(70, 480, 1)
    $aPeople[2][1] = Random(70, 130, 1)

    _GDIPlus_GraphicsDrawArc($hGraphic, $aPeople[1][0], $aPeople[1][1], 10, 10, 0, 360, $aPeople[0][1])
    _GDIPlus_GraphicsDrawArc($hGraphic, $aPeople[2][0], $aPeople[2][1], 10, 10, 0, 360, $aPeople[0][1])

    $hTimer = TimerInit()
    ConsoleWrite("Martins: " & _Martins() & " :: Time: " & TimerDiff($hTimer) & @CRLF)
EndFunc

Func _Martins()
    Local $A = 150
    Local $B = 150
    Local $C = $aPeople[1][0]
    Local $D = $aPeople[1][1]
    Local $E = $aPeople[2][0]
    Local $F = $aPeople[2][1]

    If ($D-$E)/($C-$E) < ($D-$E)/($C-$A) then Return True
    Return False
EndFunc

Func _ClearGdip()
    _GDIPlus_Shutdown()
EndFunc

This is a mod to the above which seems to work.

#include <GDIPlus.au3>
_GDIPlus_Startup()
OnAutoItExitRegister("_ClearGdip")

HotKeySet("{ENTER}", "_DrawRoom")

Global $hGUI = GUICreate("Testing window", 600, 600)
Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)

Global $hPen = _GDIPlus_PenCreate(0xFFFFFFFF, 100)

Global $aPeople[3][2] = [[2, _GDIPlus_PenCreate(0xFF00FF00, 30)],[0, 0],[0, 0]]

GUISetState()

While 1
    Switch GUIGetMsg()
    Case - 3
    Exit
    EndSwitch
WEnd

Func _DrawRoom()
    _GDIPlus_GraphicsClear($hGraphic)
    _GDIPlus_GraphicsDrawLine($hGraphic, 100, 100, 100, 500, $hPen)
    _GDIPlus_GraphicsDrawLine($hGraphic, 100, 150, 500, 150, $hPen)
    $aPeople[1][0] = Random(70, 130, 1)
    $aPeople[1][1] = Random(70, 480, 1)

    $aPeople[2][0] = Random(70, 480, 1)
    $aPeople[2][1] = Random(70, 130, 1)

    _GDIPlus_GraphicsDrawArc($hGraphic, $aPeople[1][0], $aPeople[1][1], 10, 10, 0, 360, $aPeople[0][1])
    _GDIPlus_GraphicsDrawArc($hGraphic, $aPeople[2][0], $aPeople[2][1], 10, 10, 0, 360, $aPeople[0][1])

    $hTimer = TimerInit()
    ConsoleWrite("Martins: " & _Martins() & " :: Time: " & TimerDiff($hTimer) & @CRLF)
EndFunc ;==>_DrawRoom

Func _Martins()
    Local $A = 150
    Local $B = 200;this was 150 which is incorrect
    Local $C = $aPeople[1][0]
    Local $D = $aPeople[1][1]
    Local $E = $aPeople[2][0]
    Local $F = $aPeople[2][1]

    If $C < $A and $E < $a then return True
    If $D < $B and $F < $B then return True
    if $D = $F then return True
    if $C = $E then return true

    ConsoleWrite($C & ', ' & $D & ', ' & $E & ', ' & $F & @CRLF)
    ;Wall = Y = 150
    ;line between people is X = mY + K
    ;m = (D-E)/(E-C)
    Local $m, $k, $x
    $m = ($C - $E)/($D - $F)
    $k = $C - $m * $D;from x = $m*y + $k using the fact that the line passes through $C,$d
    ;The lines intersect where Y = 150 so
    $x = $m * 150 + $k

    ;if this point is to the left of the corner then visible
    Return $x < 150


EndFunc ;==>_Martins, well it is now

Func _ClearGdip()
    _GDIPlus_Shutdown()
EndFunc ;==>_ClearGdip
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

This is a mod to the above which seems to work.

Indeed. You're right, doing with the slope is simpler.

OTOH, computing with cartesian as below isn't bad either. I made the thing console only, but finally tried to make use of Mat's graphic example.

I confess being a quiche on graphics and the different handedless (differing origin) forced me into near ugly code. I had the points as an array, which I kept. If you abstract the indirections I used, both central computation have probably comparable timing, offering a choice for implementation.

@Mat: sorry for earlier dumb remark about no function called: I didn't spot the HotKeySet...

;;***********************************************
;; needs patch to Array.au3 as per ticket #1438
;;***********************************************

;; assuming a simple "L-shape" configuration
;; lower left corner is at (0, 0)
;; X is horizontal, Y is vertical
;; wall is lower right corner as in OP's post schema

;; for GDI graphics, the origin is of course upper left

Global $ConsoleOutput = False       ; change to True for console output as well


#include <Array.au3>

;; Playground
Global Const $Xsize = 800
Global Const $Ysize = 600

Global Const $Crowd = 25    ; max number of points ("people")

Global $WallEnd[2] = [$Xsize - 1, 0]    ; an unreachable point "far enough" "inside" the wall

#include <GDIPlus.au3>
_GDIPlus_Startup()
OnAutoItExitRegister("_ClearGdip")

Global $hGUI = GUICreate("Mutual visibility Testing window", $Xsize, $Ysize)
Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)

Global $hPenW = _GDIPlus_PenCreate(0xFFFFFFFF, 10)
Global $hPenR = _GDIPlus_PenCreate(0xFFFF0000, 1)
Global $hPenG = _GDIPlus_PenCreate(0xFF00FF00, 2)
Global $hPenB = _GDIPlus_PenCreate(0xFF0000FF, 2)
Global $hBrush1 = _GDIPlus_BrushCreateSolid()
_GDIPlus_BrushSetSolidColor($hBrush1, 0xFF7F7F7F)

GUISetState()

_DrawRoom()     ; first run

HotKeySet("{ENTER}", "_DrawRoom")

While 1
    Switch GUIGetMsg()
    Case - 3
    Exit
    EndSwitch
WEnd


Func _DrawRoom()
    _GDIPlus_GraphicsClear($hGraphic)

    ;; place wall corner
    Local $WallCorner = PlaceWall()
    If $ConsoleOutput Then ConsoleWrite('Wall corner was placed at (' & $WallCorner[0] & ',' & $WallCorner[1] & ')' & @LF)
    _GDIPlus_GraphicsFillRect($hGraphic, $WallCorner[0], $Ysize - $WallCorner[1], $Xsize - $WallCorner[0], $WallCorner[1], $hBrush1)
    _GDIPlus_GraphicsDrawArc($hGraphic, $WallCorner[0] + 1, $Ysize - $WallCorner[1] + 1, 2, 2, 0, 360, $hPenB)

    ;; init and place "people"
    Local $nbPoints = Random(2, $Crowd, 1)
    Local $Points[$nbPoints][3]     ; x, y, quadrant
    For $i = 0 To $nbPoints - 1
        Do
            $xy = PlacePoint()
        Until ($xy[0] < $WallCorner[0]) Or ($xy[1] > $WallCorner[1])
        $Points[$i][0] = $xy[0]
        $Points[$i][1] = $xy[1]
        Select
            Case ($xy[0] < $WallCorner[0]) And ($xy[1] < $WallCorner[1])
                $Points[$i][2] = 1      ; South-West quadrant (numbering is arbitrary)
            Case ($xy[0] > $WallCorner[0]) And ($xy[1] > $WallCorner[1])
                $Points[$i][2] = 2      ; North-East quadrant
            Case Else
                $Points[$i][2] = 0      ; North-West quadrant (includes Wall corner boundaries)
        EndSelect
        _GDIPlus_GraphicsDrawArc($hGraphic, $Points[$i][0] - 1, $Ysize - $Points[$i][1] - 1, 2, 2, 0, 360, $hPenG)
    Next

    ;; compute and show visibility
    Local $list[$nbPoints]
    For $i = 0 to $nbPoints - 1
        $list[$i] = $i
    Next
    Local $couples = _ArrayCombinations($list, 2, ",")      ;; needs patch to Array.au3 as per ticket #1438
    Local $candidates, $result, $neg[2] = ["'t", ""], $visible, $p0, $p1, $deltaX, $deltaY

    For $i = 1 To $couples[0]
        $candidates = StringRegExp($couples[$i], "(\d+),(\d+)", 1)
        $p0 = Number($candidates[0])
        $p1 = Number($candidates[1])
        If ($Points[$p0][2] = $Points[$p1][2]) Or _             ; points in the same quadrants see each other
            ($Points[$p0][2] = 0) Or ($Points[$p1][2] = 0) Then     ; points in quadrant 0 see everyone
            $visible = True
        Else
            ;; points "see" each other if the wall corner and wall end are the same side of the line joining the two points
            ;; translate into the two equations below have the same sign
            ;; since we have no practical Sign() operator, we multiply them and look at the resulting sign.
            $deltaX = $Points[$p1][0] - $Points[$p0][0]
            $deltaY = $Points[$p1][1] - $Points[$p0][1]
            $visible = (    (   ($deltaX * ($WallCorner[1] - $Points[$p0][1]) - $deltaY * ($WallCorner[0] - $Points[$p0][0])) * _
                                ($deltaX * ($WallEnd[1] - $Points[$p0][1]) - $deltaY * ($WallEnd[0] - $Points[$p0][0])) _
                            ) > 0 _
                        )
        EndIf
        If $visible Then
            _GDIPlus_GraphicsDrawLine($hGraphic, $Points[$p0][0], $Ysize - $Points[$p0][1], $Points[$p1][0], $Ysize - $Points[$p1][1], $hPenR)
        EndIf
        $result = StringFormat("Point %i at (%i,%i) can%s see point %i at (%i,%i)", _
                                     $p0, _
                                             $Points[$p0][0], _
                                                $Points[$p0][1], _
                                                     $neg[$visible], _
                                                                    $p1, _
                                                                         $Points[$p1][0], _
                                                                             $Points[$p1][1] _
                             )
        If $ConsoleOutput Then ConsoleWrite($result & @LF)
    Next
    ; redraw the green points (are often heavily drawn over by junction lines)
    For $i = 0 To $nbPoints - 1
        _GDIPlus_GraphicsDrawArc($hGraphic, $Points[$i][0] - 1, $Ysize - $Points[$i][1] - 1, 2, 2, 0, 360, $hPenG)
    Next
EndFunc

Func PlaceWall()
    Return(PlacePoint(Round($Xsize / 4), Round(($Xsize - 1) / 2), Round($Ysize / 2), Round(($Ysize - 1) * 3 / 4)))
EndFunc


Func PlacePoint($x_min = 0, $x_max = Default, $y_min = 0, $y_max = Default)
    If IsKeyword($x_max) Then $x_max = $Xsize - 1
    If IsKeyword($y_max) Then $y_max = $Ysize - 1
    Local $a[2] = [ _
        Random($x_min, $x_max, 1), _
        Random($y_min, $y_max, 1) _
    ]
    Return($a)
EndFunc

Sidenote: I've noticed that sometimes the display is all grey but I didn't succeed in finding why. This happens with both examples. After a second thought, it may be due to a periodic task I have running all the time, which could interfere with the graphics display (not redrawn automatically). Yes, that's most probably the reason.

If you feel that this post stinks, that's normal as I've been repairing something with the central heating and you know that whatever caution you deploy you always end up smelling the marvelous fragrance of gasoline anyway. @^~$¤%!

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...