private void OrientedArrow() { //Create an arrow. vtkArrowSource arrowSource = vtkArrowSource.New(); // Generate a random start and end point vtkMath.RandomSeed(8775070); double[] startPoint = new double[] { vtkMath.Random(-10, 10), vtkMath.Random(-10, 10), vtkMath.Random(-10, 10) }; double[] endPoint = new double[] { vtkMath.Random(-10, 10), vtkMath.Random(-10, 10), vtkMath.Random(-10, 10) }; // Compute a basis double[] normalizedX = new double[3]; double[] normalizedY = new double[3]; double[] normalizedZ = new double[3]; // The X axis is a vector from start to end myMath.Subtract(endPoint, startPoint, ref normalizedX); double length = myMath.Norm(normalizedX); myMath.Normalize(ref normalizedX); // The Z axis is an arbitrary vector cross X double[] arbitrary = new double[] { vtkMath.Random(-10, 10), vtkMath.Random(-10, 10), vtkMath.Random(-10, 10) }; myMath.Cross(normalizedX, arbitrary, ref normalizedZ); myMath.Normalize(ref normalizedZ); // The Y axis is Z cross X myMath.Cross(normalizedZ, normalizedX, ref normalizedY); vtkMatrix4x4 matrix = vtkMatrix4x4.New(); // Create the direction cosine matrix matrix.Identity(); for (int i = 0; i < 3; i++) { matrix.SetElement(i, 0, normalizedX[i]); matrix.SetElement(i, 1, normalizedY[i]); matrix.SetElement(i, 2, normalizedZ[i]); } // Apply the transforms vtkTransform transform = vtkTransform.New(); transform.Translate(startPoint[0], startPoint[1], startPoint[2]); transform.Concatenate(matrix); transform.Scale(length, length, length); //Create a mapper and actor for the arrow vtkPolyDataMapper mapper = vtkPolyDataMapper.New(); vtkActor actor = vtkActor.New(); #if USER_MATRIX mapper.SetInputConnection(arrowSource.GetOutputPort()); actor.SetUserMatrix(transform.GetMatrix()); #else // Transform the polydata vtkTransformPolyDataFilter transformPD = vtkTransformPolyDataFilter.New(); transformPD.SetTransform(transform); transformPD.SetInputConnection(arrowSource.GetOutputPort()); mapper.SetInputConnection(transformPD.GetOutputPort()); #endif actor.SetMapper(mapper); // Create spheres for start and end point vtkSphereSource sphereStartSource = vtkSphereSource.New(); sphereStartSource.SetCenter(startPoint[0], startPoint[1], startPoint[2]); vtkPolyDataMapper sphereStartMapper = vtkPolyDataMapper.New(); sphereStartMapper.SetInputConnection(sphereStartSource.GetOutputPort()); vtkActor sphereStart = vtkActor.New(); sphereStart.SetMapper(sphereStartMapper); sphereStart.GetProperty().SetColor(1.0, 1.0, .3); vtkSphereSource sphereEndSource = vtkSphereSource.New(); sphereEndSource.SetCenter(endPoint[0], endPoint[1], endPoint[2]); vtkPolyDataMapper sphereEndMapper = vtkPolyDataMapper.New(); sphereEndMapper.SetInputConnection(sphereEndSource.GetOutputPort()); vtkActor sphereEnd = vtkActor.New(); sphereEnd.SetMapper(sphereEndMapper); sphereEnd.GetProperty().SetColor(1.0, .3, .3); vtkRenderWindow renderWindow = myRenderWindowControl.RenderWindow; vtkRenderer renderer = renderWindow.GetRenderers().GetFirstRenderer(); renderer.SetBackground(0.2, 0.3, 0.4); renderer.AddActor(actor); renderer.AddActor(sphereStart); renderer.AddActor(sphereEnd); renderer.ResetCamera(); }
public void UpdatePosition(double[] endPoint, double[] startPoint) { double[] normalizedX = new double[3]; double[] normalizedY = new double[3]; double[] normalizedZ = new double[3]; // The X axis is a vector from start to end Subtract(endPoint, startPoint, normalizedX); double length = Math.Sqrt(normalizedX[0] * normalizedX[0] + normalizedX[1] * normalizedX[1] + normalizedX[2] * normalizedX[2]); //Console.WriteLine(@"length = " + length); normalizedX = VTKUtil.Normalize(normalizedX); // The Z axis is an arbitrary vecotr cross X double[] arbitrary = new double[3]; arbitrary[0] = vtkMath.Random(-10, 10); arbitrary[1] = vtkMath.Random(-10, 10); arbitrary[2] = vtkMath.Random(-10, 10); arbitrary = VTKUtil.Normalize(arbitrary); // TODO FIX ME normalizedZ = VTKUtil.Cross(normalizedX, arbitrary); //vtkMath.Cross(VTKUtil.ConvertIntPtr(normalizedX), VTKUtil.ConvertIntPtr(arbitrary), VTKUtil.ConvertIntPtr(normalizedZ)); //vtkMath.Normalize(VTKUtil.ConvertIntPtr(normalizedZ)); // The Y axis is Z cross X // TODO FIX ME //vtkMath.Cross(VTKUtil.ConvertIntPtr(normalizedZ), VTKUtil.ConvertIntPtr(normalizedX), VTKUtil.ConvertIntPtr(normalizedY)); normalizedY = VTKUtil.Cross(normalizedX, normalizedZ); vtkMatrix4x4 matrix = vtkMatrix4x4.New(); // Create the direction cosine matrix matrix.Identity(); for (int i = 0; i < 3; i++) { matrix.SetElement(i, 0, normalizedX[i]); matrix.SetElement(i, 1, normalizedY[i]); matrix.SetElement(i, 2, normalizedZ[i]); } //Console.WriteLine(matrix); // Apply the transforms vtkTransform transform = vtkTransform.New(); transform.Translate(VTKUtil.ConvertIntPtr(startPoint)); transform.Concatenate(matrix); //length = 500; transform.Scale(length, length, length); // Transform the polydata //vtkTransformPolyDataFilter transformPD = new vtkTransformPolyDataFilter(); //transformPD.SetTransform(transform); //transformPD.SetInputConnection(_arrowSource.GetOutputPort()); _arrowSource.SetTipRadius(0.25); _arrowSource.SetTipLength(0.7); _arrowSource.Update(); _mapper.SetInput(_arrowSource.GetOutput()); _arrowActor.SetUserMatrix(transform.GetMatrix()); _arrowActor.GetProperty().ShadingOn(); _arrowActor.GetProperty().SetAmbient(0.7); _arrowActor.GetProperty().SetOpacity(0.4); _arrowActor.SetMapper(_mapper); }