Sunday, January 19, 2025

Rotation of axis in Computer Graphics...

 Rotating the Axes in Computer Graphics refers to transforming the coordinate system itself rather than the objects within the system. This concept is central to understanding rotational transformations, where the axes of the system are rotated to simplify calculations or visualize transformations from a different perspective.


Key Concepts

  1. Rotation of Axes:

    • In a 2D space, rotating the axes involves changing the orientation of the xx- and yy-axes by an angle θ\theta.
    • In a 3D space, you can rotate about one of the principal axes (xx, yy, zz) or around an arbitrary axis.
  2. Transformation Matrices:

    • Rotation transformations use homogeneous coordinate matrices. These matrices apply rotation formulas to either the axes or the points.

2D Rotation of Axes

Formula:

Given a point P(x,y)P(x, y) in the original coordinate system, if the axes are rotated counterclockwise by an angle θ\theta, the new coordinates (x,y)(x', y') of the same point in the rotated system are:

x=xcosθ+ysinθx' = x \cos\theta + y \sin\theta y=xsinθ+ycosθy' = -x \sin\theta + y \cos\theta

Matrix Representation:

[xy]=[cosθsinθsinθcosθ][xy]\begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} \cos\theta & \sin\theta \\ -\sin\theta & \cos\theta \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix}

3D Rotation of Axes

In 3D, rotation involves one of the principal axes:

1. Rotation Around the Z-Axis:

[xyz]=[cosθsinθ0sinθcosθ0001][xyz]\begin{bmatrix} x' \\ y' \\ z' \end{bmatrix} = \begin{bmatrix} \cos\theta & \sin\theta & 0 \\ -\sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ z \end{bmatrix}

2. Rotation Around the X-Axis:

[xyz]=[1000cosθsinθ0sinθcosθ][xyz]\begin{bmatrix} x' \\ y' \\ z' \end{bmatrix} = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\theta & \sin\theta \\ 0 & -\sin\theta & \cos\theta \end{bmatrix} \begin{bmatrix} x \\ y \\ z \end{bmatrix}

3. Rotation Around the Y-Axis:

[xyz]=[cosθ0sinθ010sinθ0cosθ][xyz]\begin{bmatrix} x' \\ y' \\ z' \end{bmatrix} = \begin{bmatrix} \cos\theta & 0 & -\sin\theta \\ 0 & 1 & 0 \\ \sin\theta & 0 & \cos\theta \end{bmatrix} \begin{bmatrix} x \\ y \\ z \end{bmatrix}

Applications

  1. Camera Movements: Changing the view of a 3D scene by rotating the axes.
  2. Animation: Rotating objects and their local axes for complex transformations.
  3. Projection Systems: Adjusting coordinate systems in orthographic and perspective projections.

Example in Computer Graphics:

To rotate an object in a 2D space by 4545^\circ counterclockwise, the rotation matrix is:

[cos45sin45sin45cos45]=[0.7070.7070.7070.707]\begin{bmatrix} \cos 45^\circ & \sin 45^\circ \\ -\sin 45^\circ & \cos 45^\circ \end{bmatrix} = \begin{bmatrix} 0.707 & 0.707 \\ -0.707 & 0.707 \end{bmatrix}

This matrix is applied to all the object's vertices to determine their new coordinates in the rotated system.

Rotating the axes is a foundational concept for understanding object transformations in any graphics system.

And here we go... experimentation of Axis rotation in freeCAD...


And here's the python script for the experimentation using freeCAD.
import FreeCAD
import FreeCADGui
from PySide2 import QtWidgets, QtCore

class AxisRotationApp(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Axis Rotation in FreeCAD")
        self.setGeometry(300, 300, 400, 300)
        
        # UI Layout
        layout = QtWidgets.QVBoxLayout()
        
        # Create Cube Button
        self.create_cube_btn = QtWidgets.QPushButton("Create Cube")
        self.create_cube_btn.clicked.connect(self.create_cube)
        layout.addWidget(self.create_cube_btn)
        
        # Axis Selection
        self.axis_label = QtWidgets.QLabel("Select Axis of Rotation:")
        layout.addWidget(self.axis_label)
        
        self.axis_selector = QtWidgets.QComboBox()
        self.axis_selector.addItems(["X-Axis", "Y-Axis", "Z-Axis"])
        layout.addWidget(self.axis_selector)
        
        # Angle Input
        self.angle_input = QtWidgets.QLineEdit()
        self.angle_input.setPlaceholderText("Enter rotation angle (degrees)")
        layout.addWidget(self.angle_input)
        
        # Apply Rotation Button
        self.apply_rotation_btn = QtWidgets.QPushButton("Apply Rotation")
        self.apply_rotation_btn.clicked.connect(self.apply_rotation)
        layout.addWidget(self.apply_rotation_btn)
        
        # Reset Cube Button
        self.reset_cube_btn = QtWidgets.QPushButton("Reset Cube Position")
        self.reset_cube_btn.clicked.connect(self.reset_position)
        layout.addWidget(self.reset_cube_btn)
        
        self.setLayout(layout)
        self.obj = None  # To store the cube object

    def create_cube(self):
        """Creates a cube in FreeCAD."""
        if not FreeCAD.ActiveDocument:
            FreeCAD.newDocument("AxisRotationDemo")
        else:
            FreeCAD.ActiveDocument.clearAllObjects()
        
        self.obj = FreeCAD.ActiveDocument.addObject("Part::Box", "Cube")
        self.obj.Length = 10
        self.obj.Width = 10
        self.obj.Height = 10
        self.obj.Placement = FreeCAD.Placement()  # Reset placement to default
        FreeCAD.ActiveDocument.recompute()
        QtWidgets.QMessageBox.information(self, "Cube Created", "A cube has been created.")

    def apply_rotation(self):
        """Applies rotation to the cube."""
        if self.obj is None:
            QtWidgets.QMessageBox.warning(self, "Error", "Create a cube first!")
            return
        
        try:
            # Get axis and angle
            axis = self.axis_selector.currentText()
            angle = float(self.angle_input.text())
            
            # Map axis to vector
            if axis == "X-Axis":
                rotation_axis = FreeCAD.Vector(1, 0, 0)
            elif axis == "Y-Axis":
                rotation_axis = FreeCAD.Vector(0, 1, 0)
            elif axis == "Z-Axis":
                rotation_axis = FreeCAD.Vector(0, 0, 1)
            else:
                raise ValueError("Invalid axis selection")
            
            # Apply rotation
            current_placement = self.obj.Placement
            rotation = FreeCAD.Rotation(rotation_axis, angle)
            new_placement = FreeCAD.Placement(
                current_placement.Base,
                rotation.multiply(current_placement.Rotation)
            )
            self.obj.Placement = new_placement
            
            FreeCAD.ActiveDocument.recompute()
            QtWidgets.QMessageBox.information(self, "Success", f"Rotated around {axis} by {angle} degrees.")
        except ValueError:
            QtWidgets.QMessageBox.warning(self, "Invalid Input", "Please enter a valid rotation angle.")

    def reset_position(self):
        """Resets the cube's rotation to the default."""
        if self.obj is None:
            QtWidgets.QMessageBox.warning(self, "Error", "Create a cube first!")
            return
        
        self.obj.Placement = FreeCAD.Placement()  # Reset placement to default
        FreeCAD.ActiveDocument.recompute()
        QtWidgets.QMessageBox.information(self, "Position Reset", "Cube position reset to default.")

# Main function to run the UI
def show_axis_rotation_app():
    # Wrap the widget in a QDockWidget
    app_widget = AxisRotationApp()
    dock_widget = QtWidgets.QDockWidget("Axis Rotation Tool")
    dock_widget.setWidget(app_widget)
    
    # Add the dock widget to FreeCAD's main window
    main_window = FreeCADGui.getMainWindow()
    main_window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, dock_widget)

# Run the application
show_axis_rotation_app()

No comments: