This version makes public some matrix and vector classes, with whose help you could fit nodes within the view as shown below.
https://mindfusion.eu/_beta/fcnet_matrix.zipThe method moves the camera backwards iteratively until all nodes fit. Our developer will try to implement something more precise for the next release.
void Fit3D()
{
diagramView3D.PointCameraTo(CenterPoint());
while (!Fits())
{
MoveCameraForward(-1);
diagramView3D.ResetProjection();
}
}
bool Fits()
{
foreach (DiagramNode node in diagram.Nodes)
{
Rectangle rect = diagramView3D.GetProjectionRect(node);
if (!diagramView3D.ClientRectangle.Contains(rect))
return false;
}
return true;
}
Point3D CenterPoint()
{
if (diagram.Nodes.Count == 0)
return new Point3D();
Point3D center = new Point3D();
foreach (DiagramNode node in diagram.Nodes)
{
Point3D p = (Point3D)node.LayoutTraits[View3D.Position];
center.X += p.X;
center.Y += p.Y;
center.Z += p.Z;
}
center.X /= diagram.Nodes.Count;
center.Y /= diagram.Nodes.Count;
center.Z /= diagram.Nodes.Count;
return center;
}
private void MoveCameraForward(float dz)
{
Matrix3D cameraRotationMatrix = GetRotationMatrix();
if (cameraRotationMatrix == null)
return;
Vector3D v = new Vector3D(0, 0, dz);
Vector3D r = cameraRotationMatrix.Invert() * v;
Point3D cameraPosition = diagramView3D.CameraPosition;
cameraPosition.X += (float)r.X;
cameraPosition.Y += (float)r.Y;
cameraPosition.Z += (float)r.Z;
diagramView3D.CameraPosition = cameraPosition;
}
Matrix3D GetRotationMatrix()
{
Point3D cameraRotation = diagramView3D.CameraRotation;
double[] t = new double[3];
t[0] = (Math.PI / (180 / cameraRotation.X));
t[1] = (Math.PI / (180 / cameraRotation.Y));
t[2] = (Math.PI / (180 / cameraRotation.Z));
return
new Matrix3D(1, 0, 0, 0, Math.Cos(-t[0]), Math.Sin(-t[0]), 0, -Math.Sin(-t[0]), Math.Cos(-t[0])) *
new Matrix3D(Math.Cos(-t[1]), 0, -Math.Sin(-t[1]), 0, 1, 0, Math.Sin(-t[1]), 0, Math.Cos(-t[1])) *
new Matrix3D(Math.Cos(-t[2]), Math.Sin(-t[2]), 0, -Math.Sin(-t[2]), Math.Cos(-t[2]), 0, 0, 0, 1);
}
I hope that helps,
Stoyan