Lines and angles from points
(Originally posted by gjermund on 10/03/2007)
Hello
This is my problem:
I
would like to measure salmon hearts by 5 lengths and one angle. All of
the above are defined by 4 points, see fig a. The lengths are the
distances between P1-P2, P1-P3, P2-P3, P3-P4 and P4 - Line 1 (on the
line between P3 and P4) green line in fig b. Finally I would like to
measure the angle between line L1 and L4, see AF1 in fig c.
We
have 6000 hearts, and need a macro that can measure these parameters
based on the four points, which will have to be put in interactively
with the mouse.
Appreciate any good tips on macro functions that can do this. Thanks.
0
Comments
(Originally posted by KevinR on 10/3/2007)
The simplest way would be to prompt the user to draw the polygon using either the AOI or annotation tool, then look at the points in the polygon and calculate the geometric properties thereof.
I would run a small loop that prompts the user with IpDocClick to click on the various points, drawing an annotation line with IpAnCreateObj( ) for each segment. After the 4th point draw the last connecting line, use IpAnGet with GO_ATTR_NUMPOINTS and GO_ATTR_POINTS to obtain the points for the lines, and then calculate your values using sin, cos, and atan.
(Originally posted by KevinR on 10/8/2007)
Here's a few useful IpBasic routines for this sort of calculation. OffsetToAngle( ) converts an X and Y distance (from the differences between two points, for example) into an angle. TrimAngle is a utility function that makes certain angles remain between 0-2*pi. AngleDiff( ) gives you the difference between two angles.
Lengths of lines defined by two points are simple geometry, the Euclidian distance:
Length = [ (x1-x2)^2 + (y1-y2)^2 ] ^0.5
Here's the set of utility routines. These are written so that zero degrees is a vertical line, pointing to 12 o-clock as you look at the screen. This matches with angles produced by Count/Size, for example.
Const PI = 3.14159265 Function TrimAngle(angle As Single) As Single If angle = 0.0 Then TrimAngle = 0.0 Exit Function End If Do Until angle > 0.0 angle = angle + 2.0 * PI Loop Do Until angle <= 2.0 * PI angle = angle - 2.0 * PI Loop TrimAngle = angle End Function Function OffsetToAngle(xOff As Long, yOff As Long) As Single If xOff = 0 Then If yOff < 0 Then OffsetToAngle = 0.0 Else OffsetToAngle = PI End If Else OffsetToAngle = Atn(CSng(yOff)/CSng(xOff)) If xOff >= 0 And yOff >= 0 Then ' No change ElseIf xOff < 0 And yOff >= 0 Then OffsetToAngle = PI + OffsetToAngle ElseIf xOff < 0 And yOff < 0 Then OffsetToAngle = PI + OffsetToAngle Else OffsetToAngle = 2.0 * PI + OffsetToAngle End If End If OffsetToAngle = OffsetToAngle + PI/2.0 OffsetToAngle = TrimAngle(OffsetToAngle) End Function Function AngleDiff(ByVal angle1 As Single, ByVal angle2 As Single) As Single Dim diff1 As Single, diff2 As Single diff1 = Abs(angle1 - angle2) If angle1 > angle2 Then angle2 = angle2 + 2.0*PI Else angle1 = angle1 + 2.0*PI End If diff2 = Abs(angle1 - angle2) If diff1 < diff2 Then AngleDiff = diff1 Else AngleDiff = diff2 End If End Function
For information such as distance between points and a line, projections of one line on another, and other geometric calculations, I would recommend checking with a geometry text or Googling the measurement of interest for the basic equations. Searching on "distance between point and line" gave the essential equations in four of the first five references.
(Originally posted by gjermund on 10/15/2007)
Thanks! The advice was just what I needed!
I now have a macro that does all the neccessary calculations from the four points.