I'm trying to program for a 4D Quaternion but my compiler shows the following error.
11 C:\Users\user\Downloads\Documents\Fractals\4D fractal simple\4D fractal.cpp wrong number of template arguments (0, should be 1)
What could be the issue?
Here's the code.
#include "Quaternion.h"
#include <iostream>
#include <cmath>
using namespace std;
int main() {
const int N = 100;
const int M = 10;
double delta = 2.0 / M;
Quaternion<> c( -0.63543, 0.172645, 0.172645, 0.0 );
for ( int r = -M; r <= M; ++r ) {
for ( int i = -M; i <= M; ++i ) {
for ( int j = -M; j <= M; ++j ) {
Quaternion<> z0( delta*r, delta*i, delta*j, 0 );
Quaternion<> z = z0;
int n;
for ( n = 0; n < N; ++n ) {
z = sqr(z) + c;
if ( z.norm() > 4 ) {
break;
}
}
if ( n == N ) {
cout << "(" << z0.real() << ","
<< z0.imag_i() << ","
<< z0.imag_j() << ")" << endl;
}
}
}
}
return 0;
}
Header files are here.
//
// C++ Interface: quaternion
//
//* Implementation for a generalized quaternion class *
//* *
//* Written 1.25.00 by Angela Bennett *
// http://ift.tt/21DX0bg
// $Id: quaternion.h,v 1.1 2009/02/09 20:57:20 thernis Exp $
#ifndef STDQUATERNION_H
#define STDQUATERNION_H
#include <iostream>
#include <cmath>
#include "EulerAngles.h"
//! Implementation for a generalized quaternion class, written 1.25.00 by Angela Bennett
template<class _Tp>
class Quaternion
{
public:
//Quaternion
// -default constructor
// -creates a new quaternion with all parts equal to zero
Quaternion(void);
//Quaternion
// -constructor
// -parametes : w, x, y, z elements of the quaternion
// -creates a new quaternion based on the elements passed in
Quaternion(_Tp wi, _Tp xi, _Tp yi, _Tp zi);
//Quaternion
// -constructor
// -parameters : 4D vector
// -creates a new quaternion based on the elements passed in
Quaternion(_Tp v[4]);
//Quaternion
// -copy constructor
// -parameters : const quaternion q
// -creates a new quaternion based on the quaternion passed in
Quaternion(const Quaternion<_Tp>& q);
//Quaternion
// -constructor
// -parameters : yaw, pitch, and roll of an Euler angle
// -creates a new quaternion based on the Euler elements passed in
// -used with Shoemakes code
Quaternion(_Tp e[3], int order);
//~Quaternion
// -default destructor
~Quaternion();
//operator=
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on quaternion q2 sets q2 to be an object of q3
Quaternion<_Tp> operator = (const Quaternion<_Tp>& q);
//operator+
// -parameters : q1 - Quaternion object
// -return value : Quaternion
// -when called on quaternion q2 adds q1 + q2 and returns the sum in a new quaternion
Quaternion<_Tp> operator + (const Quaternion<_Tp>& q);
//operator-
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on q1 subtracts q1 - q2 and returns the difference as a new quaternion
Quaternion<_Tp> operator - (const Quaternion<_Tp>& q);
//operator*
// -parameters : q1 - Quaternion object
// -return values : Quaternion
// -when called on a quaternion q2, multiplies q2 *q1 and returns the product in a new quaternion
Quaternion<_Tp> operator * (const Quaternion<_Tp>& q);
//operator/
// -parameters : q1 and q2- Quaternion objects
// -return values : Quaternion
// -divide q1 by q2 and returns the quotient as q1
Quaternion<_Tp> operator / (Quaternion<_Tp>& q);
//operator+=
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on quaternion q3 adds q1 and q3 and returns the sum as q3
Quaternion<_Tp>& operator += (const Quaternion<_Tp>& q);
//operator-=
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on quaternion q3, subtracts q1 from q3 and returns the difference as q3
Quaternion<_Tp>& operator -= (const Quaternion<_Tp>& q);
//operator*=
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on quaternion q3, multiplies q3 by q1 and returns the product as q3
Quaternion<_Tp>& operator *= (const Quaternion<_Tp>& q);
//operator/=
// -parameters : q1- Quaternion object
// -return values : quaternion
// -when called on quaternion q3, divides q3 by q1 and returns the quotient as q3
Quaternion<_Tp>& operator /= (Quaternion<_Tp>& q);
//operator<<
// -parameters : ostream o, quaternion q
// -return values :
// -prints out a quaternion by it's components
friend inline std::ostream& operator << (std::ostream& output, const Quaternion<_Tp>& q)
{
output << "[" << q.w << ", " << "(" << q.x << ", " << q.y << ", " << q.z << ")]";
return output;
}
//operator!=
// -parameters : q1 and q2- Quaternion objects
// -return value : bool
// -determines if q1 and q2 and equal
bool operator != (const Quaternion<_Tp>& q);
//operator==
// -parameters : q1 and q2- Quaternion objects
// -return value : bool
// -determines if q1 and q2 and equal
bool operator == (const Quaternion<_Tp>& q);
//other methods: norm, inverse, conjugate, toEuler
//norm
// -parameters : none
// -return value : _Tp
// -when called on a quaternion object q, returns the norm of q
_Tp norm();
//magnitude
// -parameters : none
// -return value : _Tp
// -when called on a quaternion object q, returns the magnitude q
_Tp magnitude();
//scale
// -parameters : s- a value to scale q1 by
// -return value: quaternion
// -returns the original quaternion with each part, w,x,y,z, multiplied by some scalar s
Quaternion<_Tp> scale(_Tp s);
//inverse
// -parameters : none
// -return value : quaternion
// -when called on a quaternion object q, returns the inverse of q
Quaternion<_Tp> inverse();
//conjugate
// -parameters : none
// -return value : quaternion
// -when called on a quaternion object q, returns the conjugate of q
Quaternion<_Tp> conjugate();
//UnitQuaternion
// -parameters : none
// -return value : quaternion
// -when called on quaterion q, takes q and returns the unit quaternion of q
Quaternion<_Tp> UnitQuaternion();
// -parameters : 3D vector of type _Tp
// -return value : void
// -when given a 3D vector, v, rotates v by the quaternion
void QuatRotation(_Tp v[3]);
// -parameters : empty 3D vector, rotation order
// -return : void
// - converts this quaternion into Euler angles
void toEuler(_Tp e[3], int order);
private:
// [w, (x, y, z)]
_Tp w, x, y, z;
};
// ----- For linking success, the implementation of a template class
// sould be in the header.
//Quaternion
// -default constructor
// -creates a new quaternion with all parts equal to zero
template<class _Tp>
Quaternion<_Tp>::Quaternion(void)
{
x = 0;
y = 0;
z = 0;
w = 0;
}
//Quaternion
// -constructor
// -parametes : x, y, z, w elements of the quaternion
// -creates a new quaternion based on the elements passed in
template<class _Tp>
Quaternion<_Tp>::Quaternion(_Tp wi, _Tp xi, _Tp yi, _Tp zi)
{
w = wi;
x = xi;
y = yi;
z = zi;
}
//Quaternion
// -constructor
// -parameters : vector/array of four elements
// -creates a new quaternion based on the elements passed in
template<class _Tp>
Quaternion<_Tp>::Quaternion(_Tp v[4])
{
w = v[0];
x = v[1];
y = v[2];
z = v[3];
}
//Quaternion
// -copy constructor
// -parameters : const quaternion q
// -creates a new quaternion based on the quaternion passed in
template<class _Tp>
Quaternion<_Tp>::Quaternion(const Quaternion<_Tp>& q)
{
w = q.w;
x = q.x;
y = q.y;
z = q.z;
}
//Quaternion
// -constructor
// -parameters : yaw, pitch, and roll of an Euler angle
// -creates a new quaternion based on the Euler elements passed in
// -used with Shoemakes code
template<class _Tp>
Quaternion<_Tp>::Quaternion(_Tp e[3], int order)
{
EulerAngles ea;
ea.x = e[0];
ea.y = e[1];
ea.z = e[2];
ea.w = order;
Quat q = Eul_ToQuat(ea);
x = q.x;
y = q.y;
z = q.z;
w = q.w;
}
//~Quaternion
// -destructor
// -deleted dynamically allocated memory
template<class _Tp>
Quaternion<_Tp>::~Quaternion()
{
}
//operator=
// -parameters : q1 - Quaternion object
// -return value : Quaternion
// -when called on quaternion q2 sets q2 to be an object of q3
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::operator = (const Quaternion<_Tp>& q)
{
w = q.w;
x = q.x;
y = q.y;
z = q.z;
return (*this);
}
//operator+
// -parameters : q1 - Quaternion object
// -return value : Quaternion
// -when called on quaternion q2 adds q1 + q2 and returns the sum in a new quaternion
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::operator + (const Quaternion<_Tp>& q)
{
return Quaternion(w+q.w, x+q.x, y+q.y, z+q.z);
}
//operator-
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on q1 subtracts q1 - q2 and returns the difference as a new quaternion
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::operator - (const Quaternion<_Tp>& q)
{
return Quaternion(w-q.w, x-q.x, y-q.y, z-q.z);
}
//operator*
// -parameters : q1 - Quaternion object
// -return values : Quaternion
// -when called on a quaternion q2, multiplies q2 *q1 and returns the product in a new quaternion
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::operator * (const Quaternion<_Tp>& q)
{
return Quaternion(
w*q.w - x*q.x - y*q.y - z*q.z,
w*q.x + x*q.w + y*q.z - z*q.y,
w*q.y + y*q.w + z*q.x - x*q.z,
w*q.z + z*q.w + x*q.y - y*q.x);
}
//operator/
// -parameters : q1 and q2- Quaternion objects
// -return values : Quaternion
// -divide q1 by q2 and returns the quotient q1
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::operator / (Quaternion<_Tp>& q)
{
return ((*this) * (q.inverse()));
}
//operator+=
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on quaternion q3, adds q1 and q3 and returns the sum as q3
template<class _Tp>
Quaternion<_Tp>& Quaternion<_Tp>::operator += (const Quaternion<_Tp>& q)
{
w += q.w;
x += q.x;
y += q.y;
z += q.z;
return (*this);
}
//operator-=
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on quaternion q3, subtracts q1 from q3 and returns the difference as q3
template<class _Tp>
Quaternion<_Tp>& Quaternion<_Tp>::operator -= (const Quaternion<_Tp>& q)
{
w -= q.w;
x -= q.x;
y -= q.y;
z -= q.z;
return (*this);
}
//operator*=
// -parameters : q1- Quaternion object
// -return values : Quaternion
// -when called on quaternion q3, multiplies q3 by q1 and returns the product as q3
template<class _Tp>
Quaternion<_Tp>& Quaternion<_Tp>::operator *= (const Quaternion<_Tp>& q)
{
_Tp w_val = w*q.w - x*q.x - y*q.y - z*q.z;
_Tp x_val = w*q.x + x*q.w + y*q.z - z*q.y;
_Tp y_val = w*q.y + y*q.w + z*q.x - x*q.z;
_Tp z_val = w*q.z + z*q.w + x*q.y - y*q.x;
w = w_val;
x = x_val;
y = y_val;
z = z_val;
return (*this);
}
//operator/=
// -parameters : q1- Quaternion object
// -return values : quaternion
// -when called on quaternion q3, divides q3 by q1 and returns the quotient as q3
template<class _Tp>
Quaternion<_Tp>& Quaternion<_Tp>::operator /= (Quaternion<_Tp>& q)
{
(*this) = (*this)*q.inverse();
return (*this);
}
//operator!=
// -parameters : q1 and q2- Quaternion objects
// -return value : bool
// -determines if q1 and q2 are not equal
template<class _Tp>
bool Quaternion<_Tp>::operator != (const Quaternion<_Tp>& q)
{
return (w!=q.w || x!=q.x || y!=q.y || z!=q.z) ? true : false;
}
//operator==
// -parameters : q1 and q2- Quaternion objects
// -return value : bool
// -determines if q1 and q2 are equal
template<class _Tp>
bool Quaternion<_Tp>::operator == (const Quaternion<_Tp>& q)
{
return (w==q.w && x==q.x && y==q.y && z==q.z) ? true : false;
}
//norm
// -parameters : none
// -return value : _Tp
// -when called on a quaternion object q, returns the norm of q
template<class _Tp>
_Tp Quaternion<_Tp>::norm()
{
return (w*w + x*x + y*y + z*z);
}
//magnitude
// -parameters : none
// -return value : _Tp
// -when called on a quaternion object q, returns the magnitude q
template<class _Tp>
_Tp Quaternion<_Tp>::magnitude()
{
return sqrt(norm());
}
//scale
// -parameters : s- a value to scale q1 by
// -return value: quaternion
// -returns the original quaternion with each part, w,x,y,z, multiplied by some scalar s
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::scale(_Tp s)
{
return Quaternion(w*s, x*s, y*s, z*s);
}
// -parameters : none
// -return value : quaternion
// -when called on a quaternion object q, returns the inverse of q
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::inverse()
{
return conjugate().scale(1/norm());
}
//conjugate
// -parameters : none
// -return value : quaternion
// -when called on a quaternion object q, returns the conjugate of q
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::conjugate()
{
return Quaternion(w, -x, -y, -z);
}
//UnitQuaternion
// -parameters : none
// -return value : quaternion
// -when called on quaterion q, takes q and returns the unit quaternion of q
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::UnitQuaternion()
{
return (*this).scale(1/(*this).magnitude());
}
// -parameters : vector of type _Tp
// -return value : void
// -when given a 3D vector, v, rotates v by this quaternion
template<class _Tp>
void Quaternion<_Tp>::QuatRotation(_Tp v[3])
{
Quaternion <_Tp> qv(0, v[0], v[1], v[2]);
Quaternion <_Tp> qm = (*this) * qv * (*this).inverse();
v[0] = qm.x;
v[1] = qm.y;
v[2] = qm.z;
}
// -parameters : integer order- which will specify the order of the rotation, q- quaternion
// -return value : Euler angle
// -
template<class _Tp>
void Quaternion<_Tp>::toEuler(_Tp e[3], int order)
{
Quat q;
q.w = 0;
q.x = e[0];
q.y = e[1];
q.z = e[2];
EulerAngles ea = Eul_FromQuat(q, order);
w = ea.w;
x = ea.x;
y = ea.y;
z = ea.z;
}
#endif
/*
* $Log: quaternion.h,v $
* Revision 1.1 2009/02/09 20:57:20 thernis
* Put some old code here in case I need that one day...
*
* Revision 1.2 2007/05/14 17:19:41 thernis
* Add CVS id and log in all files
*
*/
AND
/**** EulerAngles.h - Support for 24 angle schemes ****/
/* Ken Shoemake, 1993 */
#ifndef _H_EulerAngles
#define _H_EulerAngles
#include "QuatTypes.h"
/*** Order type constants, constructors, extractors ***/
/* There are 24 possible conventions, designated by: */
/* o EulAxI = axis used initially */
/* o EulPar = parity of axis permutation */
/* o EulRep = repetition of initial axis as last */
/* o EulFrm = frame from which axes are taken */
/* Axes I,J,K will be a permutation of X,Y,Z. */
/* Axis H will be either I or K, depending on EulRep. */
/* Frame S takes axes from initial static frame. */
/* If ord = (AxI=X, Par=Even, Rep=No, Frm=S), then */
/* {a,b,c,ord} means Rz(c)Ry(b)Rx(a), where Rz(c)v */
/* rotates v around Z by c radians. */
#define EulFrmS 0
#define EulFrmR 1
#define EulFrm(ord) ((unsigned)(ord)&1)
#define EulRepNo 0
#define EulRepYes 1
#define EulRep(ord) (((unsigned)(ord)>>1)&1)
#define EulParEven 0
#define EulParOdd 1
#define EulPar(ord) (((unsigned)(ord)>>2)&1)
/* this code is merely a quick (and legal!) way to set arrays, EulSafe being 0,1,2,0 */
#define EulSafe "\000\001\002\000"
#define EulNext "\001\002\000\001"
#define EulAxI(ord) ((int)(EulSafe[(((unsigned)(ord)>>3)&3)]))
#define EulAxJ(ord) ((int)(EulNext[EulAxI(ord)+(EulPar(ord)==EulParOdd)]))
#define EulAxK(ord) ((int)(EulNext[EulAxI(ord)+(EulPar(ord)!=EulParOdd)]))
#define EulAxH(ord) ((EulRep(ord)==EulRepNo)?EulAxK(ord):EulAxI(ord))
/* EulGetOrd unpacks all useful information about order simultaneously. */
#define EulGetOrd(ord,i,j,k,h,n,s,f) {unsigned o=(unsigned)ord;f=o&1;o>>=1;s=o&1;o>>=1;\
n=o&1;o>>=1;i=EulSafe[o&3];j=EulNext[i+n];k=EulNext[i+1-n];h=s?k:i;}
/* EulOrd creates an order value between 0 and 23 from 4-tuple choices. */
#define EulOrd(i,p,r,f) (((((((i)<<1)+(p))<<1)+(r))<<1)+(f))
/* Static axes */
#define EulOrdXYZs EulOrd(X,EulParEven,EulRepNo,EulFrmS)
#define EulOrdXYXs EulOrd(X,EulParEven,EulRepYes,EulFrmS)
#define EulOrdXZYs EulOrd(X,EulParOdd,EulRepNo,EulFrmS)
#define EulOrdXZXs EulOrd(X,EulParOdd,EulRepYes,EulFrmS)
#define EulOrdYZXs EulOrd(Y,EulParEven,EulRepNo,EulFrmS)
#define EulOrdYZYs EulOrd(Y,EulParEven,EulRepYes,EulFrmS)
#define EulOrdYXZs EulOrd(Y,EulParOdd,EulRepNo,EulFrmS)
#define EulOrdYXYs EulOrd(Y,EulParOdd,EulRepYes,EulFrmS)
#define EulOrdZXYs EulOrd(Z,EulParEven,EulRepNo,EulFrmS)
#define EulOrdZXZs EulOrd(Z,EulParEven,EulRepYes,EulFrmS)
#define EulOrdZYXs EulOrd(Z,EulParOdd,EulRepNo,EulFrmS)
#define EulOrdZYZs EulOrd(Z,EulParOdd,EulRepYes,EulFrmS)
/* Rotating axes */
#define EulOrdZYXr EulOrd(X,EulParEven,EulRepNo,EulFrmR)
#define EulOrdXYXr EulOrd(X,EulParEven,EulRepYes,EulFrmR)
#define EulOrdYZXr EulOrd(X,EulParOdd,EulRepNo,EulFrmR)
#define EulOrdXZXr EulOrd(X,EulParOdd,EulRepYes,EulFrmR)
#define EulOrdXZYr EulOrd(Y,EulParEven,EulRepNo,EulFrmR)
#define EulOrdYZYr EulOrd(Y,EulParEven,EulRepYes,EulFrmR)
#define EulOrdZXYr EulOrd(Y,EulParOdd,EulRepNo,EulFrmR)
#define EulOrdYXYr EulOrd(Y,EulParOdd,EulRepYes,EulFrmR)
#define EulOrdYXZr EulOrd(Z,EulParEven,EulRepNo,EulFrmR)
#define EulOrdZXZr EulOrd(Z,EulParEven,EulRepYes,EulFrmR)
#define EulOrdXYZr EulOrd(Z,EulParOdd,EulRepNo,EulFrmR)
#define EulOrdZYZr EulOrd(Z,EulParOdd,EulRepYes,EulFrmR)
EulerAngles Eul_(float ai, float aj, float ah, int order);
Quat Eul_ToQuat(EulerAngles ea);
void Eul_ToHMatrix(EulerAngles ea, HMatrix M);
EulerAngles Eul_FromHMatrix(HMatrix M, int order);
EulerAngles Eul_FromQuat(Quat q, int order);
#endif
AND
/**** QuatTypes.h - Basic type declarations ****/
#ifndef _H_QuatTypes
#define _H_QuatTypes
/*** Definitions ***/
typedef struct {float x, y, z, w;} Quat; /* Quaternion */
enum QuatPart {X, Y, Z, W};
typedef float HMatrix[4][4]; /* Right-handed, for column vectors */
typedef Quat EulerAngles; /* (x,y,z)=ang 1,2,3, w=order code */
#endif
Thanks for your assistance.
Aucun commentaire:
Enregistrer un commentaire