src/types.h

Fri, 10 May 2013 17:39:56 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Fri, 10 May 2013 17:39:56 +0300
changeset 189
ac2d3e8dd110
parent 188
4e686b771996
child 191
9bb6a17305ad
permissions
-rw-r--r--

Rewrote the string class with a simpler version. The old one was more than probably leaking water like a boat with an elephant on board...

/*
 *  LDForge: LDraw parts authoring CAD
 *  Copyright (C) 2013 Santeri Piippo
 *  
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef TYPES_H
#define TYPES_H

#include "common.h"
#include "misc.h"

typedef unsigned int uint;
typedef unsigned short ushort;
typedef unsigned long ulong;

// Typedef out the _t suffices :)
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;

template<class T> using initlist = std::initializer_list<T>;
using std::vector;

enum Axis { X, Y, Z };
static const Axis g_Axes[3] = {X, Y, Z};

// =============================================================================
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// =============================================================================
// matrix
// 
// A templated, mathematical N x N matrix
// =============================================================================
template<int N> class matrix {
public:
	// Constructors
	matrix () {}
	matrix (initlist<double> vals) {
		assert (vals.size() == N * N);
		memcpy (&m_vals[0], &(*vals.begin ()), sizeof m_vals);
	}
	
	matrix (double fillval) {
		for (short i = 0; i < (N * N); ++i)
			m_vals[i] = fillval;
	}
	
	matrix (double vals[]) {
		for (short i = 0; i < (N * N); ++i)
			m_vals[i] = vals[i];
	}
	
	template<int M> matrix (matrix<M> other) {
		assert (M >= N);
		
		for (short i = 0; i < M; ++i)
		for (short j = 0; j < M; ++j) {
			const short idx = (i * M) + j;
			m_vals[idx] = other[idx];
		}
	}
	
	matrix<N> mult (matrix<N> other) {
		matrix val;
		val.zero ();

		for (short i = 0; i < N; ++i)
		for (short j = 0; j < N; ++j)
		for (short k = 0; k < N; ++k)
			val[(i * N) + j] += m_vals[(i * N) + k] * other[(k * N) + j];

		return val;
	}
	
	matrix<N>& operator= (matrix<N> other) {
		memcpy (&m_vals[0], &other.m_vals[0], sizeof (double) * N * N);
		return *this;
	}
	
	matrix<N> operator* (matrix<N> other) {
		return mult (other);
	}
	
	double& operator[] (const uint idx) {
		return m_vals[idx];
	}
	
	const double& operator[] (const uint idx) const {
		return m_vals[idx];
	}
	
	void zero () {
		memset (&m_vals[0], 0, sizeof (double) * N * N);
	}
	
	void puts () const {
		for (short i = 0; i < N; ++i) {
			for (short j = 0; j < N; ++j)
				printf ("%*f\t", 10, m_vals[(i * N) + j]);
			
			printf ("\n");
		}
	}
	
	str stringRep () const {
		str val;
		for (short i = 0; i < N * N; ++i) {
			if (i > 0)
				val += ' ';
			
			val += fmt ("%s", ftoa (m_vals[i]).chars());
		}
		
		return val;	
	}

private:
	double m_vals[N * N];
};

// =============================================================================
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// =============================================================================
// vertex
// 
// Vertex class, contains a single point in 3D space. Not to be confused with
// LDVertex, which is a vertex used in an LDraw part file.
// =============================================================================
class vertex {
public:
	double m_coords[3];
	
	vertex () {}
	vertex (double x, double y, double z) {
		m_coords[X] = x;
		m_coords[Y] = y;
		m_coords[Z] = z;
	}
	
	void move (vertex other) {
		for (const Axis ax : g_Axes)
			m_coords[ax] += other[ax];
	}
	
	vertex& operator+= (vertex other) {
		move (other);
		return *this;
	}
	
	vertex operator/ (const double d) const {
		vertex other (*this);
		return other /= d;
	}
	
	vertex& operator/= (const double d) {
		for (const Axis ax : g_Axes)
			m_coords[ax] /= d;
		return *this;
	}
	
	bool operator== (const vertex& other) const {
		return coord (X) == other[X] &&
			coord (Y) == other[Y] &&
			coord (Z) == other[Z];
	}
	
	bool operator!= (const vertex& other) const {
		return !operator== (other);
	}
	
	vertex operator- () const {
		return vertex (-m_coords[X], -m_coords[Y], -m_coords[Z]);
	}
	
	double& coord (const ushort n) {
		return m_coords[n];
	}
	
	const double& coord (const ushort n) const {
		return m_coords[n];
	}
	
	double& operator[] (const Axis ax) {
		return coord ((ushort) ax);
	}
	
	const double& operator[] (const Axis ax) const {
		return coord ((ushort) ax);
	}
	
	double& x () { return m_coords[X]; }
	double& y () { return m_coords[Y]; }
	double& z () { return m_coords[Z]; }
	const double& x () const { return m_coords[X]; }
	const double& y () const { return m_coords[Y]; }
	const double& z () const { return m_coords[Z]; }
	
	vertex midpoint (vertex& other);
	str stringRep (const bool mangled);
	void transform (matrix<3> matr, vertex pos);
	void transform (matrix<4> matr);
};

#endif // TYPES_H

mercurial