Author Topic: Math - 3D Solid Challenge  (Read 7017 times)

0 Members and 1 Guest are viewing this topic.

CmdrDuh

  • Automatic Duh Generator
  • King Gator
  • Posts: 4039
Re: Math - 3D Solid Challenge
« Reply #15 on: January 29, 2008, 04:53:37 PM »
Thats what I thought, but google didn't even know
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

CmdrDuh

  • Automatic Duh Generator
  • King Gator
  • Posts: 4039
Re: Math - 3D Solid Challenge
« Reply #16 on: January 29, 2008, 04:53:58 PM »
what about the fact that the centerlines are off of the center of the upper part?
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

Cathy

  • Bull Frog
  • Posts: 251
Re: Math - 3D Solid Challenge
« Reply #17 on: January 29, 2008, 05:04:44 PM »
Would putting some workpoints in your blocks help with some of this?  Like a point where the CLs cross, points where the pipes connect?

IRT -- odd I always use WRT (with respect to).  Is that just a difference is Aussie English and American English?  Or is just a difference in disciplines? 

CmdrDuh

  • Automatic Duh Generator
  • King Gator
  • Posts: 4039
Re: Math - 3D Solid Challenge
« Reply #18 on: January 29, 2008, 05:08:15 PM »
I was thinking of calcing the workpoint in code, and then moving down and to the left/right from there to start the line.  If you look at the first pic, you can see some cross's inside the pipe, that is the start/stop point for the vertical anlge of pipe
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

MickD

  • Gator
  • Posts: 3314
  • (x-in)->[process]->(y-out)
Re: Math - 3D Solid Challenge
« Reply #19 on: January 29, 2008, 05:15:56 PM »
>>what about the fact that the centerlines are off of the center of the upper part?

The angle is still the same so I'd translate the pipe 11/16 to the left and the bottom T the amount of the offset from insert point to the left, repeat on right side.

I'd have a go at this but I'm busy with something else at the moment but here's the steps I would take using the math I posted earlier -

Calc the pipe lengths and pnt1 on the left side
Insert the top pipe at origin
Insert the left bottom T at pnt1 and translate it the offset amount to the left
Extrude the pipe, translate it to the origin and the angle then translate it left the top T offset amount
(and along the line a bit if needed to clear cross pipe as it's shorter than the actual line length)
Copy and mirror over top T c.l. for right side.

If I get time later I'll code something up.
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

CmdrDuh

  • Automatic Duh Generator
  • King Gator
  • Posts: 4039
Re: Math - 3D Solid Challenge
« Reply #20 on: January 29, 2008, 05:22:00 PM »
thanks
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

Bryco

  • Water Moccasin
  • Posts: 1849
Re: Math - 3D Solid Challenge
« Reply #21 on: January 30, 2008, 10:55:23 AM »
I had some success with below code.
To the apex bock I added 2 regions on defpoints that are positiioned where you have the lines.
These regions are copied from the block itself then tranlated to the blockrefs position.
Then extruded.

Code: [Select]
Sub Cmd()

    Dim Ent As AcadEntity
    Dim B As AcadBlock
    Dim Br As AcadBlockReference
    Dim P, m, Ret
    Dim Ms As AcadBlock
    Dim Obj(0) As Object
    Dim C1 As AcadCircle, C2 As AcadCircle
    Dim R1 As AcadRegion
    Dim sBlock As String
    Dim Dist As Double, Ht As Double
    Dim Util As AcadUtility
   
    Set Util = ThisDrawing.Utility
    Set Ms = ThisDrawing.ModelSpace
    sBlock = "5020760"
    Util.GetEntity Ent, P, "Pick the 5020"
    If Not TypeOf Ent Is AcadBlockReference Then Exit Sub
    If Not Ent.Name = sBlock Then Exit Sub
    Set Br = Ent
    Set B = ThisDrawing.Blocks(sBlock)
    For Each Ent In B
        If TypeOf Ent Is AcadRegion Then
        Set Obj(0) = Ent
            Ret = ThisDrawing.CopyObjects(Obj, Ms)
            Set R1 = Ret(0)
            R1.Layer = "0"
            R1.Color = 2
            Exit For
        End If
    Next Ent
    Dist = Util.GetDistance(, "Centerline distance")
    If Dist < 17.0855 Then
        MsgBox ("Distance must be larger than 17")
        Exit Sub
    End If
    Ht = (Dist - 17.0855) / Cos(15 / 180 * PI) + 4
    m = BlockRefMatrix(Br)
    m = InverseMatrix(m)

    R1.TransformBy (m)
    Dim Tube As Acad3DSolid
    Set Tube = Ms.AddExtrudedSolid(R1, Ht, 0)
   
End Sub



Function BlockRefMatrix(oBref As AcadBlockReference) As Variant

    Dim V, m(3, 3) As Double, M1, M2
    Dim j As Integer
    Dim X, Y, Z, ins
    Dim Rot As Double
   
    Rot = oBref.Rotation
    Z = oBref.Normal
    V = GetOcsFromNormal(Z)
    X = V(0): Y = V(1)
    PrintP X
    PrintP Y
    ins = oBref.InsertionPoint
   
    M1 = RotZ(-Rot)
    For j = 0 To 2
        m(0, j) = X(j)
        m(1, j) = Y(j)
        m(2, j) = Z(j)
    Next j
    m(0, 3) = -ins(0): m(1, 3) = -ins(1): m(2, 3) = -ins(2)
    m(3, 3) = 1
    'PrintM M
    If Rot = 0 Then
        BlockRefMatrix = m
    Else
        M2 = M4xM4(m, M1)
        PrintM M2
        BlockRefMatrix = M2
    End If
   
   
   
End Function

MickD

  • Gator
  • Posts: 3314
  • (x-in)->[process]->(y-out)
Re: Math - 3D Solid Challenge
« Reply #22 on: January 30, 2008, 05:44:32 PM »
I had some success with below code.
To the apex bock I added 2 regions on defpoints that are positiioned where you have the lines.
These regions are copied from the block itself then tranlated to the blockrefs position.
Then extruded.

Great idea Bryco! saves quite a bit of matrix mojo. Perhaps you can put the other bottom blocks in as well as nested in the correct alignment then just translate it along the line vector the given amount after calc'ing with the new height?
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

Bryco

  • Water Moccasin
  • Posts: 1849
Re: Math - 3D Solid Challenge
« Reply #23 on: January 30, 2008, 08:07:38 PM »
I haven't done much coding for the creation and editing of 3d objects so I tried a circle first, only to find a cylinder doesn't follow a path.
So yes the region saves a bit of matricising (Pres. Bush speak).
After an hour I thought I would have the hard part whooped but alas the correct matrix is eluding me for the funky blocks. (Dang it). Works for the blocks rotated in the same plane.
Mick, I think straight vector math will establish the insertion point of the other blocks and when that is translated using the same magical matrix David can say "Bob's me uncle"

MickD

  • Gator
  • Posts: 3314
  • (x-in)->[process]->(y-out)
Re: Math - 3D Solid Challenge
« Reply #24 on: January 30, 2008, 08:12:53 PM »
Do you mean to rotate the bottom T or to mirror it?

To create a mirror matrix you should be able to just negate some the vectors for axes and translation and transformBy.
If you are mirroring over the y axis, negate the x vector for example.

if it's the rotation of the blocks perhaps setting them up in the block drg in the correct location/orientation for simple insert (create a block for left and right say).
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

MickD

  • Gator
  • Posts: 3314
  • (x-in)->[process]->(y-out)
Re: Math - 3D Solid Challenge
« Reply #25 on: January 30, 2008, 08:36:21 PM »
It's even easier, I just noticed that ent's have a Mirror3d method. that may help.
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

MickD

  • Gator
  • Posts: 3314
  • (x-in)->[process]->(y-out)
Re: Math - 3D Solid Challenge
« Reply #26 on: January 30, 2008, 09:52:48 PM »
This is what I'm thinking -
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

Bryco

  • Water Moccasin
  • Posts: 1849
Re: Math - 3D Solid Challenge
« Reply #27 on: January 31, 2008, 12:27:43 AM »
This works, finally. David the last part is mirror3d as Mick suggests.
Transpose rather than inverse threw for a while as usual (More brains reqd.)
There is a weird variety of math used here, but they all relate to normals somewhere.
Code: [Select]
Option Explicit
Const PI As Double = 3.14159265358979


Sub Dav()

    Dim Ent As AcadEntity
    Dim B As AcadBlock
    Dim Br As AcadBlockReference
    Dim P, M, M1, Ret
    Dim Ms As AcadBlock
    Dim Obj(0) As Object
    Dim C1 As AcadCircle, C2 As AcadCircle
    Dim R1 As AcadRegion
    Dim sBlock As String
    Dim Dist As Double, Ht As Double
    Dim Util As AcadUtility
    Dim Zero(2) As Double
   
   
    Set Util = ThisDrawing.Utility
    Set Ms = ThisDrawing.ModelSpace
    sBlock = "5020760"
    Util.GetEntity Ent, P, "Pick the 5020"
    If Not TypeOf Ent Is AcadBlockReference Then Exit Sub
    If Not Ent.Name = sBlock Then Exit Sub
    Set Br = Ent
    Set B = ThisDrawing.Blocks(sBlock)
    For Each Ent In B
        If TypeOf Ent Is AcadRegion Then
        Set Obj(0) = Ent
            Ret = ThisDrawing.CopyObjects(Obj, Ms)
            Set R1 = Ret(0)
            R1.Layer = "0"
            R1.color = 2
            Exit For
        End If
    Next Ent
    Dist = Util.GetDistance(, "Centerline distance")
    If Dist < 17.0855 Then
        MsgBox ("Distance must be larger than 17")
        Exit Sub
    End If
    Ht = (Dist - 17.0855) / Cos(15 / 180 * PI) + 4
    M = BlockRefMatrix(Br)

    M1 = Transpose(M)
    R1.TransformBy (M1)
    Dim Tube As Acad3DSolid
    Set Tube = Ms.AddExtrudedSolid(R1, Ht, 0)
    R1.Delete
   
    Dim width As Double
    Dim inspt(2) As Double
    Dim Br2 As AcadBlockReference
   
    width = (Tan(15 / 180 * PI) * (Dist - 17.0855)) + 4.0682
    inspt(1) = -width: inspt(2) = -Dist
   

    P = TransformPt2(M1, inspt)
    Set Br2 = Ms.InsertBlock(Zero, "5141714", 1, 1, 1, 0)
    Br2.Normal = Br.Normal
    Br2.Rotation = Br.Rotation
    Br2.Move Zero, P
   
End Sub









Function BlockRefMatrix(oBref As AcadBlockReference) As Variant

    Dim V, M(3, 3) As Double, M1, M2
    Dim j As Integer
    Dim X, Y, Z, ins
    Dim Rot As Double
   
    Rot = oBref.Rotation
    Z = oBref.Normal
    V = GetOcsFromNormal(Z)
    X = V(0): Y = V(1)

    ins = oBref.InsertionPoint
   
    M1 = RotZ(-Rot)
    For j = 0 To 2
        M(0, j) = X(j)
        M(1, j) = Y(j)
        M(2, j) = Z(j)
        M(3, j) = ins(j)
    Next j
    M(3, 3) = 1

    If Rot = 0 Then
        BlockRefMatrix = M
    Else
        M2 = M4xM4(M, M1)
        BlockRefMatrix = M2
    End If
   
   
End Function






Function Transpose(Matrix As Variant) As Variant

    Dim iCnt As Integer, jCnt As Integer
    Dim transMat(0 To 3, 0 To 3) As Double
    Dim I As Integer, j As Integer
    iCnt = UBound(Matrix, 1)
    jCnt = UBound(Matrix, 2)
    For I = 0 To iCnt
        For j = 0 To jCnt
            transMat(I, j) = Matrix(j, I)
        Next j
    Next I
    Transpose = transMat
   
End Function



Function TransformPt2(M As Variant, P1 As Variant) As Variant
    Dim I As Integer
    Dim X As Double, Y As Double, Z As Double, d As Double
    Dim P(3) As Double
    Dim P2(2) As Double
    For I = 0 To 2
        P(I) = P1(I)
    Next
    P(3) = 1
   
    For I = 0 To 3
        X = X + P(I) * M(0, I)
        Y = Y + P(I) * M(1, I)
        Z = Z + P(I) * M(2, I)
        d = d + P(I) * M(3, I)
    Next
    P2(0) = X: P2(1) = Y: P2(2) = Z
    TransformPt2 = P2

End Function



Function GetOcsFromNormal(N As Variant) As Variant
    'Arbitrary Axis Algorithm in dxf help
    'N is the normal vector.
    'Wy is the world Y axis, which is always (0,1,0).
    'Wz is the world Z axis, which is always (0,0,1).
    Dim Wy(2) As Double
    Dim Wz(2) As Double
    Dim Nx As Double, Ny As Double
    Dim Ax, Ay, Ocs(1) As Variant
   
    N = NormaliseVector(N)
    Wy(0) = 0: Wy(1) = 1: Wy(2) = 0
    Wz(0) = 0: Wz(1) = 0: Wz(2) = 1
    Nx = N(0): Ny = N(1)
    If (Abs(Nx) < 1 / 64) And (Abs(Ny) < 1 / 64) Then
         'Ax = Wy X N (where “X” is the cross-product operator).
         Ax = Crossproduct(Wy, N)
    Else
         Ax = Crossproduct(Wz, N)
    End If
    Ocs(0) = Ax
 
    Ay = Crossproduct(N, Ax)
    Ocs(1) = Ay
    GetOcsFromNormal = Ocs

End Function



Function RotZ(Ang As Double) As Variant
   'Rotate by an angle around the z axis
    Dim M
    Dim CosAng As Double, sinAng As Double
   
    CosAng = Cos(Ang): sinAng = Sin(Ang)
    M = IDMatrix
    M(0, 0) = CosAng
    M(0, 1) = -sinAng
    M(1, 0) = sinAng
    M(1, 1) = CosAng
     
    RotZ = M

End Function


Function M4xM4(M1, M2) As Variant
    'Matrix x matrix
    Dim M(3, 3) As Double
    Dim I As Integer, j As Integer
    Dim k As Integer
    Dim Sum As Double
   
    For I = 0 To 3
        For j = 0 To 3
            For k = 0 To 3
                Sum = Sum + M1(k, j) * M2(I, k)
            Next k
            M(I, j) = Sum
            Sum = 0
        Next j
    Next I
    M4xM4 = M
   
End Function


Function NormaliseVector(V As Variant) As Variant
    Dim Unit As Double
    Dim Vn(2) As Double
    Unit = Sqr(V(0) * V(0) + V(1) * V(1) + V(2) * V(2))
    Vn(0) = V(0) / Unit: Vn(1) = V(1) / Unit: Vn(2) = V(2) / Unit
    NormaliseVector = Vn
End Function


Function Crossproduct(A, B) As Variant

    Dim Ax As Double, Ay As Double, Az As Double
    Dim Bx As Double, By As Double, Bz As Double
    Dim Unit As Double
    Dim c(2) As Double
    'get CrossProduct
    Ax = A(0): Ay = A(1): Az = A(2)
    Bx = B(0): By = B(1): Bz = B(2)
   
    c(0) = Ay * Bz - Az * By
    c(1) = Az * Bx - Ax * Bz
    c(2) = Ax * By - Ay * Bx
   
    'Convert to unit normal
    Unit = Sqr(c(0) * c(0) + c(1) * c(1) + c(2) * c(2))
    c(0) = c(0) / Unit: c(1) = c(1) / Unit: c(2) = c(2) / Unit
    Crossproduct = c

End Function



Function IDMatrix()
    Dim M(3, 3) As Double
    Dim I As Integer, j As Integer
    M(0, 0) = 1
    M(1, 1) = 1
    M(2, 2) = 1
    M(3, 3) = 1
    IDMatrix = M
   
End Function

Bryco

  • Water Moccasin
  • Posts: 1849
Re: Math - 3D Solid Challenge
« Reply #28 on: January 31, 2008, 12:39:12 AM »
Test dwg.

SEANT

  • Bull Frog
  • Posts: 332
Re: Math - 3D Solid Challenge
« Reply #29 on: January 31, 2008, 07:02:10 AM »
Excellent work once again gentlemen.  A word of caution; if you persist in this development of “one click design creation”, managers may do the work themselves and figure they need CAD techs no longer. :-)

Bryco, I see you’ve expanded the scope of the project to include “other’world’ly” alignments – certainly a welcome inclusion for those of us with chaotic structures.  The one recommendation I would make for dealing with these non-aligned setups, like the block in CmdrduhTest.dwg @ (99.9462, 265.5402, 0.4912), is to switch order of operation from:

Br2.Normal = Br.Normal
Br2.Rotation = Br.Rotation

To:

Br2.Rotation = Br.Rotation 
Br2.Normal = Br.Normal
   
Sean Tessier
AutoCAD 2016 Mechanical