Re:Pixel precision...
That seems to me difficult to implement... If you can help...
Here is the case :
I start from Source:TBitmap
I want to paint it according (xy? z? distance) transformation into a
reuslting Target:TBitmap...
I fill the target canvas with a solid color
self._target.Canvas.Brush.Color := clBlue;
self._target.Canvas.FillRect(TVCL.Rect(_target));
I calculate the source center O, and the target center O2 :
_O := TXYZ.D3(self._source.Width * 0.5, self._source.Height * 0.5, 0);
_O2 := TXYZ.D3(self._target.Width * 0.5, self._target.Height * 0.5, 0);
Then, I do loop Source.ScanLine with _y/_x :
for _y
do for _x
do
Here comes the calculation :
_A := TXYZ.DoOffset( _incline,
TXYZ.D3(- _O.x + _O2.x +
_x, - _O.y + _O2.y + _y, 0),
_O2,
osAdd
);
_incline is (xy? z?
DoOffset just adds the _incline to the given point (adjusted for being
centered, distance = zero) and center (O2)...
You can read it as : rotate (x,y,z) with addition of (xy? z?, and take
center at O2...
The Result (_A), is now the projected 3D point of the Source (x,y) point...
so obviously comes the copy of the bytes :
_targetarr :=
self._target.ScanLine[System.Round(_A.y)];
_ix1 := (_target.Width - System.Round(_A.x)) *
3;
_x0 := _x * 3;
_targetarr[_ix1 ] := _bytes[_x0];
_targetarr[_ix1 + 1] := _bytes[_x0 + 1];
_targetarr[_ix1 + 2] := _bytes[_x0 + 2];
Note : the Target's (Height/Width) are forced to be double of highest
(Width/Height) from Source....so no range error/checking...
How to go to inverse ?
That is from Source.ScanLine (x/y), center O2, what operation to compare
with unrotated (x,y), center O ?
DH
Here are the 2D DoIncline and 3D DoOffset functions :
-------------------------------------------------------------
class function TXY.DoIncline(const _value:TDegrees; const _O:TD2; const
_A:TD2):TD2;
var _cos:TReal;
_delta:TD2;
_sin:TReal;
begin
if TXY.IsDefined(_O) and TXY.IsDefined(_A) and
TMeasure.IsDefined(_value)
then begin
_delta.X := _A.X - _O.X;
_delta.Y := _A.Y - _O.Y;
_cos := TAngle.DoCosinus(_value);
_sin := TAngle.DoSinus(_value);
Result := TXY.D2( _cos * _delta.X - _sin * _delta.Y +
_O.X,
_sin * _delta.X + _cos * _delta.Y +
_O.Y
);
end
else Result := TXY.ValueLessD2;
end;
class function TXYZ.DoOffset(const _value:TD3Incline; const _A:TD3; const
_O:TD3; const _style:TOffsetStyles):TD3;
begin
if TXYZ.IsDefined(_O) and TXYZ.IsDefined(_A) and TXYZ.IsDefined(_value)
then begin
with TXY.DoIncline( _value.xy * IIF(_style = osAdd,
1, -1),
TXY.D2(_O.x, _O.y),
TXY.D2(_A.x, _A.y)
)
do begin
Result.x := y;
Result.y := x;
Result.z := _A.z;
end;
with TXY.DoIncline( _value.z * IIF(_style = osAdd, 1, -1),
TXY.D2(_O.y, _O.z),
TXY.D2(Result.y, Result.z)
)
do begin
Result.x := Result.x;
Result.y := x;
Result.z := y;
end;
end
else Result := TXYZ.ValueLessD3;
end;