6 Replies - 1776 Views - Last Post: 09 December 2009 - 11:55 AM Rate Topic: -----

#1 tiny13  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 19
  • Joined: 05-November 09

Composition

Posted 06 December 2009 - 09:29 AM

OK! So basically I am working on a code that requires me to do a couple things. I already know what I NEED to do, I just don't know how to put it into code. Basically, the program as it is, takes a triangle and rotates it around the vertex in a set amount of degrees. What needs to be done to this code is: The triangle must rotate around one of it's vertices. I have chosen the point (50, 50, 0) as the rotating point. Now it's just a matter of getting the object to rotate around the point, rather than the vertex of the graph.

So basically I need to do it in this order:

1.) Translate the triangle so that it's at the origin.
2.) Rotate the triangle.
3.) Translate the triangle so that it's back at it's original location.

Now, from what I understand, I need to use a Combo Matrix. Basically combine 3 matrices into 1. Now what I don't know is if I need to write this combo matrix from scratch, or I need to just simply multiply the matrices within the code. Any tips or help would be greatly appreciated! Thanks in advance!

.cpp file:

/*
composition.cpp

simple animation using a composition transformation matrix
*/

#include <stdio.h>
#include <windows.h>

#include "resource.h"

// your path for this include may vary
#include "GraphicsFramework.h"
#include "gmath.h"

// Global variable to store the graphics framwork object
GraphicsFramework* PGraphics;

HWND HOutput = 0;  // handle to the output control
HWND HDialog = 0;

// function to draw a line between two points
void DrawLine(int x1, int y1, int x2, int y2, unsigned int color) {
	int dx, dy;						 // dy / dx is the slope
	int x, y;						   // loop and point variables

	// calculate changes in y and x between the points
	dy = y2 - y1;
	dx = x2 - x1;

	if (Abs(dy) > Abs(dx)) {
		// since there is a greater change in y than x we must
		// loop in y, calculate x and draw
		for (y=y1; y != y2; y += Sign(dy)) {
			x = x1 + (y - y1) * dx / dy;
			PGraphics->AddPoint(x, y, color);
		}
	}
	else {
		// since there is a greater (or equal) change in x than y we must
		// loop in x, calculate y and draw
		for (x=x1; x != x2; x += Sign(dx)) {
			y = y1 + (x - x1) * dy / dx;
			PGraphics->AddPoint(x, y, color);
		}
	}

	// draw the last pixel
	PGraphics->AddPoint(x2, y2, color);
}

void DrawStuff() {
	COLORREF green = RGB(0, 255, 0);	// green color to draw with
	COLORREF red = RGB(0, 0, 255);	  // red color to draw with
	char str[32];					   // string to store user input
	Vector3 pts[3];					 // original data points
	Vector3 newPts[3];				  // transformed points
	double angle;					   // rotation angle
	Matrix4 rz;						 // current rotation matrix about z axis

	// this composite matrix need to remember its value between calls to this draw function
	// so it must be declared static or made a global variable
	static Matrix4 c;				   // composition matrix

	// set up the original points for the triangle
	pts[0].set(  0,   0, 0);
	pts[1].set(100, 100, 0);
	pts[2].set(100,   0, 0);

	// clear the scene and add an axis
	PGraphics->ClearScene(RGB(0, 0, 0));
	PGraphics->AddAxis(RGB(150, 150, 150), 10);

	// get the user input from the edit boxes and 
	// convert string input to double
	GetDlgItemText(HDialog, IDC_EDIT_ANGLE, str, 32);
	angle = atof(str);

	// make the current rotation matrix
	rz.makeRotationMatrixZ(angle);
	// update the composite matrix - remember we must pre-multiply by m: c = m x c
	c = Multiply(rz, c);

	// transform the original triangle points into the new points for drawing
	for (int i=0; i < 3; i++) {
		newPts[i] = Multiply(c, pts[i]);
	}

	// draw the triangle lines 0-1, 1-2, 2-0
	DrawLine(newPts[0].x, newPts[0].y, newPts[1].x, newPts[1].y, green);
	DrawLine(newPts[1].x, newPts[1].y, newPts[2].x, newPts[2].y, green);
	DrawLine(newPts[2].x, newPts[2].y, newPts[0].x, newPts[0].y, green);

	// draw the points
	PGraphics->Draw();
}

/*
DialogProc
this is the window event handler for the main dialog
*/
BOOL CALLBACK DialogProc (HWND hwnd, 
	UINT message, 
	WPARAM wParam, 
	LPARAM lParam)
{
	switch(message)
	{
	case WM_INITDIALOG:
		// dialog is initializing - store the picture box handle in a global variable for later
		HOutput = GetDlgItem(hwnd, IDC_PICTURE_OUTPUT);		

		// instantiate and initialize our graphics framework object
		PGraphics = new GraphicsFramework(HOutput);

		break;

	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
			case IDC_BTN_DRAW:
				// draw button was pressed
				DrawStuff();
				break;
			case IDC_BTN_CLEAR:
				// clear button was pressed so clear the scene and draw the empty scene
				PGraphics->ClearScene(RGB(0, 0, 0));
				PGraphics->Draw();
				break;
			case IDCANCEL:
				// user is quitting so release the GraphicsFramework object and quit
				delete PGraphics;
				PostQuitMessage(0);
				break;
		}
				  
	}
	return FALSE;
}

// this is the main function that starts the application
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, char * cmdParam, int cmdShow)
{
	// create the main window
	// store its handle in a global if needed
	HDialog = CreateDialog (GetModuleHandle(NULL), 
		MAKEINTRESOURCE(IDD_DIALOG1), 
		0, 
		DialogProc);

	// make the dialog visible
	ShowWindow(HDialog, SW_SHOW);

	// standard windows message loop
	MSG  msg;
	int status;
	while ((status = GetMessage (&msg, 0, 0, 0)) != 0)
	{
		if (status == -1)
			return -1;
		// avoid processing messages for the dialog
		if (!IsDialogMessage (HDialog, & msg))
		{
			TranslateMessage ( & msg );
			DispatchMessage ( & msg );
		}
	}

	return (int)(msg.wParam);
}



gmath.h header file:

// gmath.h

#ifndef GMATH_H
#define GMATH_H

#include <math.h>

const double PI		  = 3.14159265359;
const double DTOR		= 0.01745329251994;	 // degrees to radians
const double RTOD		= 57.29577951308;	   // radians to degrees

// function to get the absolute value of an integer
int Abs(int x) {
	if (x < 0)  return -x;
	else		return x;
}

// function to get the sign (+1 or -1) of an integer
int Sign(int x) {
	if (x < 0)  return -1;
	else		return 1;
}

// a 3D vector with a homogeneous coordinate
// if not used set w = 1
class Vector3 {
public:
	double x, y, z, w;

	// default constructor
	Vector3() {
		x = y = z = 0.0;
		w = 1.0;
	}

	// set this vector to a new value
	void set(double x, double y, double z, double w = 1.0) {
		this->x = x; 
		this->y = y; 
		this->z = z;   
		this->w = w;
	}

	// set this vector to a new value
	void set(Vector3 v) {
		this->x = v.x; 
		this->y = v.y; 
		this->z = v.z;   
		this->w = v.w;
	}

	// scale this vector uniformly
	void scale(double f) {
		this->x *= f; 
		this->y *= f; 
		this->z *= f;   
	}

	// return squared length of this vector
	double squaredLength() {
		return x * x + y * y + z * z;
	}

	// return length of this vector
	double length() {
		return sqrt(x * x + y * y + z * z);
	}

	// normalize this vector
	void normalize() {
		double len = length();
		scale(1/len);
	}

};

Vector3 Add(Vector3 a, Vector3 b) {
	// addition - returns result = a + b
	Vector3 result;
	result.x = a.x + b.x;
	result.y = a.y + b.y;
	result.z = a.z + b.z;
	return result;
}

Vector3 Subtract(Vector3 a, Vector3 b){
	// subtraction - returns result = a - b
	Vector3 result;
	result.x = a.x - b.x;
	result.y = a.y - b.y;
	result.z = a.z - b.z;
	return result;
}

Vector3 CrossProduct(Vector3 a, Vector3 b) {
	// cross product - returns result = a X b
	Vector3 result;
	result.x = a.y * b.z - a.z * b.y;
	result.y = a.z * b.x - a.x * b.z;
	result.z = a.x * b.y - a.y * b.x;
	return result;
}

// return dot product of a & b
double DotProduct(Vector3 a, Vector3 b) {
	return a.x * b.x + a.y * b.y + a.z * b.z;
}

// a 4x4 matrix class
class Matrix4 {
public:
	double m[4][4];

	Matrix4(){ 
		// default constructor set m = I
		m[0][0] = 1.0;  m[0][1] = 0.0;  m[0][2] = 0.0;  m[0][3] = 0.0;
		m[1][0] = 0.0;  m[1][1] = 1.0;  m[1][2] = 0.0;  m[1][3] = 0.0;
		m[2][0] = 0.0;  m[2][1] = 0.0;  m[2][2] = 1.0;  m[2][3] = 0.0;
		m[3][0] = 0.0;  m[3][1] = 0.0;  m[3][2] = 0.0;  m[3][3] = 1.0;
	}

	Matrix4(double m00, double m01, double m02, double m03, 
			double m10, double m11, double m12, double m13,
			double m20, double m21, double m22, double m23,
			double m30, double m31, double m32, double m33) {
		m[0][0] = m00;  m[0][1] = m01;  m02 = m02;  m03 = m03;
		m[1][0] = m10;  m[1][1] = m11;  m12 = m12;  m13 = m13;
		m[2][0] = m20;  m[2][1] = m21;  m22 = m22;  m23 = m23;
		m[3][0] = m30;  m[3][1] = m31;  m32 = m32;  m33 = m33;
	}

	void makeIdMatrix() {
		// makes an identity matrix
		m[0][0] = 1.0;  m[0][1] = 0.0;  m[0][2] = 0.0;  m[0][3] = 0.0;   
		m[1][0] = 0.0;  m[1][1] = 1.0;  m[1][2] = 0.0;  m[1][3] = 0.0;   
		m[2][0] = 0.0;  m[2][1] = 0.0;  m[2][2] = 1.0;  m[2][3] = 0.0;   
		m[3][0] = 0.0;  m[3][1] = 0.0;  m[3][2] = 0.0;  m[3][3] = 1.0;   
	}

	void makeTranslationMatrix(double dx, double dy, double dz) {
		// makes a translation matrix
		m[0][0] = 1.0;  m[0][1] = 0.0;  m[0][2] = 0.0;  m[0][3] = dx;   
		m[1][0] = 0.0;  m[1][1] = 1.0;  m[1][2] = 0.0;  m[1][3] = dy;   
		m[2][0] = 0.0;  m[2][1] = 0.0;  m[2][2] = 1.0;  m[2][3] = dz;   
		m[3][0] = 0.0;  m[3][1] = 0.0;  m[3][2] = 0.0;  m[3][3] = 1.0;   
	}

	void makeScaleMatrix(double sx, double sy, double sz){
		// makes a scale matrix
		m[0][0] =  sx;  m[0][1] = 0.0;  m[0][2] = 0.0;  m[0][3] = 0.0;   
		m[1][0] = 0.0;  m[1][1] =  sy;  m[1][2] = 0.0;  m[1][3] = 0.0;   
		m[2][0] = 0.0;  m[2][1] = 0.0;  m[2][2] =  sz;  m[2][3] = 0.0;   
		m[3][0] = 0.0;  m[3][1] = 0.0;  m[3][2] = 0.0;  m[3][3] = 1.0;   
	}

	// makes rotation matrix about X-axis based on a given angle in degrees
	void makeRotationMatrixX(double angle) {
		double angleInRads = angle * DTOR;
		makeRotationMatrixX(sin(angleInRads), cos(angleInRads));
	}

	void makeRotationMatrixX(double sinA, double cosA){
		// makes rotation matrix about X-axis
		m[0][0] = 1.0; m[0][1] =   0.0;  m[0][2] =   0.0;  m[0][3] = 0.0;   
		m[1][0] = 0.0; m[1][1] =  cosA;  m[1][2] = -sinA;  m[1][3] = 0.0;   
		m[2][0] = 0.0; m[2][1] =  sinA;  m[2][2] =  cosA;  m[2][3] = 0.0;   
		m[3][0] = 0.0; m[3][1] =   0.0;  m[3][2] =   0.0;  m[3][3] = 1.0;   
	}

	// makes rotation matrix about Y-axis based on a given angle in degrees
	void makeRotationMatrixY(double angle) {
		double angleInRads = angle * DTOR;
		makeRotationMatrixY(sin(angleInRads), cos(angleInRads));
	}

	void makeRotationMatrixY(double sinA, double cosA){
		// makes rotation matrix about Y-axis
		m[0][0] =  cosA; m[0][1] = 0.0;  m[0][2] =  sinA;  m[0][3] = 0.0;   
		m[1][0] =   0.0; m[1][1] = 1.0;  m[1][2] =   0.0;  m[1][3] = 0.0;   
		m[2][0] = -sinA; m[2][1] = 0.0;  m[2][2] =  cosA;  m[2][3] = 0.0;   
		m[3][0] =   0.0; m[3][1] = 0.0;  m[3][2] =   0.0;  m[3][3] = 1.0;   
	}

	// makes rotation matrix about Z-axis based on a given angle in degrees
	void makeRotationMatrixZ(double angle) {
		double angleInRads = angle * DTOR;
		makeRotationMatrixZ(sin(angleInRads), cos(angleInRads));
	}

	void makeRotationMatrixZ(double sinA, double cosA){
		// makes rotation matrix about Z-axis
		m[0][0] =  cosA; m[0][1] = -sinA;  m[0][2] = 0.0;  m[0][3] = 0.0;   
		m[1][0] =  sinA; m[1][1] =  cosA;  m[1][2] = 0.0;  m[1][3] = 0.0;   
		m[2][0] =   0.0; m[2][1] =   0.0;  m[2][2] = 1.0;  m[2][3] = 0.0;   
		m[3][0] =   0.0; m[3][1] =   0.0;  m[3][2] = 0.0;  m[3][3] = 1.0;   
	}
};

// multiplies matrix m by vector a
Vector3 Multiply(Matrix4 m, Vector3 a) {
	// returns result = m * a
	Vector3 result;
	result.x = m.m[0][0] * a.x + m.m[0][1] * a.y + m.m[0][2] * a.z + m.m[0][3] * a.w;
	result.y = m.m[1][0] * a.x + m.m[1][1] * a.y + m.m[1][2] * a.z + m.m[1][3] * a.w;
	result.z = m.m[2][0] * a.x + m.m[2][1] * a.y + m.m[2][2] * a.z + m.m[2][3] * a.w;
	result.w = m.m[3][0] * a.x + m.m[3][1] * a.y + m.m[3][2] * a.z + m.m[3][3] * a.w;
	return result;
}

// multiplies vector a by matrix m
Vector3 Multiply(Vector3 a, Matrix4 m) {
	// returns result = a * m
	Vector3 result;
	result.x = a.x * m.m[0][0] + a.y * m.m[1][0] + a.z * m.m[2][0] + a.w * m.m[3][0];
	result.y = a.x * m.m[0][1] + a.y * m.m[1][1] + a.z * m.m[2][1] + a.w * m.m[3][1];
	result.z = a.x * m.m[0][2] + a.y * m.m[1][2] + a.z * m.m[2][2] + a.w * m.m[3][2];
	result.w = a.x * m.m[0][3] + a.y * m.m[1][3] + a.z * m.m[2][3] + a.w * m.m[3][3];
	return result;
}

// multiply x X y using loops
Matrix4 Multiply(Matrix4 x, Matrix4 y) {
	int i, j, k;
	Matrix4 result;

	for(i=0; i < 4; i++) {
		for(j=0; j < 4; j++) {
			result.m[i][j] = 0.0;
			for(k=0; k < 4; k++) {
				result.m[i][j] += x.m[i][k] * y.m[k][j];	
			}
		}
	}
	return result;
}

#endif



I'd appreciate any help.

Is This A Good Question/Topic? 0
  • +

Replies To: Composition

#2 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4187
  • View blog
  • Posts: 11,845
  • Joined: 18-April 07

Re: Composition

Posted 06 December 2009 - 06:35 PM

I think you might be going the complicated route with all this. If you break the problem into some key functions, you will find things line up much easier. I would create one function which converts degrees into radians. Create another which takes in a x, y, and radian angle which will be used to rotate a point around an origin using the formulas...

x' = x cos() - y sin() 
y' = x sin() + y cos()



Where x and y are the original coordinates and x' and y' are the new coordinates and is your radian angle.

Then all you need to do is take a point, subtract from the origin's x and y to move the point based on an origin of 0,0... pass these coordinates to your coordinate function along with your rotation which would be the result from your radian converting function (negative radians for clockwise and positive radians for counterclockwise), calculate the new position and then add the x, y back to the results.

The matrices you are trying to do essentially boils down to the formulas I just gave you above. We are going to bypass all that by just cutting to the meat of the matter. Hope this makes sense. :)

This post has been edited by Martyr2: 06 December 2009 - 06:42 PM

Was This Post Helpful? 0
  • +
  • -

#3 tiny13  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 19
  • Joined: 05-November 09

Re: Composition

Posted 07 December 2009 - 06:06 AM

View PostMartyr2, on 6 Dec, 2009 - 05:35 PM, said:

I think you might be going the complicated route with all this. If you break the problem into some key functions, you will find things line up much easier. I would create one function which converts degrees into radians. Create another which takes in a x, y, and radian angle which will be used to rotate a point around an origin using the formulas...

x' = x cos() - y sin() 
y' = x sin() + y cos()



Where x and y are the original coordinates and x' and y' are the new coordinates and is your radian angle.

Then all you need to do is take a point, subtract from the origin's x and y to move the point based on an origin of 0,0... pass these coordinates to your coordinate function along with your rotation which would be the result from your radian converting function (negative radians for clockwise and positive radians for counterclockwise), calculate the new position and then add the x, y back to the results.

The matrices you are trying to do essentially boils down to the formulas I just gave you above. We are going to bypass all that by just cutting to the meat of the matter. Hope this makes sense. :)


Actually, this doesn't make any sense at all to me. I have no clue what your talking about.
Was This Post Helpful? 0
  • +
  • -

#4 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3088
  • View blog
  • Posts: 19,136
  • Joined: 14-September 07

Re: Composition

Posted 07 December 2009 - 06:41 AM

Do you understand rotational matrices?


Instead of going through all of the hullabaloo, Martyr2 provided a way to do what you want to do without all of the overhead.
Was This Post Helpful? 0
  • +
  • -

#5 tiny13  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 19
  • Joined: 05-November 09

Re: Composition

Posted 07 December 2009 - 07:38 AM

View PostKYA, on 7 Dec, 2009 - 05:41 AM, said:

Do you understand rotational matrices?


Instead of going through all of the hullabaloo, Martyr2 provided a way to do what you want to do without all of the overhead.


No i really don't understand rotational matrices. Please show me exactly what I need to do. I'm so confused.
Was This Post Helpful? 0
  • +
  • -

#6 tiny13  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 19
  • Joined: 05-November 09

Re: Composition

Posted 08 December 2009 - 11:55 AM

View Posttiny13, on 7 Dec, 2009 - 06:38 AM, said:

View PostKYA, on 7 Dec, 2009 - 05:41 AM, said:

Do you understand rotational matrices?


Instead of going through all of the hullabaloo, Martyr2 provided a way to do what you want to do without all of the overhead.


No i really don't understand rotational matrices. Please show me exactly what I need to do. I'm so confused.


Can someone please help me get this working? I can't figure it out.
Was This Post Helpful? 0
  • +
  • -

#7 tiny13  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 19
  • Joined: 05-November 09

Re: Composition

Posted 09 December 2009 - 11:55 AM

View Posttiny13, on 8 Dec, 2009 - 10:55 AM, said:

View Posttiny13, on 7 Dec, 2009 - 06:38 AM, said:

View PostKYA, on 7 Dec, 2009 - 05:41 AM, said:

Do you understand rotational matrices?


Instead of going through all of the hullabaloo, Martyr2 provided a way to do what you want to do without all of the overhead.


No i really don't understand rotational matrices. Please show me exactly what I need to do. I'm so confused.


Can someone please help me get this working? I can't figure it out.


I don't understand how to get this program to work. Can someone please help me figure it out??
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1