Author Topic: New point planear to original points  (Read 6522 times)

0 Members and 1 Guest are viewing this topic.

MickD

  • King Gator
  • Posts: 3619
  • (x-in)->[process]->(y-out) ... simples!
Re: New point planear to original points
« Reply #15 on: May 24, 2007, 02:12:54 AM »
I've thought about this a bit further and found something in a previous post in this thread that makes things a bit clearer, I'll try to explain -

problem =
you want to rotate a 3d solid to wcs from any orientation in space, let's say that the edge you use is the length property (it doesn't matter though but if it's an odd shape, you would naturally use the longest 'direction' as the length in this case).
When rotated, let's say you need the L (length direction) to follow the z world axis, this will give you both the x and y axes to extract width and height.

so far so good??

What you will need -

Some vector modification functions such as dot product, cross product, normalisation, add/subtract etc, do a search on vb vector math or similar to find them, they will be done already I guarantee it ;)

A rudementary understanding of using matrices with acad, you will need to be able to set up a matix given 3 vectors(3 sets of doubles, they 'may' need to be normalised) and you need to know how to 'invert' it (reverse/negate it), if acad has a matrix class/method in vba, it will/should have an invert method.

Ok, given that, here's the solution -

1. Get your line/edge as a vector, to do this subtract the end point from the start point (not the other way around!)

2. Next you can use the line's normal, another point of the region or the regions' normal, I'll step out both methods. Either way they both 'should' be perpendicular to the plane of the region.

2a. Using the line or region's normal, get the cross product of the vector from the edge and the normal

zvec = edge.ep - edge.sp
yvec = edge/region.normal
xvec = yvec.cross(zvec)

that should give you three vectors along each x,y,z axis of that plane/region's face with the z vector being along the edge, a y vector normal/perp to plane (in the negative direction I think) and an x vector to the right and perp of z & y.

2b. Using another point of the plane - to do this you will need the 'previous' point before the start point of the edge that you have for L.
From this point, create another vec by subtracting the sp from this previous point, the difference here is we will need to do 2 cross products to make our axes orthoganal (square to each other).

zvex = edge.ep - edge.sp
xvec = prevpnt - edge.sp
yvec = zvec.cross(xvec)

now to square it up, yvec is already square to zvec from performing the cross product but xvec may not necessarilly be square to zvec, nor does it need to be yet but this will fix it.

xvec = yvec.cross(zvec)

this should give you the same result BUT - if the previous point is not to 'the right side' of the edge it may throw the resultant yvec in the other direction, no prob's, just 'negate' it (reverses the direction).
To do this you can get the first 2 vecs from 2b above and perform a dot product to see which side it's on, you may need to experiment but the result will either be +ive or -ive but it's easy to do once you know what you need.

Now, to rotate it to world, create a matrix loading in the numbers of your 3 vec axes into the appropriate matrix columns, get the object and transform it using this matrices 'to world' method or similar, get your data and rotate it back with the original matrix, it should put the object with the L direction along the z axis with the edge sp at 0,0,0 with the region plane along the x axis but you may need to experiment to get it how you like, easy peasy :D

Let's see what you can do with that ;)



"Short cuts make long delays,' argued Pippin.”
J.R.R. Tolkien

DaveW

  • Guest
Re: New point planear to original points
« Reply #16 on: May 24, 2007, 02:45:36 PM »
OMG Mick!!!

That will take me days to do start to get a handle on. I am not going to have any time for a few weeks, but I will give it shot and try to work it through, as I really want to understand. If I take it step by step I think it may help with a few things.

Thanks a bunch for such a detailed post.

DaveW

  • Guest
Re: New point planear to original points
« Reply #17 on: May 24, 2007, 02:47:41 PM »
This is the basics of what i planning on using. It circumvents ACAD's colinear error.

Code: [Select]
Public Sub align()



Dim MyLine As AcadLine
Dim Ent As AcadEntity
Dim LineNormalHold(0 To 2) As Double
Dim FirstPoint(0 To 2) As Double
Dim SecondPoint(0 To 2) As Double
Dim ThirdPoint(0 To 2) As Double

For Each Ent In ThisDrawing.ModelSpace

    If Ent.ObjectName = "AcDbLine" Then
   
       Set MyLine = Ent
       
       LineNormalHold(0) = MyLine.Normal(0)
       LineNormalHold(1) = MyLine.Normal(1)
       LineNormalHold(2) = MyLine.Normal(2)
       
       LineNormalHold(0) = LineNormalHold(0) * MyLine.Length
       LineNormalHold(1) = LineNormalHold(1) * MyLine.Length
       LineNormalHold(2) = LineNormalHold(2) * MyLine.Length
       
       
       FirstPoint(0) = MyLine.StartPoint(0)
       FirstPoint(1) = MyLine.StartPoint(1)
       FirstPoint(2) = MyLine.StartPoint(2)
       
       SecondPoint(0) = MyLine.EndPoint(0)
       SecondPoint(1) = MyLine.EndPoint(1)
       SecondPoint(2) = MyLine.EndPoint(2)
       
       ThirdPoint(0) = LineNormalHold(0)
       ThirdPoint(1) = LineNormalHold(1)
       ThirdPoint(2) = LineNormalHold(2)
       
        ThisDrawing.SendCommand "align "
        ThisDrawing.SendCommand "all  "
       
        ThisDrawing.SendCommand Trim(Str(Round(FirstPoint(0), 12))) & "," & _
                                Trim(Str(Round(FirstPoint(1), 12))) & "," & _
                                Trim(Str(Round(FirstPoint(2), 12))) & " "
        ThisDrawing.SendCommand "0,0,0 "
       
        ThisDrawing.SendCommand Trim(Str(Round(SecondPoint(0), 12))) & "," & _
                                Trim(Str(Round(SecondPoint(1), 12))) & "," & _
                                Trim(Str(Round(SecondPoint(2), 12))) & " "
        ThisDrawing.SendCommand "1000,0,0 "
       
        ThisDrawing.SendCommand Trim(Str(Round(ThirdPoint(0), 12))) & "," & _
                                Trim(Str(Round(ThirdPoint(1), 12))) & "," & _
                                Trim(Str(Round(ThirdPoint(2), 12))) & " "
        ThisDrawing.SendCommand "0,10000,0 "
   
        ThisDrawing.SendCommand "z "
        ThisDrawing.SendCommand "e "
       
        Exit Sub
       
    End If
Next
End Sub

MickD

  • King Gator
  • Posts: 3619
  • (x-in)->[process]->(y-out) ... simples!
Re: New point planear to original points
« Reply #18 on: May 24, 2007, 06:01:12 PM »
I thought about an easier way to explain this and this may help also.

Ok, you have your ucs set to 'world' and you have an object at some place and odd angle in space. You want to convert the object form this place to the world ucs.
If you took a list of every point in the object in wcs they would be exactly as you would expect, now, if you placed your ucs on the object at some place for the origin with the x,y and z axes aligned as you would like them to be if you moved it to wcs, those points would now be different in relation to this new ucs yes?

The difference has everything to do with the coordinate system and the objects reference to it, what we're doing above is getting the objects preferred coordinate system(ucs) and transforming it to wcs but we are also taking all those points (the object) with it, you can move any object, no matter its shape like this and is exactly how a cad system does its MOVE/MIRROR/ROTATE/SCALE and other commands, it takes the current coordinate system and the objects vetices with it and multiply them by another coordinate system to produce a different result for all vertices.
MOVE is easier though as you only need a vector of the sp and end to multiply your vertices with and is much easier than pushing the vertices through a matrix but quite often you 'set' the matrix to translation which is optimised just for this.

Say you wanted to scale a box along the z axis by 2, you have your wcs (x=1,y=1,z=1 where 1 is a normalised length of the axis vector), to transform (scale), if you multiplied all vertices of the object by this ucs you would get the same values back as multiplying each vertex's xyz values by 1 would be the same.
Now, if you multiplied each vertex's xyz values by (x=1,y=1,z=2) respectively you would get the z vertex with a value twice the size as before and would therefore make your object longer along the z axis as a result.

As soon as that sinks in you'll find that rotations and transformations work exactly the same, it's just how you build your matrix.
« Last Edit: May 24, 2007, 06:05:53 PM by MickD »
"Short cuts make long delays,' argued Pippin.”
J.R.R. Tolkien

Bryco

  • Water Moccasin
  • Posts: 1882
Re: New point planear to original points
« Reply #19 on: May 24, 2007, 09:57:54 PM »
Mick what's your take on a line normal?
It appears to be meaningless and trustworthy.
You can give it any value and the line doesn't change.
Whereas circles, ellipses arcs plines etc behave.
I can imagine that a line shouldn't have a normal , but perhaps a normal plane.
I bring it up as 3d vectors are easier to figure out when you disregard the line.normal output.

MickD

  • King Gator
  • Posts: 3619
  • (x-in)->[process]->(y-out) ... simples!
Re: New point planear to original points
« Reply #20 on: May 24, 2007, 10:27:44 PM »
That's why I gave 2 ways to produce the 'normal' using the region's normal or from 3 points (or a plane).
A line's normal from memory, if you draw a line in wcs in the xy plane the lines normal will be in the z direction, now, changing that normal won't change the line in any way which makes sense as a line doesn't have sides. Circles etc have their own plane and that is what you're changing when changing the normal.
Basically, changing a line's normal rotates the line around itself so there appears to be no change but a circle has many points around its insertion and they are rotated around this point so you do see a difference
 
Technically you could argue that a line, being 2d, shouldn't have a normal but it can prove invaluable in cad work. I think acad uses it primarily to distinguish which plane it was drawn in and it therefore gives it an ocs of sorts.

But, as you say, it can be changed and with some 3d stuff I was working on I used to do this intentionally.
An example -
I used to put in 'working' lines in a ucs to prepare the centre line geometry for a steel portal frame say, I would then add 3d solid steel sections to these lines using the lines normal to give the section its correct orientation and direction. If that line was drawn in say a ucs 90 deg different, my section would face the wrong way, I'd then change the normal of the line and reset the section only this time it faces the correct way.
« Last Edit: May 24, 2007, 10:31:42 PM by MickD »
"Short cuts make long delays,' argued Pippin.”
J.R.R. Tolkien

Bryco

  • Water Moccasin
  • Posts: 1882
Re: New point planear to original points
« Reply #21 on: May 24, 2007, 10:39:53 PM »
Good point.