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