USE ieee.math_real.ALL; -- Conrtol Signals -- BIT description 0 1 -- 9 translate at begining no yes -- 8 translate at end no yes -- 7 Around point no yes -- 6 scaling local no yes -- 5 scaling global no yes -- 4-2 rotation order -- 1-0 reflection order -- Rotation Order -- 000 no rotation -- 001 xyz -- 010 yzx -- 011 zxy -- 100 zyx -- 101 yxz -- 110 xzy -- 111 no rotation -- Reflection -- 00 no reflection -- 01 across xy plane -- 10 across YZ plane -- 11 across xz plane ENTITY affine IS PORT(x_in,y_in,z_in, rotate_x,rotate_y,rotate_z, trans_x,trans_y,trans_z, scale_x,scale_y,scale_z,scale_factor: IN REAL; control: IN BIT_VECTOR(9 downto 0); x_out,y_out,z_out:OUT REAL); END affine; ARCHITECTURE test7 OF affine IS TYPE tuple_4 IS ARRAY(0 to 3) OF REAL; TYPE transform_matrix IS ARRAY (0 to 3) OF tuple_4; TYPE data_matrix IS ARRAY (NATURAL range<>) OF tuple_4; FUNCTION matrix_multiply(X:tuple_4; T:transform_matrix) RETURN tuple_4 IS VARIABLE X_1: tuple_4; BEGIN FOR n IN 0 TO 3 LOOP X_1(n):= X(0)*T(0)(n)+X(1)*T(1)(n) + X(2)*T(2)(n) + X(3)*T(3)(n); END LOOP; RETURN X_1; END; FUNCTION transform_multiply(T1:transform_matrix; T2:transform_matrix) RETURN transform_matrix IS VARIABLE T: transform_matrix; BEGIN FOR n IN 0 TO 3 LOOP T(n) := matrix_multiply( T1(n), T2); END LOOP; RETURN T; END; FUNCTION identity RETURN transform_matrix IS VARIABLE T: transform_matrix; BEGIN for i IN 0 to 3 LOOP for j in 0 to 3 loop T(i)(j) := 0.0; end loop; end loop; T(0)(0) := 1.0; T(1)(1) := 1.0; T(2)(2) := 1.0; T(3)(3) := 1.0; return T; END; FUNCTION translate(x,y,z:REAL) RETURN transform_matrix IS VARIABLE T: transform_matrix; BEGIN T := identity; T(3)(0) := x; T(3)(1) := y; T(3)(2) := z; return T; END; FUNCTION rotateX(rotate:REAL) -- degrees RETURN transform_matrix IS VARIABLE T: transform_matrix; BEGIN T := identity; T(1)(1) := cos(rotate*MATH_DEG_TO_RAD); T(2)(2) := T(1)(1); T(1)(2) := sin(rotate*MATH_DEG_TO_RAD); T(2)(1) := -T(1)(2); return T; END; FUNCTION rotateY(rotate:REAL) -- degrees RETURN transform_matrix IS VARIABLE T: transform_matrix; BEGIN T := identity; T(0)(0) := cos(rotate*MATH_DEG_TO_RAD); T(2)(2) := T(0)(0); T(2)(0) := sin(rotate*MATH_DEG_TO_RAD); T(0)(2) := -T(2)(0); return T; END; FUNCTION rotateZ(rotate:REAL) -- degrees RETURN transform_matrix IS VARIABLE T: transform_matrix; BEGIN T := identity; T(0)(0) := cos(rotate*MATH_DEG_TO_RAD); T(1)(1) := T(0)(0); T(0)(1) := sin(rotate*MATH_DEG_TO_RAD); T(1)(0) := -T(0)(1); return T; END; FUNCTION reflect(rx,ry,rz:REAL) -- create a reflection transform matrix RETURN transform_matrix IS variable T: transform_matrix; BEGIN t:= identity; t(0)(0) := rx; t(1)(1) := ry; t(2)(2) := rz; return T; END; FUNCTION scale(x,y,z:REAL) -- create a scaling transform matrix RETURN transform_matrix IS variable T: transform_matrix; BEGIN t:= identity; t(0)(0) := x; t(1)(1) := y; t(2)(2) := z; return T; END; -- normal global scaling FUNCTION scale(s:REAL) -- create a global scaling transform matrix RETURN transform_matrix IS variable T: transform_matrix; BEGIN t:= identity; t(0)(0) := s; t(1)(1) := s; t(2)(2) := s; return T; END; -- shear with following effects -- x* = x + dy + gz -- y* = bx + y + iz -- z* = cx + fy + z FUNCTION shear(b,c,d,f,g,i:REAL) RETURN transform_matrix IS VARIABLE T: transform_matrix; BEGIN T := identity; t(0)(1) := b; t(0)(2) := c; t(1)(0) := d; t(1)(2) := f; t(2)(1) := g; t(2)(1) := i; return T; END; BEGIN PROCESS ( x_in,y_in,z_in,control, trans_x,trans_y,trans_z, scale_x,scale_y,scale_z,scale_factor, rotate_x,rotate_y,rotate_z) variable X:tuple_4; variable T:transform_matrix; begin X(0) := x_in; X(1) := y_in; X(2) := z_in; X(3) := 1.0; T := identity; if (control(9) = '1' and not control(7) = '1') then T := transform_multiply(T,translate(trans_x,trans_y,trans_z)); end if; if (control(7) = '1') then T := transform_multiply(T,translate(-trans_x,-trans_y,-trans_z)); end if; if (control(6) = '1') then T := transform_multiply(T,scale(scale_x,scale_y,scale_z)); end if; if (control(5) = '1') then T := transform_multiply(T,scale(scale_factor)); end if; CASE control(4 downto 2) IS WHEN "000" => WHEN "001" => -- XYZ T := transform_multiply(T, rotateX(rotate_X) ); T := transform_multiply(T, rotateY(rotate_Y) ); T := transform_multiply(T, rotateZ(rotate_Z) ); WHEN "010" => -- YZX T := transform_multiply(T, rotateY(rotate_Y) ); T := transform_multiply(T, rotateZ(rotate_Z) ); T := transform_multiply(T, rotateX(rotate_X) ); WHEN "011" => -- ZXY T := transform_multiply(T, rotateY(rotate_Y) ); T := transform_multiply(T, rotateZ(rotate_Z) ); T := transform_multiply(T, rotateX(rotate_X) ); WHEN "100" => -- ZYX T := transform_multiply(T, rotateZ(rotate_Z) ); T := transform_multiply(T, rotateY(rotate_Y) ); T := transform_multiply(T, rotateX(rotate_X) ); WHEN "101" => -- YXZ T := transform_multiply(T, rotateY(rotate_Y) ); T := transform_multiply(T, rotateX(rotate_X) ); T := transform_multiply(T, rotateZ(rotate_Z) ); WHEN "110" => -- XZY T := transform_multiply(T, rotateX(rotate_X) ); T := transform_multiply(T, rotateZ(rotate_Z) ); T := transform_multiply(T, rotateY(rotate_Y) ); WHEN "111" => END CASE; CASE control(1 downto 0) IS WHEN "00" => WHEN "01" => T := transform_multiply(T,reflect( 1.0, 1.0,-1.0)); WHEN "10" => T := transform_multiply(T,reflect(-1.0, 1.0, 1.0)); WHEN "11" => T := transform_multiply(T,reflect( 1.0,-1.0, 1.0)); END CASE; if control(7) = '1' then T := transform_multiply(T,translate(trans_x,trans_y,trans_z)); end if; if (control(8) = '1' and not control(7) = '1') then T := transform_multiply(T,translate(trans_x,trans_y,trans_z)); end if; X := matrix_multiply(X,T); x_out <= X(0); y_out <= X(1); z_out <= X(2); end PROCESS; END test7;