According to my suggestion I modified the code from the Link you are refering to.

Here is my Solution : I build a Control which has the Behaviour that allows to rotate a cube with/by the Mouse-Movement.

VB

Imports System.Drawing.Graphics Public Class RotatingCube Inherits Control Protected m_vertices(8) As Point3D Protected m_faces(6, 4) As Integer Protected m_colors(6) As Color Protected m_brushes(6) As Brush Sub New() ' Enable double-buffering to eliminate flickering. Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True) Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True) ' Create the cube vertices. m_vertices = New Point3D() { New Point3D(-1, 1, -1), New Point3D(1, 1, -1), New Point3D(1, -1, -1), New Point3D(-1, -1, -1), New Point3D(-1, 1, 1), New Point3D(1, 1, 1), New Point3D(1, -1, 1), New Point3D(-1, -1, 1)} ' Create an array representing the 6 faces of a cube. Each face is composed by indices to the vertex array ' above. m_faces = New Integer(,) {{0, 1, 2, 3}, {1, 5, 6, 2}, {5, 4, 7, 6}, {4, 0, 3, 7}, {0, 4, 5, 1}, {3, 2, 6, 7}} ' Define the colors of each face. m_colors = New Color() {Color.BlueViolet, Color.Cyan, Color.Green, Color.Yellow, Color.Violet, Color.LightSkyBlue} ' Create the brushes to draw each face. Brushes are used to draw filled polygons. For i = 0 To 5 m_brushes(i) = New SolidBrush(m_colors(i)) Next End Sub Property xAngle As Integer Get Return my_xAngle End Get Set(value As Integer) my_xAngle = (value + 360) Mod 360 Me.Invalidate() End Set End Property Private my_xAngle As Integer Property yAngle As Integer Get Return my_yAngle End Get Set(value As Integer) my_yAngle = (value + 360) Mod 360 Me.Invalidate() End Set End Property Private my_yAngle As Integer Property zAngle As Integer Get Return my_zAngle End Get Set(value As Integer) my_zAngle = (value + 360) Mod 360 Me.Invalidate() End Set End Property Private my_zAngle As Integer Protected Overrides Sub OnMouseDown(e As System.Windows.Forms.MouseEventArgs) If e.Button = Windows.Forms.MouseButtons.Left Then MousePress = True MousePosLast = e.Location End If MyBase.OnMouseDown(e) End Sub Private MousePress As Boolean = False Protected Overrides Sub OnMouseUp(e As System.Windows.Forms.MouseEventArgs) MousePress = False MyBase.OnMouseUp(e) End Sub Protected Overrides Sub OnMouseMove(e As System.Windows.Forms.MouseEventArgs) If MousePress Then MouseMoveHorizontal = MousePosLast.X - e.X MouseMoveVertical = MousePosLast.Y - e.Y MousePosLast = e.Location Dim xxAngle As Integer = (xAngle + 360) Mod 180 Dim yyAngle As Integer = (yAngle + 360) Mod 180 If (yyAngle > 135) Or (yyAngle <= 45) Then yAngle += MouseMoveHorizontal xAngle -= MouseMoveVertical Else xxAngle = (xAngle + 360) Mod 180 If (xxAngle > 135) Or (xxAngle <= 45) Then yAngle += MouseMoveHorizontal xAngle -= MouseMoveVertical Else xAngle += MouseMoveHorizontal yAngle -= MouseMoveVertical End If End If Me.Invalidate() End If MyBase.OnMouseMove(e) End Sub Private MouseMoveVertical As Integer = 0 Private MouseMoveHorizontal As Integer = 0 Private MousePosLast As Point Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs) Dim t(8) As Point3D Dim f(4) As Integer Dim v As Point3D Dim avgZ(6) As Double Dim order(6) As Integer Dim tmp As Double Dim iMax As Integer ' Clear the window e.Graphics.Clear(Color.LightBlue) ' Transform all the points and store them on the "t" array. For i = 0 To 7 Dim b As Brush = New SolidBrush(Color.White) v = m_vertices(i) t(i) = v.RotateX(xAngle).RotateY(yAngle).RotateZ(zAngle) t(i) = t(i).Project(Me.ClientSize.Width, Me.ClientSize.Height, 256, 4) Next ' Compute the average Z value of each face. For i = 0 To 5 avgZ(i) = (t(m_faces(i, 0)).Z + t(m_faces(i, 1)).Z + t(m_faces(i, 2)).Z + t(m_faces(i, 3)).Z) / 4.0 order(i) = i Next ' Next we sort the faces in descending order based on the Z value. ' The objective is to draw distant faces first. This is called ' the PAINTERS ALGORITHM. So, the visible faces will hide the invisible ones. ' The sorting algorithm used is the SELECTION SORT. For i = 0 To 4 iMax = i For j = i + 1 To 5 If avgZ(j) > avgZ(iMax) Then iMax = j End If Next If iMax <> i Then tmp = avgZ(i) avgZ(i) = avgZ(iMax) avgZ(iMax) = tmp tmp = order(i) order(i) = order(iMax) order(iMax) = tmp End If Next ' Draw the faces using the PAINTERS ALGORITHM (distant faces first, closer faces last). For i = 0 To 5 Dim points() As Point Dim index As Integer = order(i) points = New Point() { New Point(CInt(t(m_faces(index, 0)).X), CInt(t(m_faces(index, 0)).Y)), New Point(CInt(t(m_faces(index, 1)).X), CInt(t(m_faces(index, 1)).Y)), New Point(CInt(t(m_faces(index, 2)).X), CInt(t(m_faces(index, 2)).Y)), New Point(CInt(t(m_faces(index, 3)).X), CInt(t(m_faces(index, 3)).Y)) } e.Graphics.FillPolygon(m_brushes(index), points) Next MyBase.OnPaint(e) End Sub End Class

VB

Public Class Point3D Protected m_x As Double, m_y As Double, m_z As Double Public Sub New(ByVal x As Double, ByVal y As Double, ByVal z As Double) Me.X = x Me.Y = y Me.Z = z End Sub Public Property X() As Double Get Return m_x End Get Set(ByVal value As Double) m_x = value End Set End Property Public Property Y() As Double Get Return m_y End Get Set(ByVal value As Double) m_y = value End Set End Property Public Property Z() As Double Get Return m_z End Get Set(ByVal value As Double) m_z = value End Set End Property Public Function RotateX(ByVal angle As Integer) As Point3D Dim rad As Double, cosa As Double, sina As Double, yn As Double, zn As Double rad = angle * Math.PI / 180 cosa = Math.Cos(rad) sina = Math.Sin(rad) yn = Me.Y * cosa - Me.Z * sina zn = Me.Y * sina + Me.Z * cosa Return New Point3D(Me.X, yn, zn) End Function Public Function RotateY(ByVal angle As Integer) As Point3D Dim rad As Double, cosa As Double, sina As Double, Xn As Double, Zn As Double rad = angle * Math.PI / 180 cosa = Math.Cos(rad) sina = Math.Sin(rad) Zn = Me.Z * cosa - Me.X * sina Xn = Me.Z * sina + Me.X * cosa Return New Point3D(Xn, Me.Y, Zn) End Function Public Function RotateZ(ByVal angle As Integer) As Point3D Dim rad As Double, cosa As Double, sina As Double, Xn As Double, Yn As Double rad = angle * Math.PI / 180 cosa = Math.Cos(rad) sina = Math.Sin(rad) Xn = Me.X * cosa - Me.Y * sina Yn = Me.X * sina + Me.Y * cosa Return New Point3D(Xn, Yn, Me.Z) End Function Public Function Project(ByVal viewWidth, ByVal viewHeight, ByVal fov, ByVal viewDistance) Dim factor As Double, Xn As Double, Yn As Double factor = fov / (viewDistance + Me.Z) Xn = Me.X * factor + viewWidth / 2 Yn = Me.Y * factor + viewHeight / 2 Return New Point3D(Xn, Yn, Me.Z) End Function End Class

Good luck, my friend!

You want to create a 3D-Vector, corresponding to a Centerpoint on the Screen, with the Mouse ?

At which point do you stuck ?

Your code-snippet doesn't show me anything about your issue ...

You should see it different :

- you have one centerpoint and one base-vector for your calculation

- your mouse-movement only allows you to detect it's x- and y-movement. If you want to rotate your calculated vector results on this movement. When moving horizontal you rotate the vector around the y-axis. When moving vertical you rotate around the x-axis. Depending on each movement you will get a new vector which is the base for your next movement. Only with this vector you can do the rotation/roll calculation and finally you could draw that.

I don't believe that Scale-Translate-Transform is very helpful for this ...

I think that only relative transforming could not bring the right result ...

In your question you refered to a link - I think (but I don't tried it by myself) this is working in the same way ...

Could I determine the relative axis by which axis are pointing highest & lower direction. This way I will be altering only 2 axis which can controlled by mouse movement.

example:- If Z axis is pointing up most then the vertical roll would change & X axis is pointing down most then the horizontal roll should be used. Also the mid axis unaffected.

Would this work & give me the desired affect??

You could also say (and I would try which is the best behaviour) if Z is pointing up-down and X is pointing left-right the up-down movement from the Mouse rotates the Z/Y-axis around the X-axis and the left-right movement from the Mouse rotates the X/Y-axis around the Z-axis.

A "little bit" difficulter could it be if one (or more) axis are allready diagonal - in this case you should rotate the remaining vector to the movement around the other remaining vector. It could be the best if you paint the vector for yourself on a piece of paper (for example) - I think that could be become clearer.

But for your information : I never have done this before but if necessary I would start like this. Your project sounds very interesting for me ...

I have had another thought but i may need some help with the math.

If you take the start point as well as the mouse move point & back calculate the 3D point back to axis. This would give you the appearance of moving the start point on screen as a roll. This may come up with more than one answer but we could filter this by closest angle previous.

Do you think this is a way that is possible or a long shot?

The bit that keeps me trying is that it must be possible as other application manage to do it.

Because it is interesting for me too I will try to make own experiments.

What I first would do is : rotate depending on the Mouse-Movement around the vertical/horizontal axises.

I will give you an reply when I have a result ...

When you have a base-point (x=0,y=0,z=0) you could have to angles for the vector : angle from x0 into y-direction and angle from x0 into z-direction. Both angle could be modified by your mouse : x_to_y with the vertical movement and x_to_z by the horizontal movement. You should define an increment/decrement for each of those angles corresponding to the real mouse-movement.

This would be my 1st step to start. I would realize that inside a special control (which derives from Control) to keep the code "clean".

I can get the 2D angles (As viewed on screen after conversion) & direction from converting points let say 50 from the origin point. Then calculating the angle using Math.Atan2 but this is where I get a bit lost & how to convert to X-Z & X-Y. Sorry

Z|

| /Y

|/

-----X

So, if you have it like this X2Y and X2Z both are 0°.

If you rotate X counterclockwise then X will become Z after 90° or -Z after 90° clockwise.

Same with X and Y.

But actually I don't have a calculation for that (not enough time - sorry).

Getting there & maybe I should of asked for help along time ago but I was just going try to figure it for myself. maybe I should not tried for over a year.

If you have any more ideas to solve these issue just shout.

Many thanks