Daniel,
See for example demos in svn branch/examples/autofleet/nightfighter
and there in the end of Cadencer1Progress you could find
with DummyCube1.Position do
if Y < TerrainRenderer1.InterpolatedHeight(AsVector) then
Y := TerrainRenderer1.InterpolatedHeight(AsVector) + FCamHeight;
PW
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Pavel!
Thank you for the answer.
Yes, I have used Interpolated height for TerrainRenderer, but the function does not seem to exist for a heightfield.
How can I do the same thing for a Heightfield object?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Daniel,
Hm, use search opt in your RAD, there are many demos for Delphi in the trunk and look also at AlitaOnHightField example in branch\games folder where
procedure TForm1.HeightField1GetHeight(const X, Y: Single; var z: Single;
var Color: TVector4f; var TexPoint: TTexPoint);
var
val: Integer;
xi, yi: Integer;
begin
xi := Round(X * (Image1.Picture.Width - 1));
// translate heightfield coordinate to Image1 pixel number
yi := Round((1 - Y) * (Image1.Picture.Height - 1));
val := (Image1.Picture.Bitmap.Canvas.Pixels[xi, yi]) AND $000000FF;
// use brightness of heightmap pixel to calculate height of point x,y
z := val * 0.05; // return the height of the landscape in z at position x,y
end;
Pavel
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Daniel, i take a look in the TGLHeightfield class is not possible to do what you want, because Height is calculate and redering dynamically in real time. So the value are not stored. So the only way is to make lookup table (like a bitmap or a simple array like said Pavel). you can fill it in the HeightFieldGetHeight event, after you'll can retrieve the right value from the x,y pos
eg :
procedure TForm1.formula1(const x, y: Single; var z: Single;
var color: TVector4f; var texPoint: TTexPoint);
begin
z := vectornorm(x,y);
z := some sin() equations...
MyArray[x,y]:=z;
procedure GLCadencer.OnProgress
begin
if CurrentPosZ<MyArray[CurrentPosX, CurrentPosY] then .....
Or something like that
Cheers
Last edit: Jerome.D (BeanzMaster) 2017-03-13
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Daniel,
Here is an application that I wrote to help my granson to understand 3D math.
There are some aspects that I need to improve but not just now.
Eric Hardinge
Hi, Eric, Pavel I'm tried to convert Plot3D under Lazarus but some missing maths functions. Have you
code for : ArcCsc, ArcSec, ArcCot, Csch, SecH, CotH, ArcCsch, ArcSecH, ArcCotH.
For ArcCot,ArcSec and ArcCsc i just negate value of the Csc, Sec and Cotangent functions from FPC Math unit, but not sure is right.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Jerome,
Here the maths functions that not included in GLVectorGeometry unit from System.Math:
const
FuzzFactor = 1000;
Infinity = 1.0 / 0.0; // not for comparison, only assignments
ExtendedResolution = 1E-19 * FuzzFactor;
function IsZero(const A: Extended; Epsilon: Extended): Boolean;
begin
if Epsilon = 0 then
Epsilon := ExtendedResolution;
Result := Abs(A) <= Epsilon;
end;
procedure FClearExcept;
begin
end;
procedure FCheckExcept;
begin
end;
// next only for single case
//ArcCsc,
function ArcCsc(const X: Single): Single;
begin
FClearExcept;
if IsZero(X) then
Result := Infinity
else
Result := ArcSin(1 / X);
FCheckExcept;
end;
//ArcSec,
function ArcSec(const X: Single): Single;
begin
FClearExcept;
if IsZero(X) then
Result := Infinity
else
Result := ArcCos(1 / X);
FCheckExcept;
end;
//ArcCot
function ArcCot(const X: Single): Single;
begin
FClearExcept;
if IsZero(X) then
Result := PI / 2
else
Result := ArcTan(1 / X);
FCheckExcept;
end;
//Csch
function CscH(const X: Single): Single;
begin
FClearExcept;
Result := 1 / SinH(X);
FCheckExcept;
end;
//SecH
function SecH(const X: Single): Single;
begin
FClearExcept;
Result := 1 / CosH(X);
FCheckExcept;
end;
//CotH
function CotH(const X: Extended): Extended;
begin
FClearExcept;
Result := 1 / TanH(X);
FCheckExcept;
end;
//ArcCsch,
function ArcCscH(const X: Single): Single;
begin
FClearExcept;
if IsZero(X) then
Result := Infinity
else
if X < 0 then
Result := Ln((1 - Sqrt(1 + X * X)) / X)
else
Result := Ln((1 + Sqrt(1 + X * X)) / X);
FCheckExcept;
end;
//ArcSecH
function ArcSecH(const X: Single): Single;
begin
FClearExcept;
if IsZero(X) then
Result := Infinity
else if SameValue(X, 1) then
Result := 0
else
Result := Ln((Sqrt(1 - X * X) + 1) / X);
FCheckExcept;
end;
//ArcCotH
function ArcCotH(const X: Single): Single;
begin
FClearExcept;
if SameValue(X, 1) then
Result := Infinity // 1.0 / 0.0
else if SameValue(X, -1) then
Result := NegInfinity // -1.0 / 0.0
else
Result := 0.5 * Ln((X + 1) / (X - 1));
FCheckExcept;
end;
And it's needs to say that if we have nevertheless using System.Math unit in uses clause of GLVectorGeometry then there are many obsolete dublicated routines yet.
PW
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Eric,
Your Plot3D math is an excellent app for z=f(x,y) on hightfiled and it may be remains only to develop the next advanced Plot4D for g=f(x,y,z) on 3D grid. But I've found that it's creating a folder C:\Plot 3D that might be not advisable for Win 10. So it's more safety to compile the project to your Plot3d\bin directory and then if necessary to write Innosetup's installler to send exe to C:Program Files.
PW
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Pavel,
That is one of the problems of old age, I turned 80 last week;
"You cant teach old dogs new tricks"
However I will take your advise and modify the installer etc.
I have also wanted to develop the 4 D version but it all takes time, and I cant spend long periods of time sitting as my body becomes stiff and painful.
I do have a parametric 2D application and a 3D parametric plotter might be good.
Eric Hardinge
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi, thanks Pavel i'll add those functions in GLVectorGeometry.Pas of the Lazarus Branch.
And like siad Pavel, to take care of you is the most important Eric. Thanks great job a lot of little tricks in your code.
Cheers
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi everyone!
I need to get the height of a certain spot on a heightfield, can someone explain how I can do that?
Thanks in advance!
/Daniel
Daniel,
See for example demos in svn branch/examples/autofleet/nightfighter
and there in the end of Cadencer1Progress you could find
with DummyCube1.Position do
if Y < TerrainRenderer1.InterpolatedHeight(AsVector) then
Y := TerrainRenderer1.InterpolatedHeight(AsVector) + FCamHeight;
PW
Hi Pavel!
Thank you for the answer.
Yes, I have used Interpolated height for TerrainRenderer, but the function does not seem to exist for a heightfield.
How can I do the same thing for a Heightfield object?
Hi how do you generate your heightfield ?
Hi Jerome!
I use a TGLHeightField and in a cadencer I have:
MyHeightField.OnGetHeight := formula1;
Then the formula is something like:
Similar to Pavels solution, I want an object to not fall through the HeightField.
All the best,
Daniel
Daniel,
Hm, use search opt in your RAD, there are many demos for Delphi in the trunk and look also at AlitaOnHightField example in branch\games folder where
procedure TForm1.HeightField1GetHeight(const X, Y: Single; var z: Single;
var Color: TVector4f; var TexPoint: TTexPoint);
var
val: Integer;
xi, yi: Integer;
begin
xi := Round(X * (Image1.Picture.Width - 1));
// translate heightfield coordinate to Image1 pixel number
yi := Round((1 - Y) * (Image1.Picture.Height - 1));
val := (Image1.Picture.Bitmap.Canvas.Pixels[xi, yi]) AND $000000FF;
// use brightness of heightmap pixel to calculate height of point x,y
z := val * 0.05; // return the height of the landscape in z at position x,y
end;
Pavel
Thanks Pavel!
It seems I don't even have to draw the image to get what I want.
This seems to work, unless I missed something:
Daniel, i take a look in the TGLHeightfield class is not possible to do what you want, because Height is calculate and redering dynamically in real time. So the value are not stored. So the only way is to make lookup table (like a bitmap or a simple array like said Pavel). you can fill it in the HeightFieldGetHeight event, after you'll can retrieve the right value from the x,y pos
eg :
procedure TForm1.formula1(const x, y: Single; var z: Single;
var color: TVector4f; var texPoint: TTexPoint);
begin
z := vectornorm(x,y);
z := some sin() equations...
MyArray[x,y]:=z;
procedure GLCadencer.OnProgress
begin
if CurrentPosZ<MyArray[CurrentPosX, CurrentPosY] then .....
Or something like that
Cheers
Last edit: Jerome.D (BeanzMaster) 2017-03-13
Thanks for the answer Jerome!
I'll try it out!
Cheers
Hi Daniel,
Here is an application that I wrote to help my granson to understand 3D math.
There are some aspects that I need to improve but not just now.
Eric Hardinge
Here are some example files used by Plot3D
Hi, Eric
Fine, I've tested and added your Plot2D and Plot3D in ..branches\examples\mathapps
Pavel
Hi, Eric, Pavel I'm tried to convert Plot3D under Lazarus but some missing maths functions. Have you
code for : ArcCsc, ArcSec, ArcCot, Csch, SecH, CotH, ArcCsch, ArcSecH, ArcCotH.
For ArcCot,ArcSec and ArcCsc i just negate value of the Csc, Sec and Cotangent functions from FPC Math unit, but not sure is right.
Jerome,
Here the maths functions that not included in GLVectorGeometry unit from System.Math:
const
FuzzFactor = 1000;
Infinity = 1.0 / 0.0; // not for comparison, only assignments
ExtendedResolution = 1E-19 * FuzzFactor;
function IsZero(const A: Extended; Epsilon: Extended): Boolean;
begin
if Epsilon = 0 then
Epsilon := ExtendedResolution;
Result := Abs(A) <= Epsilon;
end;
procedure FClearExcept;
begin
end;
procedure FCheckExcept;
begin
end;
// next only for single case
//ArcCsc,
function ArcCsc(const X: Single): Single;
begin
FClearExcept;
if IsZero(X) then
Result := Infinity
else
Result := ArcSin(1 / X);
FCheckExcept;
end;
//ArcSec,
function ArcSec(const X: Single): Single;
begin
FClearExcept;
if IsZero(X) then
Result := Infinity
else
Result := ArcCos(1 / X);
FCheckExcept;
end;
//ArcCot
function ArcCot(const X: Single): Single;
begin
FClearExcept;
if IsZero(X) then
Result := PI / 2
else
Result := ArcTan(1 / X);
FCheckExcept;
end;
//Csch
function CscH(const X: Single): Single;
begin
FClearExcept;
Result := 1 / SinH(X);
FCheckExcept;
end;
//SecH
function SecH(const X: Single): Single;
begin
FClearExcept;
Result := 1 / CosH(X);
FCheckExcept;
end;
//CotH
function CotH(const X: Extended): Extended;
begin
FClearExcept;
Result := 1 / TanH(X);
FCheckExcept;
end;
//ArcCsch,
function ArcCscH(const X: Single): Single;
begin
FClearExcept;
if IsZero(X) then
Result := Infinity
else
if X < 0 then
Result := Ln((1 - Sqrt(1 + X * X)) / X)
else
Result := Ln((1 + Sqrt(1 + X * X)) / X);
FCheckExcept;
end;
//ArcSecH
function ArcSecH(const X: Single): Single;
begin
FClearExcept;
if IsZero(X) then
Result := Infinity
else if SameValue(X, 1) then
Result := 0
else
Result := Ln((Sqrt(1 - X * X) + 1) / X);
FCheckExcept;
end;
//ArcCotH
function ArcCotH(const X: Single): Single;
begin
FClearExcept;
if SameValue(X, 1) then
Result := Infinity // 1.0 / 0.0
else if SameValue(X, -1) then
Result := NegInfinity // -1.0 / 0.0
else
Result := 0.5 * Ln((X + 1) / (X - 1));
FCheckExcept;
end;
And it's needs to say that if we have nevertheless using System.Math unit in uses clause of GLVectorGeometry then there are many obsolete dublicated routines yet.
PW
Eric,
Your Plot3D math is an excellent app for z=f(x,y) on hightfiled and it may be remains only to develop the next advanced Plot4D for g=f(x,y,z) on 3D grid. But I've found that it's creating a folder C:\Plot 3D that might be not advisable for Win 10. So it's more safety to compile the project to your Plot3d\bin directory and then if necessary to write Innosetup's installler to send exe to C:Program Files.
PW
Hi Pavel,
That is one of the problems of old age, I turned 80 last week;
"You cant teach old dogs new tricks"
However I will take your advise and modify the installer etc.
I have also wanted to develop the 4 D version but it all takes time, and I cant spend long periods of time sitting as my body becomes stiff and painful.
I do have a parametric 2D application and a 3D parametric plotter might be good.
Eric Hardinge
Dear Eric,
Ok, I'm understand you so I wish you health and success.
Pavel Vassiliev
Last edit: Pavel Vassiliev 2017-03-17
Hi, thanks Pavel i'll add those functions in GLVectorGeometry.Pas of the Lazarus Branch.
And like siad Pavel, to take care of you is the most important Eric. Thanks great job a lot of little tricks in your code.
Cheers
Hi just found related C code to do it with Bilinear interpolation
see (in french)
https://jeux.developpez.com/tutoriels/theorie-des-collisions/sols-monde-3d/#LIII-D-4
esaly to convert ;)