AB4D Forum

Full Version: TransformTranslate3D newbie question
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I am creating one offset polygon (1 out of 10) correctly and am attempting to draw the other 9 in a circle around the center point. I believe it is creating 10 segments but they are being drawn on top of each other.

I have the TranslateTransform3D function being populated with x and z values that are calculated with a changing angle in a 'for' loop.

Am I going in the right direction?
Thanks for your help.
You have forgotten to multiply x and y radius values by the scale that you are using - the correct code would be ("* mult" was missing):

Code:
double OutRX = 3.804 * mult;
double OutRZ = 3.804 * mult;

Also CreateExtrudedMeshGeometry method requires additional shapeYVector parameter - without that parameter I get exception that shapeYVector and extrudeVectors are parallel. The changed CreateModel3D method looks like:

Code:
private Model3D CreateModel3D()
{
    GeometryModel3D gm = new GeometryModel3D();
    DiffuseMaterial material;
    material = new DiffuseMaterial();
    material.Brush = new SolidColorBrush(Color.FromRgb(39, 126, 147));
    gm.Material = material;

    Vector3D extrudeVector = new Vector3D(0, bdthickness * mult, 0); // direction into which the 2D object will be extrude - in this case UP
    Vector3D shapeYVector = new Vector3D(0, 0, -1); // orientation of Y axis in the shape - in this case Z=-1 => into the monitor
    Vector3D modelOffset = new Vector3D(0, 0, 0);

    gm.Geometry = Mesh3DFactory.CreateExtrudedMeshGeometry(_points, false, modelOffset, extrudeVector, shapeYVector);
    return gm;
}

After that the following objects were created:
[attachment=34]


After that I have see that you also need to rotate the created object.
To do that you can use the RotateTransform3D and AxisAngleRotation3D - for example:

Code:
private void Page_Loaded(object sender, RoutedEventArgs e)
{
    _points = new List<Point>();
    Point point1 = new Point(3.804 * mult, -1.236 * mult);
    Point point2 = new Point(3.804 * mult, 1.236 * mult);
    Point point3 = new Point(2.853 * mult, .927 * mult);
    Point point4 = new Point(2.853 * mult, -.927 * mult);

    _points.Add(point1);
    _points.Add(point2);
    _points.Add(point3);
    _points.Add(point4);

    for (int a = 0; a < 360; a += 36) // 10 segments
    {
        var model3D = CreateModel3D();
        model3D.Transform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), a));

        Group.Children.Add(model3D);
    }
}

This code produces the following result:
[attachment=35]

I hope that this is what you wanted.

The AxisAngleRotation3D rotates around the specified axis - up vector in our case (0,1,0) - and for the specified angle (this time in degrees). The AxisAngleRotation3D is used to create RotateTransform3D that can be set to the Transform property.

The trick in your case is that RotateTransform3D by default rotates around (0,0,0) point (you can also specify any other center of rotation). And because your object is created at the exact position on the "circle" around the (0,0,0), you can simply rotate it around (0,0,0) and you get the other parts.

If your object would be created so that its center would be at (0,0,0), the the RotateTransform3D would rotate it around its own center. In this case you would first need to translate it to the circle (using TranslateTransform3D(radius, 0, 0) and the apply the rotation (you can group two or more transformation with Transform3DGroup).

For example you can quickly check that the objects are not intersecting with applying slight y translation to each part - this can be done with the following code:

Code:
var transform3DGroup = new Transform3DGroup();
transform3DGroup.Children.Add(new TranslateTransform3D(0, a, 0));
transform3DGroup.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), a)));

model3D.Transform = transform3DGroup;
Perfect!. It is just what I was hoping to see and I can't thank you enough for your support and your wonderful library. Having never programmed in 3D and being new to WPF, the learning curve is no less steep than I thought it would be, but I'm already feeling like I'm over the first hump and seeing how all the pieces fit together.

I wonder, though - am I doing the right thing by having a multiplier? If I use actual dimensions, the images I draw are quite small and when I zoom into them, the magnification causes the movements to be very jerky. By multiplying everything by a static number, I can still work with actual calculated dimensions but the images draw at a much larger size and the jerkiness goes away. It's likely a better way to do this, though and if that is the case, it would be great to switch to it now.

Thanks again, Abenedik!
Hm, what do you mean by jerkiness?

I have removed the modifier and it worked well for me - but I needed to lower the initial camera distance.
I just noticed if I had to zoom in a LOT, small movements in my mouse made big movements on the screen. This probably goes away if you start with the camera closer and so that is my question. If the images I want to draw are small (5" - 10"), should I draw them at full size and just use a camera that is close or should I multiply all the dimensions by a factor to start with a larger drawing. I know its all vector graphics and so it really shouldn't matter, but perhaps there is a better way to size the graphics and I'd like to start with your best practices advice.

Thanks!