Jump to content

Recommended Posts

Posted

Is anyone able to help

 

In vb.net how do i find the angle of the tangent line to a curve at a given point relative to the X axis?

 

Also would this have to be quadrant sensitive?

Posted

Don't know vb.net, but the function/expression you need is the "arc tangent", so look for something like that. In lisp it's "atan". And yes it's quadrant sensitive, positive tangent would give you a 0-90 degree result, negative is for a 90-180 degrees.

 

**edit** found this, might help:

 

This example uses the Atan method of the Math class to calculate the value of pi.

 

Public Function GetPi() As Double
   ' Calculate the value of pi.
   Return 4.0 * Math.Atan(1.0)
End Function

Posted

The general methodology for 3d curves would be:

 

1. Select the curve

2. Pick a point(Point3d) on the curve with (DatabaseServices.Curve.GetClosestPointTo)

3. Get first derivative(Geometry.Vector3d) with(DatabaseServices.Curve.GetFirstDerivative (Geometry.Point3d))

4. Get angle with System.Math.Atan(Geometry.Vector3d.Y/Geometry.Vector3d.X)

Posted

ahh thank you very much

Posted

so how do i calculate what quadrant it is in so that i can calculate the 'Normal to the tangent'.?

Posted

Tan is positive for quadrants 1 and 3 and negative for quadrants 2 and 4, hence a positive result indicates a vector at 0-pi/2 to the x-axis, plus or minus pi; and negative pi/2 - pi, plus or minus pi.

 

I suppose you could add coding to correct the angle by pi radians so that you will only get an answer between 0 and pi, then the normal to the tangent will just be the arctan + pi/2.

 

Is this a purely 2D problem, or are you interested in the Binormal to the tangent also?

Posted

No its purely 2d.

 

Thanks for that - i changed the code around so it will work now.

 

This is what i have.

 

[size=2][color=#0000ff]Public Function [/color][/size][size=2]CalcAngle([/size][size=2][color=#0000ff]ByVal [/color][/size][size=2]ObjCurve [/size][size=2][color=#0000ff]As [/color][/size][size=2]AcadNetDbServices.Curve, [/size][size=2][color=#0000ff]ByVal [/color][/size][size=2]Dist [/size][size=2][color=#0000ff]As [/color][/size][size=2][color=#6f002f]Double[/color][/size][size=2])
[/size][size=2][color=#008000] 
[/color][/size][size=2][color=#0000ff]Dim [/color][/size][size=2]Radians [/size][size=2][color=#0000ff]As [/color][/size][size=2][color=#6f002f]Double
[/color][/size][size=2][color=#0000ff]Dim [/color][/size][size=2]Degrees [/size][size=2][color=#0000ff]As [/color][/size][size=2][color=#6f002f]Double
[/color][/size][size=2][color=#0000ff]Dim [/color][/size][size=2]Point1 [/size][size=2][color=#0000ff]As [/color][/size][size=2]AcadNetGeometry.Point3d = ObjCurve.GetPointAtDist(Dist)
[/size][size=2][color=#0000ff]Dim [/color][/size][size=2]firstderiv [/size][size=2][color=#0000ff]As [/color][/size][size=2]AcadNetGeometry.Vector3d = ObjCurve.GetFirstDerivative(Point1)
Radians = Math.Atan2([/size][size=2][color=#0000ff]Cdbl[/color][/size][size=2](firstderiv.Y) , [/size][size=2][color=#0000ff]Cdbl[/color][/size][size=2](firstderiv.X))
Degrees = Radians * (180 / Math.PI)

[/size][size=2][color=#008000]'If in positive quadrants then = 180 - abs.Degrees
'If in Negative quadrants then = Abs.Degrees - 180
[/color][/size][size=2][color=#0000ff]If [/color][/size][size=2]Degrees < 0 [/size][size=2][color=#0000ff]Then
[/color][/size][size=2]Degrees = (Math.Abs(Degrees)) + 180
[/size][size=2][color=#0000ff]Else
[/color][/size][size=2]Degrees = 180 - (Math.Abs(Degrees))
[/size][size=2][color=#0000ff]End If
[/color][/size][size=2]CalcAngle = Degrees

[/size][size=2][color=#0000ff]End Function
[/color][/size] 

Posted

Not sure why you would set Degrees = 180 - angle for any positive result. Say it was initially calculated at 45 degrees, wouldn't that be a good answer already? But then I don't know what you're using it for...

Posted

I don't know much about vb.net (in fact I know absolutely nothing about it), but when you find the first derivative, does that not return a vector? - Then you would know exactly the direction of the tangent from the vector.

Posted

derivative gives the slope of the tangent.

 

using atan2 gets the arc tangent to it.

 

also i had to use Degrees = 180 - Angle in the positive quadrant because i was getting answers like 175 & 115 when it should be 5 & 65 etc

 

Thanks for your help guys.

 

This works

Posted

derivative gives the slope of the tangent.

 

using atan2 gets the arc tangent to it.

 

also i had to use Degrees = 180 - Angle in the positive quadrant because i was getting answers like 175 & 115 when it should be 5 & 65 etc

 

Thanks for your help guys.

 

This works

Posted

Ok, glad it works for you Russell - just offering other suggestions :thumbsup:

 

Lee

Posted

some more angles for whoever is interested.

 

[size=2][color=#008000]'If you want the the angle between the line defined by these two points and the horizontal axis:[/color][/size]
[size=2][color=#0000ff]Public Function [/color][/size][size=2]DoubleAngle ([/size][size=2][color=#0000ff]ByVal [/color][/size][size=2]Point1 [/size][size=2][color=#0000ff]As [/color][/size][size=2]AcadNetGeometry.Point3d, [/size][size=2][color=#0000ff]ByVal [/color][/size][size=2]Point2 [/size][size=2][color=#0000ff]As [/color][/size][size=2]AcadNetGeometry.Point3d) [/size][size=2][color=#0000ff]As [/color][/size][size=2][color=#6f002f]Double[/color][/size]
[size=2]DoubleAngle = math.Atan2(Point2(1) - Point1(1),Point2(0) - Point1(0)) [/size][size=2][color=#008000]'Answer in Radians[/color][/size]
[size=2][color=#0000ff]End Function[/color][/size]


[size=2][color=#008000]'If you want the angle bewteen the vectors OP1 and OP2 (O being the origin), you should know that the dot product between two vectors u and v is:[/color][/size]
[size=2][color=#008000]'u . v = u.x * v.x + u.y * v.y = |u|*|v|*cos(a)[/color][/size]
[size=2][color=#008000]'a being the angle between the vectors.[/color][/size]
[size=2][color=#008000]'So the angle is given by:[/color][/size]
[size=2][color=#008000]'double n1 = sqrt(x1*x1+y1*y1), n2 = sqrt(x2*x2+y2*y2);[/color][/size]
[size=2][color=#008000]'double angle = acos((x1*x2+y1*y2)/(n1*n2));[/color][/size]
[size=2][color=#0000ff]Public Function [/color][/size][size=2]AngleBetweenVectors([/size][size=2][color=#0000ff]ByVal [/color][/size][size=2]Point1 [/size][size=2][color=#0000ff]As [/color][/size][size=2]AcadNetGeometry.Point3d, [/size][size=2][color=#0000ff]ByVal [/color][/size][size=2]Point2 [/size][size=2][color=#0000ff]As [/color][/size][size=2]AcadNetGeometry.Point3d) [/size][size=2][color=#0000ff]As [/color][/size][size=2][color=#6f002f]Double[/color][/size]
[size=2][color=#0000ff]Dim [/color][/size][size=2]N1 [/size][size=2][color=#0000ff]As [/color][/size][size=2][color=#6f002f]Double[/color][/size]
[size=2]N1 = Math.Sqrt(Math.Pow(Point1(0), 2) + Math.Pow(Point1(1), 2))[/size]
[size=2][color=#0000ff]Dim [/color][/size][size=2]N2 [/size][size=2][color=#0000ff]As [/color][/size][size=2][color=#6f002f]Double[/color][/size]
[size=2]N2 = Math.Sqrt(Math.Pow(Point2(0), 2) + Math.Pow(Point2(1), 2))[/size]
[size=2][color=#0000ff]Dim [/color][/size][size=2]AngleTemp [/size][size=2][color=#0000ff]As [/color][/size][size=2][color=#6f002f]Double [/color][/size][size=2]= Math.Acos((Point1(0) * Point2(0) + Point1(1) * Point2(1)) / (N1 * N2)) [/size][size=2][color=#008000]'(in radians) * 180/MATH.PI to get degrees[/color][/size]
[size=2][color=#008000][size=2][color=black]AngleBetweenVectors = AngleTemp[/color][/size]
[/color][/size][size=2][color=#0000ff]End Function[/color][/size]

[size=2][color=#0000ff][size=2][color=#008000]'To get the Tangent vector to a curve at a given point (StartPt1) example[/color][/size]
[size=2][color=#0000ff]Dim [/color][/size][size=2][color=#000000]VectorTangent1 [/color][/size][size=2][color=#0000ff]As [/color][/size][size=2][color=#000000]AcadNetGeometry.Vector3d = TopCurve.GetFirstDerivative(StartPt1)[/color][/size]
[size=2][color=#008000]'To get the Normal vector (Perp) to the vectorTangent[/color][/size]
[size=2][color=#0000ff]Dim [/color][/size][size=2][color=#000000]VectorNormal1 [/color][/size][size=2][color=#0000ff]as [/color][/size][size=2][color=#000000]AcadNetGeometry.Vector3d = [/color][/size][size=2][color=#0000ff]New [/color][/size][size=2][color=#000000]AcadNetGeometry.Vector3d(-VectorTangent1.Y, VectorTangent1.X, VectorTangent1.Z)[/color][/size]

[/color][/size]


 

If there are any more additions or suggestions please post.

Thanks

Posted

All good stuff. 8)

 

One suggestion regarding this code:

 

'To get the Normal vector (Perp) to the vectorTangent
Dim VectorNormal1 as AcadNetGeometry.Vector3d = New AcadNetGeometry.Vector3d(-VectorTangent1.Y, VectorTangent1.X, VectorTangent1.Z) 

 

I know you mentioned earlier that the focus was mainly on 2d, but with 3d certain situation may return less than ideal result. The most obvious of which would be a case where the tangent vector is aligned with the World Z i.e., 0,0,1. The return would also be 0,0,1

 

In general, I suspect the most useful return from such a query would be a vector perpendicular to the tangent vector, but also lying in the same plane as “TopCurve” (if, indeed, TopCurve is a planar curve). A good approach to satisfy that refinement would be to get the Cross Product of TopCurve.Normal and VectorTangent. See attachment.

 

I suppose to be truly 3d compliant the vector tangent normal would always point to the center of curvature for even non-planar curves. Definitely an extra credit style of problem. :geek:

CrossProduct.dwg

Posted

I suppose I should also point out that my statement:

4. Get angle with System.Math.Atan(Geometry.Vector3d.Y/Geometry.Vector3d.X)

is not particularly 3d compliant. It would return the angle between the X axis and the vector’s projection to the WCS (I guessed that was what you were looking for in your original post). :ouch:

 

The true 3d angle between those two vectors would have to account for the Vector3d.Z component. Vector3d.GetAngleTo Method (X axis as Vector3d).

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...