TheSwamp
Code Red => .NET => Topic started by: artisteroi on June 10, 2010, 10:35:00 AM
-
Does anyone know how to creat an arc in 3D space. By that I mean one that has specific 3d coordinates for it's start and end angles. I have been working on this for a few days but the arcs are ALWAYS drawn in aligment with the world coordinate system. I found some code about transposing the wcs points to the ucs but it doesnt seem to work. Plus I had to use send string to rotate the ucs first. I cant even find the proper code to rotate the ucs. What I want to do is draw the arc on the wall (front view) as I am looking at the floor (top view). Anyone? Seems like it should be simple but I can't find it.
-
Try something like this:
(entmakex (list (cons 0 "ARC")
(cons 10 '(10. 10. 0.))
(cons 40 2.5)
(cons 50 0.)
(cons 51 1.)
(cons 210 '(0. -1. 1.))
) ;_ end of list
) ;_ end of entmakex
-
I think they are looking for a .Net method not LISP
-
This is VBA, which while not .Net, it at least shows you and example. I think Bryco wrote this code
Option Explicit
Public Declare Function GetAsyncKeyState Lib "user32" _
(ByVal vKey As Long) As Integer
Public Const VK_ESCAPE = &H1B
Public Const VK_LBUTTON = &H1
Public Function GetPointEX(Optional vPoint As Variant, _
Optional strPrmt As Variant = vbCrLf & "Select point: ") As Variant
Dim objTemp As AcadEntity
Dim objUtil As AcadUtility
Dim varPnt As Variant
Dim UcsPt As Variant
Dim varCancel As Variant
On Error GoTo Err_Control
Set objUtil = ThisDrawing.Utility
If IsMissing(vPoint) Then
varPnt = objUtil.GetPoint(Prompt:=strPrmt)
Else
UcsPt = ThisDrawing.Utility.TranslateCoordinates(vPoint, acWorld, acUCS, False)
varPnt = objUtil.GetPoint(UcsPt, strPrmt)
End If
GetPointEX = varPnt
Exit_Here:
Exit Function
Err_Control:
Select Case Err.Number
Case -2147352567
If GetAsyncKeyState(VK_ESCAPE) > 0 Then
Err.Clear
Resume Exit_Here
ElseIf GetAsyncKeyState(VK_LBUTTON) > 0 Then
Err.Clear
Resume
Else
Err.Clear
Resume Exit_Here
End If
Case -2145320928
'Right click or 'Enter'
'You could use InitializeUserInput to allow
'Keywords, but in this example we just exit
Err.Clear
Resume Exit_Here
Case "13", "-2147024809" 'Invalid argument Point in GetPoint
Err.Clear
Resume Exit_Here
Case Else
'MsgBox Err.Description
'Debug.Print Err.Description, Err.Number
Resume Exit_Here
End Select
End Function
Sub PolyArc3d()
Dim P1, P2, P3
Dim MidP(2) As Double
Dim dHt As Double, dBulge As Double '
Dim dist As Double
Dim oPline As AcadLWPolyline
Dim N As Variant
Dim dElev As Double
Dim Pts(3) As Double
Dim util As AcadUtility
Set util = ThisDrawing.Utility
P1 = GetPointEX
P2 = GetPointEX(P1)
dHt = ThisDrawing.Utility.GetDistance(, vbCrLf + "Type the height:")
MidP(0) = P1(0) + 0.5 * (P2(0) - P1(0))
MidP(1) = P1(1) + 0.5 * (P2(1) - P1(1))
MidP(2) = P1(2) + 0.5 * (P2(2) - P1(2))
dist = Length(P1, MidP)
MidP(2) = MidP(2) + dHt
P3 = MidP
N = NormalFromPoints(P1, P2, P3)
P1 = util.TranslateCoordinates(P1, acWorld, acOCS, False, N)
P2 = util.TranslateCoordinates(P2, acWorld, acOCS, False, N)
P3 = util.TranslateCoordinates(P3, acWorld, acOCS, False, N)
dElev = P1(2)
dBulge = Tan(dHt / dist)
Pts(0) = P1(0): Pts(1) = P1(1)
Pts(2) = P2(0): Pts(3) = P2(1)
Set oPline = ThisDrawing.ModelSpace.AddLightWeightPolyline(Pts)
oPline.SetBulge 0, -dBulge
oPline.Elevation = dElev
oPline.Normal = N
oPline.ConstantWidth = 0
End Sub
Public Function Length(Startpoint As Variant, Endpoint As Variant) As Double
Dim Stx As Double, Sty As Double, Stz As Double
Dim Enx As Double, Eny As Double, Enz As Double
Dim dX As Double, dY As Double, dZ As Double
Dim i As Integer
If IsEmpty(Startpoint) Then Err.Raise 13
i = UBound(Startpoint)
If UBound(Endpoint) = i Then
If i > 0 Then
Stx = Startpoint(0): Sty = Startpoint(1)
Enx = Endpoint(0): Eny = Endpoint(1)
dX = Stx - Enx
dY = Sty - Eny
If i = 1 Then
Length = Sqr(dX * dX + dY * dY)
Else
Stz = Startpoint(2): Enz = Endpoint(2)
dZ = Stz - Enz
Length = Sqr((dX * dX) + (dY * dY) + (dZ * dZ))
End If
Else
Exit Function
End If
Else
Exit Function
End If
End Function
Function NormalFromPoints(P0, P1, P2) As Variant
'n = u×v = (V1-V0)×(V2-V0)
Dim X1 As Double, X2 As Double
Dim Y1 As Double, Y2 As Double
Dim Z1 As Double, Z2 As Double
Dim Unit As Double
Dim x(2) As Double
Dim y(2) As Double
Dim N(2) As Double
'Get distance from zero
x(0) = P1(0) - P0(0): y(0) = P2(0) - P0(0)
x(1) = P1(1) - P0(1): y(1) = P2(1) - P0(1)
x(2) = P1(2) - P0(2): y(2) = P2(2) - P0(2)
'get CrossProduct
N(0) = x(1) * y(2) - x(2) * y(1)
N(1) = x(2) * y(0) - x(0) * y(2)
N(2) = x(0) * y(1) - x(1) * y(0)
'Convert to unit normal
Unit = Sqr(N(0) * N(0) + N(1) * N(1) + N(2) * N(2))
N(0) = N(0) / Unit: N(1) = N(1) / Unit: N(2) = N(2) / Unit
NormalFromPoints = N
End Function
-
Hi,
The Arc class have a constructor which allows to do it directly (as in the LISP shown upper:
Arc(Point3d center, Vector3d normal, Double radius, Double startAngle, Double endAngle);
-
That code only writes on wcs unless we are missing something. And the vba code won't work on 64 bit machines. Anybody got any C#. That would be best
-
Perhaps I misundertand the request, but the following code daws an arc on plane parallel to ZX
using System;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
namespace Gile.ArcTest
{
public class Class1
{
[CommandMethod("Test")]
public void Test()
{
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Arc a = new Arc(
new Point3d(10.0,20.0,30.0),
new Vector3d(0.0,-1.0,0.0),
10.0,
0.0,
Math.PI);
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
btr.AppendEntity(a);
tr.AddNewlyCreatedDBObject(a, true);
tr.Commit();
}
}
}
}
-
That's very different code than I have been using.
I assume this part
Arc a = new Arc(
new Point3d(10.0,20.0,30.0),
new Vector3d(0.0,-1.0,0.0),
10.0,
0.0,
is the arc parameters? Is that correct? The code I had been using had the center point (xyz) the radius, start and end angles. Yours seems to have the start point, vector, and radius. It works great, I just have my database set up to pull different data. I don't really want to re-write my whole database. Would you mind taking a look at this code:
Point3d PlacePointFull = new Point3d(PlacePointX, PlacePointY, PlacePointZ);
//Transform these World Coordinates to UCS:
Matrix3d matUCS = ED.CurrentUserCoordinateSystem.Inverse();
Point3d wcsPoint = PlacePointFull.TransformBy(matUCS);
Double StartAngleFull = Start * Math.PI / 180;
Double EndAngleFull = End * Math.PI / 180;
Arc ThisLine = new Arc(PlacePointFull, Radius, StartAngleFull, EndAngleFull);
//ThisLine.TransformBy(ED.CurrentUserCoordinateSystem);
ThisLine.TransformBy(ED.CurrentUserCoordinateSystem.Transpose());
//Into Model Space:
newBtr.AppendEntity(ThisLine);
Trans.AddNewlyCreatedDBObject(ThisLine, true);
This is what we use to make an arc. It pulls 6 parameters from a database: center x , y , z ; radius; start angle; end angle. It is supposed to trasnform the wcs points to the current ucs so the arc will be in the front alignment. But we can't get it to work. What do you think?
-
Arc a = new Arc(
new Point3d(10.0,20.0,30.0), // Center (WCS coordinates)
new Vector3d(0.0,-1.0,0.0), // Normal vector (WCS coordinates)
10.0, // Radius
0.0, // StartAngle (radians)
Math.PI); // EndAngle (radians)
-
artisteroi, you dont want to both transform the center point and transform the arc.
The 2 ways are
1)Insert on 0,0 w/ the vector (normal) being the zaxis of the current ucs then giving it a new center that is the transformed centerpoint
2) Insert at original centerpoint and transform the arc
ThisLine.TransformBy(ED.CurrentUserCoordinateSystem);
-
Gile did give me the right info with the addition of a 3D vector point. We have been able to make it work. I am sorry I didn't understand your code. There was no commenting. I was taught to always comment the code so if someone has to come behind you they will be able to tell what you did regardless of how complex it is. I guess people don't think that way anymore, or are just going so fast there isn't time to comment it.
Oh well it seems to be working now. Thanks for the help.