⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 complex.h

📁 一个纹理地形渲染器
💻 H
字号:
// Complex number class

#pragma once

#include <stdio.h>
#include "Float.h"


namespace Mathematics
{
    /// A complex number.
    /// z = Re(z) + i Im(z).

    class Complex
    {
    public:

        /// default constructor.
        /// does nothing for speed.

        Complex() {};

        /// construct a complex number with real component and no imaginary component.

	    Complex(float real)
	    {
		    x = real;
		    y = 0;
	    }

        /// construct a complex number with real component x, imaginary component y.

        Complex(float x, float y)
        {
            this->x = x;
            this->y = y;
        }

        /// construct complex number from polar coordinates.
        /// @param modulus the length of the complex number
        /// @argument the angle anti-clockwise from the positive real axis in radians.

	    void polar(float modulus, float argument)
	    {
		    x = modulus * Float::cos(argument);
		    y = modulus * Float::sin(argument);
	    }

        /// set the complex number to identity.
        /// @post x=1, y=0.

	    void identity()
	    {
		    x = 1;
		    y = 0;
	    }

        /// negate the complex number

	    void negate()
	    {
		    x = -x;
		    y = -y;
	    }

        /// add another complex number to this number

        void add(const Complex &complex)
        {
            x += complex.x;
            y += complex.y;
        }

        /// subtract another complex number from this number

        void subtract(const Vector &complex)
        {
            x -= complex.x;
            y -= complex.y;
        }

        /// multiply this complex number by a scalar

        void multiply(float scalar)
        {
            x *= scalar;
            y *= scalar;
        }

        /// divide this number by a scalar

	    void divide(float scalar)
	    {
		    assert(scalar!=0);
		    const float inv = 1.0f / scalar;
		    x *= inv;
		    y *= inv;
	    }

        /// calculate modulus.
        /// note: requires sqrt!

        float modulus() const
        {
		    return Float::sqrt(x*x + y*y);
        }

        /// calculate modulus squared

        float modulus_squared() const
        {
            return x*x + y*y;
        }

        /// normalize complex number.
        /// @post modulus=1.

        Complex& normalize()
        {
            const float magnitude = Float::sqrt(x*x + y*y);
            if (magnitude>Float::epsilon)
            {
                const float scale = 1.0f / magnitude;
                x *= scale;
                y *= scale;
            }
		    return *this;
        }

        /// return a normalized complex number in the same direction as this number.

	    Complex normal() const
	    {
		    Complex complex;
            const float magnitude = Float::sqrt(x*x + y*y);
            if (magnitude>Float::epsilon)
            {
                const float scale = 1.0f / magnitude;
                complex.x *= scale;
                complex.y *= scale;
            }
		    else
		    {
			    complex = *this;
		    }
		    return complex;
	    }

        /// test if this complex number is normalized

	    bool normalized() const
	    {
		    return Float::equal(modulus(),1);
	    }

        /// invert complex number.
        /// note: the inverse of a complex number can be used to perform complex division.

	    Complex& invert()
	    {
		    const float magnitude_squared = x*x + y*y;
		    if (magnitude_squared>Float::epsilon_squared)
		    {
			    const float inverse_magnitude_squared = 1.0f / magnitude_squared;
			    x *= inverse_magnitude_squared;
			    y *= -inverse_magnitude_squared;
		    }
		    return *this;
	    }

        /// return inverse of complex number.

	    Complex inverse() const
	    {
		    Complex complex;
		    const float magnitude_squared = x*x + y*y;
            if (magnitude_squared>Float::epsilon_squared)
            {
			    const float inverse_magnitude_squared = 1.0f / magnitude_squared;
                complex.x = x * inverse_magnitude_squared;
                complex.y = -y * inverse_magnitude_squared;
            }
		    else
		    {
			    complex = *this;
		    }
		    return complex;
	    }

        /// tests if this complex number is invertible

	    bool invertible() const
	    {
		    const float magnitude_squared = x*x + y*y;
            return magnitude_squared>Float::epsilon_squared;
	    }

        /// return conjugate of this complex number

	    Complex conjugate() const
	    {
		    return Complex(x, -y);
	    }

        /// get the real component

	    float real() const
	    {
		    return x;
	    }

        /// get the imaginary component

	    float imaginary() const
	    {
		    return y;
	    }

        /// calculate the argument.
        /// note: this is the angle measured counter-clockwise from the positive real axis in radians.

	    float argument() const
	    {
		    return (float) atan2(y,x);
	    }

        /// equals operator

	    bool operator ==(const Complex &other) const
	    {
		    if (Float::equal(x,other.x) && Float::equal(y,other.y)) return true;
		    else return false;
	    }

        /// not equals operator

	    bool operator !=(const Complex &other) const
	    {
		    return !(*this==other);
	    }

        /// print a basic text representation of complex number to stdout.

	    void print() const
	    {
		    printf("Complex[%f, %f]\n", x, y);
	    }

	    friend inline Complex operator-(const Complex &a);
	    friend inline Complex operator+(const Complex &a, const Complex &b);
	    friend inline Complex operator-(const Complex &a, const Complex &b);
	    friend inline Complex operator*(const Complex &a, const Complex &b);
	    friend inline Complex operator/(const Complex &a, const Complex &b);
	    friend inline Complex& operator+=(Complex &a, const Complex &b);
	    friend inline Complex& operator-=(Complex &a, const Complex &b);
	    friend inline Complex& operator*=(Complex &a, const Complex &b);
	    friend inline Complex& operator/=(Complex &a, const Complex &b);

	    friend inline Complex operator*(const Complex &a, float s);
	    friend inline Complex operator/(const Complex &a, float s);
	    friend inline Complex& operator*=(Complex &a, float s);
	    friend inline Complex& operator/=(Complex &a, float s);
	    friend inline Complex operator*(float s, const Complex &a);
	    friend inline Complex& operator*=(float s, Complex &a);

        float x;        ///< real component
        float y;        ///< imaginary component
    };


    inline Complex operator-(const Complex &a)
    {
	    return Complex(-a.x, -a.y);
    }

    inline Complex operator+(const Complex &a, const Complex &b)
    {
	    return Complex(a.x+b.x, a.y+b.y);
    }

    inline Complex operator-(const Complex &a, const Complex &b)
    {
	    return Complex(a.x-b.x, a.y-b.y);
    }

    inline Complex operator*(const Complex &a, const Complex &b)
    {
	    return Complex(a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x);
    }

    inline Complex operator/(const Complex &a, const Complex &b)
    {
	    return a * b.inverse();		// this should be optimized!
    }

    inline Complex& operator+=(Complex &a, const Complex &b)
    {
	    a.x += b.x;
	    a.y += b.y;
	    return a;
    }

    inline Complex& operator-=(Complex &a, const Complex &b)
    {
	    a.x -= b.x;
	    a.y -= b.y;
	    return a;
    }

    inline Complex& operator*=(Complex &a, const Complex &b)
    {
        const float cx = a.x*b.x - a.y*b.y;
        const float cy = a.x*b.y + a.y*b.x;
	    a.x = cx;
	    a.y = cy;
	    return a;
    }

    inline Complex& operator/=(Complex &a, const Complex &b)
    {
	    a /= b.inverse();			// this should be optimized!
	    return a;
    }

    inline Complex operator*(const Complex &a, float s)
    {
	    return Complex(a.x*s, a.y*s);
    }

    inline Complex operator/(const Complex &a, float s)
    {
	    assert(s!=0);
	    return Complex(a.x/s, a.y/s);
    }

    inline Complex& operator*=(Complex &a, float s)
    {
	    a.x *= s;
	    a.y *= s;
	    return a;
    }

    inline Complex& operator/=(Complex &a, float s)
    {
	    assert(s!=0);
	    a.x /= s;
	    a.y /= s;
	    return a;
    }

    inline Complex operator*(float s, const Complex &a)
    {
	    return Complex(a.x*s, a.y*s);
    }

    inline Complex& operator*=(float s, Complex &a)
    {
	    a.x *= s;
	    a.y *= s;
	    return a;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -