russell84 Posted March 2, 2009 Posted March 2, 2009 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? Quote
CarlB Posted March 2, 2009 Posted March 2, 2009 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 Quote
SEANT Posted March 2, 2009 Posted March 2, 2009 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) Quote
russell84 Posted March 2, 2009 Author Posted March 2, 2009 so how do i calculate what quadrant it is in so that i can calculate the 'Normal to the tangent'.? Quote
Lee Mac Posted March 3, 2009 Posted March 3, 2009 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? Quote
russell84 Posted March 3, 2009 Author Posted March 3, 2009 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] Quote
CarlB Posted March 3, 2009 Posted March 3, 2009 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... Quote
Lee Mac Posted March 3, 2009 Posted March 3, 2009 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. Quote
russell84 Posted March 3, 2009 Author Posted March 3, 2009 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 Quote
russell84 Posted March 3, 2009 Author Posted March 3, 2009 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 Quote
Lee Mac Posted March 3, 2009 Posted March 3, 2009 Ok, glad it works for you Russell - just offering other suggestions Lee Quote
russell84 Posted March 5, 2009 Author Posted March 5, 2009 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 Quote
SEANT Posted March 6, 2009 Posted March 6, 2009 All good stuff. 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. CrossProduct.dwg Quote
SEANT Posted March 6, 2009 Posted March 6, 2009 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). The true 3d angle between those two vectors would have to account for the Vector3d.Z component. Vector3d.GetAngleTo Method (X axis as Vector3d). Quote
Recommended Posts
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.