Lwpolyline click

Lwpolyline click

Anonymous
Not applicable
751 Views
16 Replies
Message 1 of 17

Lwpolyline click

Anonymous
Not applicable
Hello,

I have a lwpolyline, i want the user click this pline, no problem
This pline have only linear segments
I want to know between which vertices, or on which segment the user has
clicked

Thank you for the help

Bernard
ATC
45700 Villemandeur
France
0 Likes
752 Views
16 Replies
Replies (16)
Message 2 of 17

Anonymous
Not applicable
ehmm...
1. use GetEntity; you get the lwpline and a point
2. Run trough all coordinates from the lwpline. Don't forget last-first if
the pline is closed
3. Determine if Point is on the segment between two vertices, that is if the
distance between the two vertices is (almost) equal to the distance between
the point and the first vertex plus the distance between between the second
vertex and the point. I have to warn you; this might require some Pythagoras
tricks.
4. There you have it.

wkr, jwk

Bernard Flavignard had the next bright idea:

>Hello,
>
>I have a lwpolyline, i want the user click this pline, no problem
>This pline have only linear segments
>I want to know between which vertices, or on which segment the user has
>clicked
>
>Thank you for the help
>
>Bernard
>ATC
>45700 Villemandeur
>France
>
>

--
You ask a silly question, you get a technical answer...
0 Likes
Message 3 of 17

Anonymous
Not applicable
I couldn't agree more. And to make things a little easier, check out the
collinear function on this page of vbDesign 🙂 You can use something to the
effect of :

for i = lbound(coords) to ubound(coords) step 3
if collinear(coords(i+1), coords(i+2),userpick) then
'set a variable or do something 🙂
exit for
end if
next i

where coords is an array equal to the coordinates property of the pline.
-Josh

Bernard Flavignard wrote:

> Hello,
>
> I have a lwpolyline, i want the user click this pline, no problem
> This pline have only linear segments
> I want to know between which vertices, or on which segment the user has
> clicked
>
> Thank you for the help
>
> Bernard
> ATC
> 45700 Villemandeur
> France
0 Likes
Message 4 of 17

Anonymous
Not applicable
Oops, that should have been coords(i) and coords(i+1).

Minkwitz Design wrote:

> I couldn't agree more. And to make things a little easier, check out the
> collinear function on this page of vbDesign 🙂 You can use something to the
> effect of :
>
> for i = lbound(coords) to ubound(coords) step 3
> if collinear(coords(i+1), coords(i+2),userpick) then
> 'set a variable or do something 🙂
> exit for
> end if
> next i
>
> where coords is an array equal to the coordinates property of the pline.
> -Josh
0 Likes
Message 5 of 17

Anonymous
Not applicable
Oops, that should have been coords(i) and coords(i+1). And here's the link:
http://vbdesign.hypermart.net/cadpages/joshwest.htm

Minkwitz Design wrote:

> I couldn't agree more. And to make things a little easier, check out the
> collinear function on this page of vbDesign 🙂 You can use something to the
> effect of :
>
> for i = lbound(coords) to ubound(coords) step 3
> if collinear(coords(i+1), coords(i+2),userpick) then
> 'set a variable or do something 🙂
> exit for
> end if
> next i
>
> where coords is an array equal to the coordinates property of the pline.
> -Josh
>
> Bernard Flavignard wrote:
>
> > Hello,
> >
> > I have a lwpolyline, i want the user click this pline, no problem
> > This pline have only linear segments
> > I want to know between which vertices, or on which segment the user has
> > clicked
> >
> > Thank you for the help
> >
> > Bernard
> > ATC
> > 45700 Villemandeur
> > France
0 Likes
Message 6 of 17

Anonymous
Not applicable
Am I misreading that code? It looks like the function only works with straight
segments. What happens if the user selects an arc segment on a polyline?

--
http://www.acadx.com
Win a free autographed copy of
"AutoCAD 2000 VBA Programmer's Reference"

"Minkwitz Design" wrote in message
news:3ABF58A2.4B9B2C49@minkwitz-design.com...
> I couldn't agree more.
0 Likes
Message 7 of 17

Anonymous
Not applicable
Hi Frank,
Nope your not misreading the code. I'm going by what Bernard posted.

"This pline have only linear segments"

If he selects an arc segement, it won't register. That would be a little trickier
:)
-Josh

Frank Oquendo wrote:

> Am I misreading that code? It looks like the function only works with straight
> segments. What happens if the user selects an arc segment on a polyline?
>
> --
> http://www.acadx.com
> Win a free autographed copy of
> "AutoCAD 2000 VBA Programmer's Reference"
>
> "Minkwitz Design" wrote in message
> news:3ABF58A2.4B9B2C49@minkwitz-design.com...
> > I couldn't agree more.
>
0 Likes
Message 8 of 17

Anonymous
Not applicable
I looked into the code, and it seems at a first glance it's working with
lines and their length properties. Let me make a few remarks (ah, please?)

first, i'm working at this moment on some code that checks if lwplines are
next to each other, touching each other, holding.... but i digress.
At first, it worked with lines. It took 12 minutes to process. Then i changed
the code so it didn't work with lines but only with coordinates. This brought
the process time back to 2 minutes.
After that, i first put every reference to a property (coordinates,
Elevation, Thickness) into variables, and only worked with the variables.
This brought the process time back to... 10 seconds.

Am i a bad coder? Yes indeed. Could this help you, you young frustrated coder
with only a snailslow machine at your command? Probably.
In short; if you can do it in math... ehm... try math. (hey Josh, how's your
crash course Algebra? 🙂

wkr, jwk

Minkwitz Design had the next bright idea:

>I couldn't agree more. And to make things a little easier, check out the
>collinear function on this page of vbDesign 🙂 You can use something to the
>effect of :
>
>for i = lbound(coords) to ubound(coords) step 3
> if collinear(coords(i+1), coords(i+2),userpick) then
> 'set a variable or do something 🙂
> exit for
> end if
>next i
>
>where coords is an array equal to the coordinates property of the pline.
>-Josh

--
You ask a silly question, you get a technical answer...
0 Likes
Message 9 of 17

Anonymous
Not applicable
Hi jwk,
You mean regular old algebra? Not a problem. But I have yet to pick up a book
or find a cost effective course on the web for linear or abstract algebra 😞 But
you, being the math guru and all 🙂 perhaps you could take a peek at this math
version of the collinear function and tell me why it only works in 2D, but
returns false for 3D points that are collinear. I have to admit, I'm a little
stumped on this one, hence the geometry version. By the way, my machine is soooo
fast, that I can't tell the difference between the geometric and algebraic
versions 🙂
-Josh

** if knowledge is power, then withholding knowledge is oppression

Private Function Collinear_Old(Point1 As Variant, Point2 As Variant, Point3 As
Variant, Optional Tolerance As Double) As Boolean
Dim Vector1(0 To 2) As Double
Dim Vector2(0 To 2) As Double
Dim Vector3(0 To 2) As Double
Dim CrossProduct1(0 To 2) As Double
Dim CrossProduct2(0 To 2) As Double
Dim CrossProduct3(0 To 2) As Double
Dim Compare(0 To 2) As Boolean
Dim I As Integer

'Define Vectors from Points
Vector1(0) = Point2(0) - Point1(0): Vector1(1) = Point2(1) - Point1(1):
Vector1(2) = Point2(2) - Point1(2)
Vector2(0) = Point3(0) - Point2(0): Vector2(1) = Point3(1) - Point2(1):
Vector2(2) = Point3(2) - Point2(2)
Vector3(0) = Point3(0) - Point1(0): Vector3(1) = Point3(1) - Point1(1):
Vector1(2) = Point3(2) - Point1(2)

'Define CrossProducts from Vectors
CrossProduct1(0) = (Vector1(1) * Vector2(2)) - (Vector1(2) * Vector2(1))
CrossProduct1(1) = (Vector1(2) * Vector2(0)) - (Vector1(0) * Vector2(2))
CrossProduct1(2) = (Vector1(0) * Vector2(1)) - (Vector1(1) * Vector2(0))
CrossProduct2(0) = (Vector1(1) * Vector3(2)) - (Vector1(2) * Vector3(1))
CrossProduct2(1) = (Vector1(2) * Vector3(0)) - (Vector1(0) * Vector3(2))
CrossProduct2(2) = (Vector1(0) * Vector3(1)) - (Vector1(1) * Vector3(0))
CrossProduct3(0) = (Vector2(1) * Vector3(2)) - (Vector2(2) * Vector3(1))
CrossProduct3(1) = (Vector2(2) * Vector3(0)) - (Vector2(0) * Vector3(2))
CrossProduct3(2) = (Vector2(0) * Vector3(1)) - (Vector2(1) * Vector3(0))

'Check Crossproducts and compare to Tolerance to determine collinearity
For I = 0 To 2
If Abs(CrossProduct1(I)) <= Tolerance And Abs(CrossProduct2(I)) <=
Tolerance _
And Abs(CrossProduct3(I)) <= Tolerance Then
Compare(I) = True
End If
Next I
If Compare(0) And Compare(1) And Compare(2) Then Collinear_Old = True

End Function

jwk wrote:

> I looked into the code, and it seems at a first glance it's working with
> lines and their length properties. Let me make a few remarks (ah, please?)
>
> first, i'm working at this moment on some code that checks if lwplines are
> next to each other, touching each other, holding.... but i digress.
> At first, it worked with lines. It took 12 minutes to process. Then i changed
> the code so it didn't work with lines but only with coordinates. This brought
> the process time back to 2 minutes.
> After that, i first put every reference to a property (coordinates,
> Elevation, Thickness) into variables, and only worked with the variables.
> This brought the process time back to... 10 seconds.
>
> Am i a bad coder? Yes indeed. Could this help you, you young frustrated coder
> with only a snailslow machine at your command? Probably.
> In short; if you can do it in math... ehm... try math. (hey Josh, how's your
> crash course Algebra? 🙂
>
> wkr, jwk
>
> Minkwitz Design had the next bright idea:
>
> >I couldn't agree more. And to make things a little easier, check out the
> >collinear function on this page of vbDesign 🙂 You can use something to the
> >effect of :
> >
> >for i = lbound(coords) to ubound(coords) step 3
> > if collinear(coords(i+1), coords(i+2),userpick) then
> > 'set a variable or do something 🙂
> > exit for
> > end if
> >next i
> >
> >where coords is an array equal to the coordinates property of the pline.
> >-Josh
>
> --
> You ask a silly question, you get a technical answer...
0 Likes
Message 10 of 17

Anonymous
Not applicable
First, the book that's very useful to me (sometimes, when i understand it) is
"A programmer's geometry" from Adrian Bowyer and Jon Woodwark. It's an old book
with lot's of Yoda stuff like "many multiply this code have. Use you will not.
Lot CPU cycles it will take"... Actually, is meant for working with Fortran
77...

Second, let me strip your code (i will be gentle) and point the problem

> Vector3(0) = Point3(0) - Point1(0): Vector3(1) = Point3(1) -
> Point1(1): Vector1(2) = Point3(2) - Point1(2)
^ Now what does this number 2 doing here?

That's the problem of giving your variables not meaninful names (ahum).
Change te 2 into a 3, and your Collinear_old will be as new again.

Last, let me give you two functions. Just for fun...
Here's a function that also calculates if three points are collinear;
--------------
Public Function Colly(B As Variant, M As Variant, E As Variant, _
Optional Tolerance As Double) As Boolean
'Gives true if three points B(egin), M(iddle) and E(nd) are collinear
'if d(B,E)= d(B,M) + d(M,E)

Dim i As Integer, dBM As Double, dME As Double, dBE As Double

For i = 0 To UBound(B) 'Assuming all are 2D or all are 3D
dBM = dBM + (B(i) - M(i)) ^ 2
dME = dME + (M(i) - E(i)) ^ 2
dBE = dBE + (B(i) - E(i)) ^ 2
Next i
If Abs(Sqr(dBE) - Sqr(dBM) - Sqr(dME)) < Tolerance Then Colly = True _
Else Colly = False

End Function
----------------

The nifty little for next loop i picked up some time in this NG. Unfortunally,
it only works if point M is between B and E. So, you first have to order B, M,
and E. That shouldn't be a big problem. But it works for 2D and 3D.

Another one, even smaller, works only for 2D because it's calculating the area
between of the triangle between the three points.
----------------
Public Function Colly2D(B As Variant, M As Variant, E As Variant, _
Optional Tolerance As Double) As Boolean
'Gives true if three points, B(egin), M(iddle) and E(nd) are collinear
'By calculating the area of the triangle between the three points

Dim Bx As Double, By As Double, Mx As Double, My As Double
Dim Ex As Double, Ey As Double, A As Double

Bx = B(0): By = B(1): Mx = M(0): My = M(1): Ex = E(0): Ey = E(1)

A = Abs(0.5 * ((Mx - Bx) * (Ey - By) - (Ex - Bx) * (My - By)))
If A < Tolerance Then Colly2D = True Else Colly2D = False

End Function
-----------------
It looks longer because i put some meaningful variable names in it. But you can
even compress it more if you want. It's also very quick because the
calculations are very simple.

If you can use it, use it. If you have comments, follow up! Remember, this code
is bloated with copyrights; feel free to use, and if you ever even try to keep
it from other people to use it, i will hunt you down! 🙂

wkr, jwk
--
If I say you have a beautiful body would you use it against me?

Minkwitz Design had the next bright idea:

>Hi jwk,
> You mean regular old algebra? Not a problem. But I have yet to pick up
> a book
>or find a cost effective course on the web for linear or abstract algebra
>:( But you, being the math guru and all 🙂 perhaps you could take a peek
>at this math version of the collinear function and tell me why it only
>works in 2D, but returns false for 3D points that are collinear. I have to
>admit, I'm a little stumped on this one, hence the geometry version. By
>the way, my machine is soooo fast, that I can't tell the difference
>between the geometric and algebraic versions 🙂
>-Josh
>
>** if knowledge is power, then withholding knowledge is oppression
>
>Private Function Collinear_Old(Point1 As Variant, Point2 As Variant,
>Point3 As Variant, Optional Tolerance As Double) As Boolean
> Dim Vector1(0 To 2) As Double
> Dim Vector2(0 To 2) As Double
> Dim Vector3(0 To 2) As Double
> Dim CrossProduct1(0 To 2) As Double
> Dim CrossProduct2(0 To 2) As Double
> Dim CrossProduct3(0 To 2) As Double
> Dim Compare(0 To 2) As Boolean
> Dim I As Integer
>
> 'Define Vectors from Points
> Vector1(0) = Point2(0) - Point1(0): Vector1(1) = Point2(1) -
> Point1(1):
>Vector1(2) = Point2(2) - Point1(2)
> Vector2(0) = Point3(0) - Point2(0): Vector2(1) = Point3(1) -
> Point2(1):
>Vector2(2) = Point3(2) - Point2(2)
> Vector3(0) = Point3(0) - Point1(0): Vector3(1) = Point3(1) -
> Point1(1):
>Vector1(2) = Point3(2) - Point1(2)
>
> 'Define CrossProducts from Vectors
> CrossProduct1(0) = (Vector1(1) * Vector2(2)) - (Vector1(2) *
> Vector2(1)) CrossProduct1(1) = (Vector1(2) * Vector2(0)) - (Vector1(0)
> * Vector2(2)) CrossProduct1(2) = (Vector1(0) * Vector2(1)) -
> (Vector1(1) * Vector2(0)) CrossProduct2(0) = (Vector1(1) * Vector3(2))
> - (Vector1(2) * Vector3(1)) CrossProduct2(1) = (Vector1(2) *
> Vector3(0)) - (Vector1(0) * Vector3(2)) CrossProduct2(2) = (Vector1(0)
> * Vector3(1)) - (Vector1(1) * Vector3(0)) CrossProduct3(0) =
> (Vector2(1) * Vector3(2)) - (Vector2(2) * Vector3(1)) CrossProduct3(1)
> = (Vector2(2) * Vector3(0)) - (Vector2(0) * Vector3(2))
> CrossProduct3(2) = (Vector2(0) * Vector3(1)) - (Vector2(1) *
> Vector3(0))
>
> 'Check Crossproducts and compare to Tolerance to determine
> collinearity For I = 0 To 2
> If Abs(CrossProduct1(I)) <= Tolerance And Abs(CrossProduct2(I)) <=
>Tolerance _
> And Abs(CrossProduct3(I)) <= Tolerance Then
> Compare(I) = True
> End If
> Next I
> If Compare(0) And Compare(1) And Compare(2) Then Collinear_Old = True
>
>End Function
0 Likes
Message 11 of 17

Anonymous
Not applicable
Master Yoda,
Wise in algebraic ways you are! This book I have sought out. No longer in print
is it. A standing order with Amazon's used books I have.

"That's the problem of giving your variables not meaninful names (ahum)."
What? They make sense to me :),,,,Three points = point1, point2, point3

"Public Function Colly"
Do you have a Dog?

All in all, Thank You! The error of my ways you have shown me. Test your functions
and play will I.

May the force be with you,
-Josh

jwk wrote:

> First, the book that's very useful to me (sometimes, when i understand it) is
> "A programmer's geometry" from Adrian Bowyer and Jon Woodwark. It's an old book
> with lot's of Yoda stuff like "many multiply this code have. Use you will not.
> Lot CPU cycles it will take"... Actually, is meant for working with Fortran
> 77...
>
> Second, let me strip your code (i will be gentle) and point the problem
>
> > Vector3(0) = Point3(0) - Point1(0): Vector3(1) = Point3(1) -
> > Point1(1): Vector1(2) = Point3(2) - Point1(2)
> ^ Now what does this number 2 doing here?
>
> That's the problem of giving your variables not meaninful names (ahum).
> Change te 2 into a 3, and your Collinear_old will be as new again.
>
> Last, let me give you two functions. Just for fun...
> Here's a function that also calculates if three points are collinear;
> --------------
> Public Function Colly(B As Variant, M As Variant, E As Variant, _
> Optional Tolerance As Double) As Boolean
> 'Gives true if three points B(egin), M(iddle) and E(nd) are collinear
> 'if d(B,E)= d(B,M) + d(M,E)
>
> Dim i As Integer, dBM As Double, dME As Double, dBE As Double
>
> For i = 0 To UBound(B) 'Assuming all are 2D or all are 3D
> dBM = dBM + (B(i) - M(i)) ^ 2
> dME = dME + (M(i) - E(i)) ^ 2
> dBE = dBE + (B(i) - E(i)) ^ 2
> Next i
> If Abs(Sqr(dBE) - Sqr(dBM) - Sqr(dME)) < Tolerance Then Colly = True _
> Else Colly = False
>
> End Function
> ----------------
>
> The nifty little for next loop i picked up some time in this NG. Unfortunally,
> it only works if point M is between B and E. So, you first have to order B, M,
> and E. That shouldn't be a big problem. But it works for 2D and 3D.
>
> Another one, even smaller, works only for 2D because it's calculating the area
> between of the triangle between the three points.
> ----------------
> Public Function Colly2D(B As Variant, M As Variant, E As Variant, _
> Optional Tolerance As Double) As Boolean
> 'Gives true if three points, B(egin), M(iddle) and E(nd) are collinear
> 'By calculating the area of the triangle between the three points
>
> Dim Bx As Double, By As Double, Mx As Double, My As Double
> Dim Ex As Double, Ey As Double, A As Double
>
> Bx = B(0): By = B(1): Mx = M(0): My = M(1): Ex = E(0): Ey = E(1)
>
> A = Abs(0.5 * ((Mx - Bx) * (Ey - By) - (Ex - Bx) * (My - By)))
> If A < Tolerance Then Colly2D = True Else Colly2D = False
>
> End Function
> -----------------
> It looks longer because i put some meaningful variable names in it. But you can
> even compress it more if you want. It's also very quick because the
> calculations are very simple.
>
> If you can use it, use it. If you have comments, follow up! Remember, this code
> is bloated with copyrights; feel free to use, and if you ever even try to keep
> it from other people to use it, i will hunt you down! 🙂
>
> wkr, jwk
> --
> If I say you have a beautiful body would you use it against me?
>
> Minkwitz Design had the next bright idea:
>
> >Hi jwk,
> > You mean regular old algebra? Not a problem. But I have yet to pick up
> > a book
> >or find a cost effective course on the web for linear or abstract algebra
> 😠 But you, being the math guru and all 🙂 perhaps you could take a peek
> >at this math version of the collinear function and tell me why it only
> >works in 2D, but returns false for 3D points that are collinear. I have to
> >admit, I'm a little stumped on this one, hence the geometry version. By
> >the way, my machine is soooo fast, that I can't tell the difference
> >between the geometric and algebraic versions 🙂
> >-Josh
> >
> >** if knowledge is power, then withholding knowledge is oppression
> >
> >Private Function Collinear_Old(Point1 As Variant, Point2 As Variant,
> >Point3 As Variant, Optional Tolerance As Double) As Boolean
> > Dim Vector1(0 To 2) As Double
> > Dim Vector2(0 To 2) As Double
> > Dim Vector3(0 To 2) As Double
> > Dim CrossProduct1(0 To 2) As Double
> > Dim CrossProduct2(0 To 2) As Double
> > Dim CrossProduct3(0 To 2) As Double
> > Dim Compare(0 To 2) As Boolean
> > Dim I As Integer
> >
> > 'Define Vectors from Points
> > Vector1(0) = Point2(0) - Point1(0): Vector1(1) = Point2(1) -
> > Point1(1):
> >Vector1(2) = Point2(2) - Point1(2)
> > Vector2(0) = Point3(0) - Point2(0): Vector2(1) = Point3(1) -
> > Point2(1):
> >Vector2(2) = Point3(2) - Point2(2)
> > Vector3(0) = Point3(0) - Point1(0): Vector3(1) = Point3(1) -
> > Point1(1):
> >Vector1(2) = Point3(2) - Point1(2)
> >
> > 'Define CrossProducts from Vectors
> > CrossProduct1(0) = (Vector1(1) * Vector2(2)) - (Vector1(2) *
> > Vector2(1)) CrossProduct1(1) = (Vector1(2) * Vector2(0)) - (Vector1(0)
> > * Vector2(2)) CrossProduct1(2) = (Vector1(0) * Vector2(1)) -
> > (Vector1(1) * Vector2(0)) CrossProduct2(0) = (Vector1(1) * Vector3(2))
> > - (Vector1(2) * Vector3(1)) CrossProduct2(1) = (Vector1(2) *
> > Vector3(0)) - (Vector1(0) * Vector3(2)) CrossProduct2(2) = (Vector1(0)
> > * Vector3(1)) - (Vector1(1) * Vector3(0)) CrossProduct3(0) =
> > (Vector2(1) * Vector3(2)) - (Vector2(2) * Vector3(1)) CrossProduct3(1)
> > = (Vector2(2) * Vector3(0)) - (Vector2(0) * Vector3(2))
> > CrossProduct3(2) = (Vector2(0) * Vector3(1)) - (Vector2(1) *
> > Vector3(0))
> >
> > 'Check Crossproducts and compare to Tolerance to determine
> > collinearity For I = 0 To 2
> > If Abs(CrossProduct1(I)) <= Tolerance And Abs(CrossProduct2(I)) <=
> >Tolerance _
> > And Abs(CrossProduct3(I)) <= Tolerance Then
> > Compare(I) = True
> > End If
> > Next I
> > If Compare(0) And Compare(1) And Compare(2) Then Collinear_Old = True
> >
> >End Function
0 Likes
Message 12 of 17

Anonymous
Not applicable
The following code will return an integer indicating which segment of a polyline
was selected by the user, even if that segment is an arc. The segment is
1-based, so to get the coordinates for the segment look at Coordinate(Segment -
1) and Coordiante(Segment).

To use this, you must have both Curve.cls and VLAX.cls. You can get them from
the downloads section of my site.

Public Function SelectedSegment(ent As AcadEntity, pt) As Integer

Dim obj As Curve, dist As Double, i As Integer
Dim max As Integer, segment As Integer

Set obj = New Curve
Set obj.Entity = ent
dist = obj.GetDistanceAtPoint(obj.GetClosestPointTo(pt))
max = (UBound(ent.Coordinates) + 1) / 2

For i = 0 To max - 1
If obj.GetDistanceAtPoint(ent.Coordinate(i)) > dist Then Exit For
segment = segment + 1
Next

SelectedSegment = segment

End Function

--
http://www.acadx.com
Win a free autographed copy of
"AutoCAD 2000 VBA Programmer's Reference"

"Bernard Flavignard" wrote in message
news:DFE8C869D539182FF5A6C11CDB1995E8@in.WebX.maYIadrTaRb...
> Hello,
>
> I have a lwpolyline, i want the user click this pline, no problem
> This pline have only linear segments
> I want to know between which vertices, or on which segment the user has
> clicked
>
> Thank you for the help
>
> Bernard
> ATC
> 45700 Villemandeur
> France
>
0 Likes
Message 13 of 17

Anonymous
Not applicable
P.s.- further testing has informed me that your colly2d function is actually a
colly2d&3d function 🙂 I tested it with an applied tolerance of .000001 and it
works in both. And by the way, you meant change the 1 into a 3 🙂 Thanks again.

Vector3(0) = Point3(0) - Point1(0): Vector3(1) = Point3(1) - Point1(1): Vector3(2)
= Point3(2) - Point1(2)

jwk wrote:

> First, the book that's very useful to me (sometimes, when i understand it) is
> "A programmer's geometry" from Adrian Bowyer and Jon Woodwark. It's an old book
> with lot's of Yoda stuff like "many multiply this code have. Use you will not.
> Lot CPU cycles it will take"... Actually, is meant for working with Fortran
> 77...
>
> Second, let me strip your code (i will be gentle) and point the problem
>
> > Vector3(0) = Point3(0) - Point1(0): Vector3(1) = Point3(1) -
> > Point1(1): Vector1(2) = Point3(2) - Point1(2)
> ^ Now what does this number 2 doing here?
>
> That's the problem of giving your variables not meaninful names (ahum).
> Change te 2 into a 3, and your Collinear_old will be as new again.
>
> Last, let me give you two functions. Just for fun...
> Here's a function that also calculates if three points are collinear;
> --------------
> Public Function Colly(B As Variant, M As Variant, E As Variant, _
> Optional Tolerance As Double) As Boolean
> 'Gives true if three points B(egin), M(iddle) and E(nd) are collinear
> 'if d(B,E)= d(B,M) + d(M,E)
>
> Dim i As Integer, dBM As Double, dME As Double, dBE As Double
>
> For i = 0 To UBound(B) 'Assuming all are 2D or all are 3D
> dBM = dBM + (B(i) - M(i)) ^ 2
> dME = dME + (M(i) - E(i)) ^ 2
> dBE = dBE + (B(i) - E(i)) ^ 2
> Next i
> If Abs(Sqr(dBE) - Sqr(dBM) - Sqr(dME)) < Tolerance Then Colly = True _
> Else Colly = False
>
> End Function
> ----------------
>
> The nifty little for next loop i picked up some time in this NG. Unfortunally,
> it only works if point M is between B and E. So, you first have to order B, M,
> and E. That shouldn't be a big problem. But it works for 2D and 3D.
>
> Another one, even smaller, works only for 2D because it's calculating the area
> between of the triangle between the three points.
> ----------------
> Public Function Colly2D(B As Variant, M As Variant, E As Variant, _
> Optional Tolerance As Double) As Boolean
> 'Gives true if three points, B(egin), M(iddle) and E(nd) are collinear
> 'By calculating the area of the triangle between the three points
>
> Dim Bx As Double, By As Double, Mx As Double, My As Double
> Dim Ex As Double, Ey As Double, A As Double
>
> Bx = B(0): By = B(1): Mx = M(0): My = M(1): Ex = E(0): Ey = E(1)
>
> A = Abs(0.5 * ((Mx - Bx) * (Ey - By) - (Ex - Bx) * (My - By)))
> If A < Tolerance Then Colly2D = True Else Colly2D = False
>
> End Function
> -----------------
> It looks longer because i put some meaningful variable names in it. But you can
> even compress it more if you want. It's also very quick because the
> calculations are very simple.
>
> If you can use it, use it. If you have comments, follow up! Remember, this code
> is bloated with copyrights; feel free to use, and if you ever even try to keep
> it from other people to use it, i will hunt you down! 🙂
>
> wkr, jwk
> --
> If I say you have a beautiful body would you use it against me?
>
> Minkwitz Design had the next bright idea:
>
> >Hi jwk,
> > You mean regular old algebra? Not a problem. But I have yet to pick up
> > a book
> >or find a cost effective course on the web for linear or abstract algebra
> 😠 But you, being the math guru and all 🙂 perhaps you could take a peek
> >at this math version of the collinear function and tell me why it only
> >works in 2D, but returns false for 3D points that are collinear. I have to
> >admit, I'm a little stumped on this one, hence the geometry version. By
> >the way, my machine is soooo fast, that I can't tell the difference
> >between the geometric and algebraic versions 🙂
> >-Josh
> >
> >** if knowledge is power, then withholding knowledge is oppression
> >
> >Private Function Collinear_Old(Point1 As Variant, Point2 As Variant,
> >Point3 As Variant, Optional Tolerance As Double) As Boolean
> > Dim Vector1(0 To 2) As Double
> > Dim Vector2(0 To 2) As Double
> > Dim Vector3(0 To 2) As Double
> > Dim CrossProduct1(0 To 2) As Double
> > Dim CrossProduct2(0 To 2) As Double
> > Dim CrossProduct3(0 To 2) As Double
> > Dim Compare(0 To 2) As Boolean
> > Dim I As Integer
> >
> > 'Define Vectors from Points
> > Vector1(0) = Point2(0) - Point1(0): Vector1(1) = Point2(1) -
> > Point1(1):
> >Vector1(2) = Point2(2) - Point1(2)
> > Vector2(0) = Point3(0) - Point2(0): Vector2(1) = Point3(1) -
> > Point2(1):
> >Vector2(2) = Point3(2) - Point2(2)
> > Vector3(0) = Point3(0) - Point1(0): Vector3(1) = Point3(1) -
> > Point1(1):
> >Vector1(2) = Point3(2) - Point1(2)
> >
> > 'Define CrossProducts from Vectors
> > CrossProduct1(0) = (Vector1(1) * Vector2(2)) - (Vector1(2) *
> > Vector2(1)) CrossProduct1(1) = (Vector1(2) * Vector2(0)) - (Vector1(0)
> > * Vector2(2)) CrossProduct1(2) = (Vector1(0) * Vector2(1)) -
> > (Vector1(1) * Vector2(0)) CrossProduct2(0) = (Vector1(1) * Vector3(2))
> > - (Vector1(2) * Vector3(1)) CrossProduct2(1) = (Vector1(2) *
> > Vector3(0)) - (Vector1(0) * Vector3(2)) CrossProduct2(2) = (Vector1(0)
> > * Vector3(1)) - (Vector1(1) * Vector3(0)) CrossProduct3(0) =
> > (Vector2(1) * Vector3(2)) - (Vector2(2) * Vector3(1)) CrossProduct3(1)
> > = (Vector2(2) * Vector3(0)) - (Vector2(0) * Vector3(2))
> > CrossProduct3(2) = (Vector2(0) * Vector3(1)) - (Vector2(1) *
> > Vector3(0))
> >
> > 'Check Crossproducts and compare to Tolerance to determine
> > collinearity For I = 0 To 2
> > If Abs(CrossProduct1(I)) <= Tolerance And Abs(CrossProduct2(I)) <=
> >Tolerance _
> > And Abs(CrossProduct3(I)) <= Tolerance Then
> > Compare(I) = True
> > End If
> > Next I
> > If Compare(0) And Compare(1) And Compare(2) Then Collinear_Old = True
> >
> >End Function
0 Likes
Message 14 of 17

Anonymous
Not applicable
Huh? How is that possible when Colly2D only work with X- and Y-coordinates?
Have you tried using three points forming a triangle in the X-Z plane?

Now i'm stunned... 🙂

wkr, jwk

Minkwitz Design had the next bright idea:

>P.s.- further testing has informed me that your colly2d function is
>actually a colly2d&3d function 🙂 I tested it with an applied tolerance of
>.000001 and it works in both. And by the way, you meant change the 1 into
>a 3 🙂 Thanks again.

[deletia]

>> ----------------
>> Public Function Colly2D(B As Variant, M As Variant, E As Variant, _
>> Optional Tolerance As Double) As Boolean
>> 'Gives true if three points, B(egin), M(iddle) and E(nd) are
>> collinear 'By calculating the area of the triangle between the three
>> points
>>
>> Dim Bx As Double, By As Double, Mx As Double, My As Double
>> Dim Ex As Double, Ey As Double, A As Double
>>
>> Bx = B(0): By = B(1): Mx = M(0): My = M(1): Ex = E(0): Ey = E(1)
>>
>> A = Abs(0.5 * ((Mx - Bx) * (Ey - By) - (Ex - Bx) * (My - By)))
>> If A < Tolerance Then Colly2D = True Else Colly2D = False
>>
>> End Function
>> ----------------

[deletia]

--
If I say you have a beautiful body would you use it against me?
0 Likes
Message 15 of 17

Anonymous
Not applicable
Now usually i am the last man who will doubt my own intelligence. But, i have
to correct this; i tried if Colly2D was really useful with 3D, but allas. If
you use the following points;
B(0,0,0)
M(10,0,0)
E(20,0,40)
You can imagine that the answer should be false, but Colly2D thinks it's
false.
Too bad... Anyone knows the formula for calculating the area of a triangle in
3D? 🙂

>Minkwitz Design had the next bright idea:
>
>>P.s.- further testing has informed me that your colly2d function is
>>actually a colly2d&3d function 🙂 I tested it with an applied tolerance of
>>.000001 and it works in both. And by the way, you meant change the 1 into
>>a 3 🙂 Thanks again.
>
>[deletia]
>
>>> ----------------
>>> Public Function Colly2D(B As Variant, M As Variant, E As Variant, _
>>> Optional Tolerance As Double) As Boolean
>>> 'Gives true if three points, B(egin), M(iddle) and E(nd) are
>>> collinear 'By calculating the area of the triangle between the three
>>> points
>>>
>>> Dim Bx As Double, By As Double, Mx As Double, My As Double
>>> Dim Ex As Double, Ey As Double, A As Double
>>>
>>> Bx = B(0): By = B(1): Mx = M(0): My = M(1): Ex = E(0): Ey = E(1)
>>>
>>> A = Abs(0.5 * ((Mx - Bx) * (Ey - By) - (Ex - Bx) * (My - By)))
>>> If A < Tolerance Then Colly2D = True Else Colly2D = False
>>>
>>> End Function
>>> ----------------
>
>[deletia]
>

--
If I say you have a beautiful body would you use it against me?
0 Likes
Message 16 of 17

Anonymous
Not applicable
Maybe I'm misinterpreting what you where shooting for. When you said it works
only for 2D, I thought you meant it would only work in 2D and return False for
3D lines. As it stands, even an arc in 3D will return True if the points are
collinear in the current UCS. With the Z element eliminated, depth is
irrelevant. A triangle in the X-Z plane will return True because the points in
the X-Y plane will always be collinear unless one of the Y elements is
different, ect.
-Josh

jwk wrote:

> Huh? How is that possible when Colly2D only work with X- and Y-coordinates?
> Have you tried using three points forming a triangle in the X-Z plane?
>
> Now i'm stunned... 🙂
>
> wkr, jwk
>
> Minkwitz Design had the next bright idea:
>
> >P.s.- further testing has informed me that your colly2d function is
> >actually a colly2d&3d function 🙂 I tested it with an applied tolerance of
> >.000001 and it works in both. And by the way, you meant change the 1 into
> >a 3 🙂 Thanks again.
>
> [deletia]
>
> >> ----------------
> >> Public Function Colly2D(B As Variant, M As Variant, E As Variant, _
> >> Optional Tolerance As Double) As Boolean
> >> 'Gives true if three points, B(egin), M(iddle) and E(nd) are
> >> collinear 'By calculating the area of the triangle between the three
> >> points
> >>
> >> Dim Bx As Double, By As Double, Mx As Double, My As Double
> >> Dim Ex As Double, Ey As Double, A As Double
> >>
> >> Bx = B(0): By = B(1): Mx = M(0): My = M(1): Ex = E(0): Ey = E(1)
> >>
> >> A = Abs(0.5 * ((Mx - Bx) * (Ey - By) - (Ex - Bx) * (My - By)))
> >> If A < Tolerance Then Colly2D = True Else Colly2D = False
> >>
> >> End Function
> >> ----------------
>
> [deletia]
>
> --
> If I say you have a beautiful body would you use it against me?
0 Likes
Message 17 of 17

Anonymous
Not applicable
Why not just use an if statement checking for equality of the Z element of each
point? Or is that cheating 🙂

jwk wrote:

> Now usually i am the last man who will doubt my own intelligence. But, i have
> to correct this; i tried if Colly2D was really useful with 3D, but allas. If
> you use the following points;
> B(0,0,0)
> M(10,0,0)
> E(20,0,40)
> You can imagine that the answer should be false, but Colly2D thinks it's
> false.
> Too bad... Anyone knows the formula for calculating the area of a triangle in
> 3D? 🙂
>
> >Minkwitz Design had the next bright idea:
> >
> >>P.s.- further testing has informed me that your colly2d function is
> >>actually a colly2d&3d function 🙂 I tested it with an applied tolerance of
> >>.000001 and it works in both. And by the way, you meant change the 1 into
> >>a 3 🙂 Thanks again.
> >
> >[deletia]
> >
> >>> ----------------
> >>> Public Function Colly2D(B As Variant, M As Variant, E As Variant, _
> >>> Optional Tolerance As Double) As Boolean
> >>> 'Gives true if three points, B(egin), M(iddle) and E(nd) are
> >>> collinear 'By calculating the area of the triangle between the three
> >>> points
> >>>
> >>> Dim Bx As Double, By As Double, Mx As Double, My As Double
> >>> Dim Ex As Double, Ey As Double, A As Double
> >>>
> >>> Bx = B(0): By = B(1): Mx = M(0): My = M(1): Ex = E(0): Ey = E(1)
> >>>
> >>> A = Abs(0.5 * ((Mx - Bx) * (Ey - By) - (Ex - Bx) * (My - By)))
> >>> If A < Tolerance Then Colly2D = True Else Colly2D = False
> >>>
> >>> End Function
> >>> ----------------
> >
> >[deletia]
> >
>
> --
> If I say you have a beautiful body would you use it against me?
0 Likes