Author Topic: Arcs in 3D space  (Read 3112 times)

0 Members and 1 Guest are viewing this topic.

artisteroi

  • Guest
Arcs in 3D space
« 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.

kpblc

  • Bull Frog
  • Posts: 396
Re: Arcs in 3D space
« Reply #1 on: June 10, 2010, 12:22:52 PM »
Try something like this:
Code: [Select]
(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
Sorry for my English.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Arcs in 3D space
« Reply #2 on: June 10, 2010, 01:08:31 PM »
I think they are looking for a .Net method not LISP
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Arcs in 3D space
« Reply #3 on: June 10, 2010, 01:10:44 PM »
This is VBA, which while not .Net, it at least shows you and example.  I think Bryco wrote this code
Code: [Select]
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

Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Arcs in 3D space
« Reply #4 on: June 10, 2010, 02:43:56 PM »
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);
Speaking English as a French Frog

artisteroi

  • Guest
Re: Arcs in 3D space
« Reply #5 on: June 10, 2010, 04:49:47 PM »

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

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Arcs in 3D space
« Reply #6 on: June 10, 2010, 05:30:18 PM »
Perhaps I misundertand the request, but the following code daws an arc on plane parallel to ZX

Code: [Select]
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();
            }
        }
    }
}
Speaking English as a French Frog

artisteroi

  • Guest
Re: Arcs in 3D space
« Reply #7 on: June 11, 2010, 08:54:01 AM »
That's very different code than I have been using.
I assume  this part

     
Code: [Select]
                    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:
Code: [Select]
                                    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?

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Arcs in 3D space
« Reply #8 on: June 11, 2010, 09:35:32 AM »
Code: [Select]
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)
Speaking English as a French Frog

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Arcs in 3D space
« Reply #9 on: June 11, 2010, 09:45:25 AM »
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);
« Last Edit: June 11, 2010, 10:07:34 AM by Bryco »

artisteroi

  • Guest
Re: Arcs in 3D space
« Reply #10 on: June 11, 2010, 10:24:17 AM »
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.