Jump to content

Trigonometry and AutoIt


Fentus
 Share

Recommended Posts

I have a fun little Trigonometry question that I need help with, I have asked several people even ones that teach math and study programming (No luck yet, and I am only in Math 085 as of now and could use a little help figuring this out).

If I was given 3 points A (x1, y1), B (x2, y2), & C (x3, y3) the sides of a triangle how could I use them to find a random number in that said triangle.

Lets also assume the function starts like this.

Func RandPointTriangle($x1, $y1, $x2, $y2, $x3, $y3)


EndFunc

The points need to be uniform!

This might help:

http://cgafaq.info/wiki/Random_Point_In_Triangle

http://hbfs.wordpress.com/2010/10/05/ran...triangle-generating-random-seq

Very good at programming but, bad at math, bad at reading, bad at writing.

Link to comment
Share on other sites

A little bit of spoonfeeding but here you go :)

;$CoordArray[6] = [x1,y1,x2,y2,x3,y3]
Dim $CoordArray[6] = [1,1,2,3,4,2]
MsgBox(0, "", RandPointTriangle($CoordArray))
Func RandPointTriangle($cArray)
 Local $el_1 = Random(0, 1)
 Local $el_2 = Random(0, 1-$el_1)
 Local $el_3 = 1-$el_1-$el_2
 Local $rndPoint_X = $el_1*$cArray[0] + $el_2*$cArray[2] + $el_3*$cArray[4]
 Local $rndPoint_Y = $el_1*$cArray[1] + $el_2*$cArray[3] + $el_3*$cArray[5]
 Local $result = "("&Round($rndPoint_X, 2)&","&Round($rndPoint_Y, 2)&")"
 Return $result
EndFunc

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

A little bit of spoonfeeding but here you go :)

;$CoordArray[6] = [x1,y1,x2,y2,x3,y3]
Dim $CoordArray[6] = [1,1,2,3,4,2]
MsgBox(0, "", RandPointTriangle($CoordArray))
Func RandPointTriangle($cArray)
Local $el_1 = Random(0, 1)
Local $el_2 = Random(0, 1-$el_1)
Local $el_3 = 1-$el_1-$el_2
Local $rndPoint_X = $el_1*$cArray[0] + $el_2*$cArray[2] + $el_3*$cArray[4]
Local $rndPoint_Y = $el_1*$cArray[1] + $el_2*$cArray[3] + $el_3*$cArray[5]
Local $result = "("&Round($rndPoint_X, 2)&","&Round($rndPoint_Y, 2)&")"
Return $result
EndFunc

You are a god sir, I will be testing this out very shortly. I will post my results. Edited by Fentus

Very good at programming but, bad at math, bad at reading, bad at writing.

Link to comment
Share on other sites

A little bit of spoonfeeding but here you go :)

;$CoordArray[6] = [x1,y1,x2,y2,x3,y3]
Dim $CoordArray[6] = [1,1,2,3,4,2]
MsgBox(0, "", RandPointTriangle($CoordArray))
Func RandPointTriangle($cArray)
Local $el_1 = Random(0, 1)
Local $el_2 = Random(0, 1-$el_1)
Local $el_3 = 1-$el_1-$el_2
Local $rndPoint_X = $el_1*$cArray[0] + $el_2*$cArray[2] + $el_3*$cArray[4]
Local $rndPoint_Y = $el_1*$cArray[1] + $el_2*$cArray[3] + $el_3*$cArray[5]
Local $result = "("&Round($rndPoint_X, 2)&","&Round($rndPoint_Y, 2)&")"
Return $result
EndFunc

Results #1:

Posted Image

Results #2:

Posted Image

100% appreciate the help, but this is what was happening to this guy also (read link and look at my pic compared to his, it still seems to be clustering on point C):

http://hbfs.wordpress.com/2010/10/05/ran...triangle-generating-random-seq

Edited by Fentus

Very good at programming but, bad at math, bad at reading, bad at writing.

Link to comment
Share on other sites

Couldn't you just get randon x values from x min to x max, and random y values from ymin to ymax and reject any points which are outside the triangle? You can use functions by Malkey to determine if a point is inside a shape. That way there should be no clustering.

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

Couldn't you just get randon x values from x min to x max, and random y values from ymin to ymax and reject any points which are outside the triangle? You can use functions by Malkey to determine if a point is inside a shape. That way there should be no clustering.

Problem with that is this, read above the 2nd pic (way to many false calculations):

http://hbfs.wordpress.com/2010/10/05/random-points-in-a-triangle-generating-random-sequences-ii/

Very good at programming but, bad at math, bad at reading, bad at writing.

Link to comment
Share on other sites

I still don't know what do you want to use this for?

Are you trying to "fill" the triangle? Are you trying to get all of the points inside?

I guess the code works very well and it does return a point inside the triangle. Why it returns more results around a certain point? I guess it is because of the Random function used which is not absolutely "random".

I still don't understand what are these 3 images of - which one is yours?

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

I still don't know what do you want to use this for?

Are you trying to "fill" the triangle? Are you trying to get all of the points inside?

I guess the code works very well and it does return a point inside the triangle. Why it returns more results around a certain point? I guess it is because of the Random function used which is not absolutely "random".

I still don't understand what are these 3 images of - which one is yours?

http://cgafaq.info/wiki/Random_Point_In_Triangle

http://hbfs.wordpress.com/2010/10/05/ran...triangle-generating-random-seq

Are you trying to "fill" the triangle?

No, I need to do a specific operation on a random point in a given triangle (Must be uniform random).

Are you trying to get all of the points inside?

No, I only need 1 point at random, then another then another and so on.

I guess the code works very well and it does return a point inside the triangle. Why it returns more results around a certain point?

This describes the problem of Random quite well: http://mathworld.wolfram.com/TrianglePointPicking.html

I guess it is because of the Random function used which is not absolutely "random".

Sorta, you will understand if you read the link above.

I still don't understand what are these 3 images of - which one is yours?

All of them are mine, look at my links to the other sites explaining what I need. Edited by Fentus

Very good at programming but, bad at math, bad at reading, bad at writing.

Link to comment
Share on other sites

Fentus, try this example:

#include <GUIConstantsEx.au3>

GUICreate("Test", 400, 400)
Local $Graphic1 = GUICtrlCreateGraphic(5, 5, 390, 390)
Local $aTriangle[3][2]=[[10,10], [10,200], [200,10]]
GUICtrlSetGraphic(-1, $GUI_GR_MOVE, $aTriangle[0][0], $aTriangle[0][1])
GUICtrlSetGraphic(-1, $GUI_GR_LINE, $aTriangle[1][0], $aTriangle[1][1])

GUICtrlSetGraphic(-1, $GUI_GR_MOVE, $aTriangle[1][0], $aTriangle[1][1])
GUICtrlSetGraphic(-1, $GUI_GR_LINE, $aTriangle[2][0], $aTriangle[2][1])

GUICtrlSetGraphic(-1, $GUI_GR_MOVE, $aTriangle[2][0], $aTriangle[2][1])
GUICtrlSetGraphic(-1, $GUI_GR_LINE, $aTriangle[0][0], $aTriangle[0][1])
GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x000000, 0xFF0000)

Local $iXr, $iYr, $r1, $r2

For $i=1 To 600
$r1 = Random(0,1)
$r2 = Random(0,1)
$iXr = (1 - sqrt($r1)) * $aTriangle[0][0] + ((1 - $r2)*sqrt($r1)) * $aTriangle[1][0] + ($r2*sqrt($r1)) * $aTriangle[2][0]
$iYr = (1 - sqrt($r1)) * $aTriangle[0][1] + ((1 - $r2)*sqrt($r1)) * $aTriangle[1][1] + ($r2*sqrt($r1)) * $aTriangle[2][1]
ConsoleWrite($iXr & ", " & $iYr & @CRLF)
GUICtrlSetGraphic($Graphic1, $GUI_GR_DOT, Round($iXr), Round($iYr))
Next

GUISetState(@SW_SHOW)

While 1
Sleep(10)
Switch GUIGetMsg()
Case -3
Exit
EndSwitch
WEnd
Link to comment
Share on other sites

Fentus, try this example:

#include <GUIConstantsEx.au3>

GUICreate("Test", 400, 400)
Local $Graphic1 = GUICtrlCreateGraphic(5, 5, 390, 390)
Local $aTriangle[3][2]=[[10,10], [10,200], [200,10]]
GUICtrlSetGraphic(-1, $GUI_GR_MOVE, $aTriangle[0][0], $aTriangle[0][1])
GUICtrlSetGraphic(-1, $GUI_GR_LINE, $aTriangle[1][0], $aTriangle[1][1])

GUICtrlSetGraphic(-1, $GUI_GR_MOVE, $aTriangle[1][0], $aTriangle[1][1])
GUICtrlSetGraphic(-1, $GUI_GR_LINE, $aTriangle[2][0], $aTriangle[2][1])

GUICtrlSetGraphic(-1, $GUI_GR_MOVE, $aTriangle[2][0], $aTriangle[2][1])
GUICtrlSetGraphic(-1, $GUI_GR_LINE, $aTriangle[0][0], $aTriangle[0][1])
GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x000000, 0xFF0000)

Local $iXr, $iYr, $r1, $r2

For $i=1 To 600
$r1 = Random(0,1)
$r2 = Random(0,1)
$iXr = (1 - sqrt($r1)) * $aTriangle[0][0] + ((1 - $r2)*sqrt($r1)) * $aTriangle[1][0] + ($r2*sqrt($r1)) * $aTriangle[2][0]
$iYr = (1 - sqrt($r1)) * $aTriangle[0][1] + ((1 - $r2)*sqrt($r1)) * $aTriangle[1][1] + ($r2*sqrt($r1)) * $aTriangle[2][1]
ConsoleWrite($iXr & ", " & $iYr & @CRLF)
GUICtrlSetGraphic($Graphic1, $GUI_GR_DOT, Round($iXr), Round($iYr))
Next

GUISetState(@SW_SHOW)

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

The only problem with this is I can't follow it to easily (Hard to understand others programming sometimes) can you put it in the form of a function like "enaiman" did? This way I can follow the input to the result and learn a bit form it. (But it dose look very promising.) Also this will help me put it into my program and see what I come up with.

Example:

Dim $CoordArray[6] = [930,443,192,213,343,458]

$Array_r = RandPointTriangle($CoordArray)

Func RandPointTriangle($cArray)
   Local $el_1 = Random(0, 1)
   Local $el_2 = Random(0, 1-$el_1)
   Local $el_3 = 1-$el_1-$el_2
   Local $rndPoint_X = $el_1*$cArray[0] + $el_2*$cArray[2] + $el_3*$cArray[4]
   Local $rndPoint_Y = $el_1*$cArray[1] + $el_2*$cArray[3] + $el_3*$cArray[5]

   ;Local $result = "("&Round($rndPoint_X, 2)&","&Round($rndPoint_Y, 2)&")"
   Dim $Array_r[2] = [Round($rndPoint_X, 2), Round($rndPoint_Y, 2)]

   Return $Array_r
EndFunc
Edited by Fentus

Very good at programming but, bad at math, bad at reading, bad at writing.

Link to comment
Share on other sites

Fentus, here is the example modified:

#include <GUIConstantsEx.au3>

GUICreate("Test", 400, 400)
Local $Graphic1 = GUICtrlCreateGraphic(5, 5, 390, 390)
Local $aTriangle[3][2]=[[10,10], [10,200], [200,10]]
GUICtrlSetGraphic(-1, $GUI_GR_MOVE, $aTriangle[0][0], $aTriangle[0][1])
GUICtrlSetGraphic(-1, $GUI_GR_LINE, $aTriangle[1][0], $aTriangle[1][1])

GUICtrlSetGraphic(-1, $GUI_GR_MOVE, $aTriangle[1][0], $aTriangle[1][1])
GUICtrlSetGraphic(-1, $GUI_GR_LINE, $aTriangle[2][0], $aTriangle[2][1])

GUICtrlSetGraphic(-1, $GUI_GR_MOVE, $aTriangle[2][0], $aTriangle[2][1])
GUICtrlSetGraphic(-1, $GUI_GR_LINE, $aTriangle[0][0], $aTriangle[0][1])
GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x000000, 0xFF0000)

For $i=1 To 500
Local $aP = _RandomPoint($aTriangle)
ConsoleWrite($aP[0][0] & ", " & $aP[0][1] & @CRLF)
GUICtrlSetGraphic($Graphic1, $GUI_GR_DOT, Round($aP[0][0]), Round($aP[0][1]))
Next

GUISetState(@SW_SHOW)

While 1
Sleep(10)
Switch GUIGetMsg()
Case -3
Exit
EndSwitch
WEnd
Func _RandomPoint($aArray)
If UBound($aArray)<>3 And UBound($aArray,2)<>2 Then MsgBox(0,"Error!", "The array doesn't represent a triangle!...")
Local $r1, $r2, $aPoint[1][2]
$r1 = Random(0,1)
$r2 = Random(0,1)
$aPoint[0][0] = Round((1 - sqrt($r1)) * $aArray[0][0] + ((1 - $r2)*sqrt($r1)) * $aArray[1][0] + ($r2*sqrt($r1)) * $aArray[2][0],2)
$aPoint[0][1] = Round((1 - sqrt($r1)) * $aArray[0][1] + ((1 - $r2)*sqrt($r1)) * $aArray[1][1] + ($r2*sqrt($r1)) * $aArray[2][1],2)
Return $aPoint
EndFunc
Link to comment
Share on other sites

Works!

Local $aTriangle[3][2]=[[930,443], [192,213], [343,458]]

$aP = RandPointTriangle($aTriangle)

MsgBox(1, "", "(" & $aP[0][0] & ", " & $aP[0][1] & ")")

Func RandPointTriangle($aArray)
   If UBound($aArray)<>3 And UBound($aArray,2)<>2 Then MsgBox(0,"Error!", "The array doesn't represent a triangle!...")
   Local $r1, $r2, $aPoint[1][2]
   $r1 = Random(0,1)
   $r2 = Random(0,1)
   $aPoint[0][0] = Round((1 - sqrt($r1)) * $aArray[0][0] + ((1 - $r2)*sqrt($r1)) * $aArray[1][0] + ($r2*sqrt($r1)) * $aArray[2][0],2)
   $aPoint[0][1] = Round((1 - sqrt($r1)) * $aArray[0][1] + ((1 - $r2)*sqrt($r1)) * $aArray[1][1] + ($r2*sqrt($r1)) * $aArray[2][1],2)
   Return $aPoint
EndFunc

Result:

Posted Image

Very good at programming but, bad at math, bad at reading, bad at writing.

Link to comment
Share on other sites

Problem with that is this, read above the 2nd pic (way to many false calculations):

http://hbfs.wordpress.com/2010/10/05/ran...triangle-generating-random-seq

A bit late now since a better solution has been worked out, but the number of false calulations would only be half on average. You simply need to rotate the triangle until one side is vertical or horizontal and then the enclosing rectangle is only twice the area. Of course all the valid results have to be translated back again but roatating points about a point is simple.

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

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...