matlab面向對象編程的基本知識---聲明與繼承、構造函數、成員變量、成員函數、訪問權限等

classdef quaternion < handle
    % 四元數 qa qx qy qz
    
    properties
        data = zeros(4, 1);%列向量
    end
    
    methods %普通函數塊--開始
        function obj = quaternion(varargin)
            % 構造函數,支持“4x1向量” 、“1x4向量”、“4個單變量axyz”進行構造 
            % q=[qa qx qy qz]
            if 1 == nargin
                arg = varargin{1};
                obj.data(1) = arg(1); 
                obj.data(2) = arg(2); 
                obj.data(3) = arg(3); 
                obj.data(4) = arg(4); 
            elseif 4 == nargin
                obj.data(1) = varargin{1};
                obj.data(2) = varargin{2};
                obj.data(3) = varargin{3};
                obj.data(4) = varargin{4};
            else
                %error('quaternion類 僅支持“4x1向量” 、“1x4向量”、“4個單變量axyz”進行構造');%注意,轉C語言時,不要出現打印語句
            end
        end
        
        function [] = setValue(obj, in4x1)
            %賦值
            obj.data = in4x1;            
        end
        
        function [] = set.data(obj, in4x1)
            %賦值,當寫出q.data = xxxx;語句時,該函數會被自動調用,一般可用於右值合法檢測
            obj.data = in4x1;    
            %disp('quaternion set.data is called');
        end
        
        
        function [] = normalize(obj)
            %把本四元數歸一化
            obj.data = obj.data / norm(obj.data);            
        end
        
        function res = mtimes(q1, q2)
            % 乘法*運算符重載
            p = [ q1.data(1) -q1.data(2) -q1.data(3) -q1.data(4);
                  q1.data(2)  q1.data(1) -q1.data(4)  q1.data(3);
                  q1.data(3)  q1.data(4)  q1.data(1) -q1.data(2);
                  q1.data(4) -q1.data(3)  q1.data(2)  q1.data(1)] ...
              * [ q2.data(1)  q2.data(2)  q2.data(3)  q2.data(4)]';
            res = quaternion(p(1), p(2), p(3), p(4));
        end        
       
        function [ret] = rotateVec(obj, vec)
            %四元數對三維向量進行旋轉,注意,請保證輸入的q爲單位四元數
            %形參:默認本類的對象q,要被旋轉的三維向量vec(行列均可)
            %返回三維列向量
            qv = quaternion(0, vec(1), vec(2), vec(3)); %[0 vec(1) vec(2) vec(3)]';
            qi = conjugate(obj);            
            qvqi = obj * qv * qi;
            ret = [qvqi.data(2) qvqi.data(3) qvqi.data(4)]';
        end   
       
    end %普通函數塊--結束    
    
    
    methods(Static) %靜態函數塊---開始
        %這裏寫靜態函數
    end %靜態函數塊---結束       
        
        
    
end %類定義結束

以上給出了簡單的幾個示例,挨個說明:

1、類聲明與繼承

聲明形如 classdef quaternion < handle,其中<代表繼承handle類,
若繼承多個類,可寫成形如:classdef quaternion < base1 & base2 &base3

這裏繼承的handle需要強調一下,matlab有兩個超類,handle和value,關於這兩者的區別,請自行搜索學習,一般我們自己寫的類都要繼承者=這兩者之一。

2、構造函數

構造函數與類名同名,必須有一個返回值,返回值的名稱必須是obj,由於matlab不支持函數重載,因此只能有一個構造函數,不過我們可以通過可變參數表變相近似實現以下構造函數的重載,varargin這是matlab內置的形參,代表輸入的參數數目是可變的,在函數內部可通過nargin來判斷實參的數目(number of argument input),來區別不同的實參。這一技巧也可用在普通的函數中。

3、成員變量

如例子所示,被    properties      xxxxx     end標籤包裹的部分爲成員變量。

在成員函數中訪問成員變量,必須要加obj.前綴(需要注意的是,這個前綴並不固定是obj,這取決於成員函數第一參的命名),示例代碼中的很多成員函數已經展示瞭如何讀寫成員變量。

4、無參成員函數

無參函數指的是在調用時無參,一般聲明和定義函數時,matlab默認把第一參數當做this指針,所以,幾乎的成員函數都至少帶有一個形參。第一參數的名字可隨意取,一般慣例是取做obj,但不是絕對的,例如例子中重載的乘法運算符,我把第一參取名爲q1,也是可以的。

上例中,normalize函數有一個形參obj,但在調用時是無參的:

q= quaternion([1 2 3 4]');
q.normalize();
disp(q.data');%結果爲:    0.1826    0.3651    0.5477    0.7303

5、有參成員函數

真正的參數是從第二個參數開始的,例如例子中的rotateVec函數,聲明時他有兩個參數,但在調用時,只有一個參數,因爲真正的第一參被隱式用作this指針了。

q= quaternion([0.1826    0.3651    0.5477    0.7303]');
q.rotateVec([1 2 3]);

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章