### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Graduated colour depending on offset from original position  (Read 819 times)

#### ranny

• Jr. Member
• Posts: 77
##### Graduated colour depending on offset from original position
« on: July 21, 2024, 09:35:17 am »
Hi,

I have been working on a program that calculates stresses and deflection of a structure under various loading conditions.  Currently I can draw the model and I can draw, at the moment, the deflected state.  I know what the maximum deflection is for any part of the structure and what I would like is to have the deflection image display the shape with graduated colour, say, from blue to red, based on amount of deflection.

On the attached image the original framework is shown and the deflected shape is in red.  So what I would like is for any node that is deflected the elements between will be coloured based on how much it is deflected from its original position.

#### wp

• Hero Member
• Posts: 12211
##### Re: Graduated colour depending on offset from original position
« Reply #1 on: July 21, 2024, 11:39:42 am »
If you do this drawing in OpenGL you can specify a color after every vertex of the line segments, and OpenGL will interpolate colors between them:
Code: Pascal  [Select][+][-]
1.       glBegin(GL_LINES);
2.         glColor3f(1, 0, 0);
3.         glVertex3f(-1, -1, 0);
4.         glColor3f(0, 0, 1);
5.         glVertex3f(0, 1, 1);
6.       glEnd;

If you draw with standard LCL graphics canvas commands, you will have to write your own Line() method. If you draw with BGRABitmap you probably find a corresponding line-drawing method in the codebase.

#### ranny

• Jr. Member
• Posts: 77
##### Re: Graduated colour depending on offset from original position
« Reply #2 on: July 21, 2024, 12:21:52 pm »
Hi wp,

I was aware of being able to do this and I guess I have a bit of coding to do to get it to work in the three directions for each node.  I was just wondering if there was a quicker solution.

I will give it a try and see how I get on.

Thanks as always.

#### wp

• Hero Member
• Posts: 12211
##### Re: Graduated colour depending on offset from original position
« Reply #3 on: July 21, 2024, 12:47:17 pm »
Which graphics library do you use for drawing?

#### ranny

• Jr. Member
• Posts: 77
##### Re: Graduated colour depending on offset from original position
« Reply #4 on: July 21, 2024, 12:54:41 pm »
Hmm... I'm not very good at identifying these things, I just installed the lazOpenGlContext package and use the basic OpenGl commands.  Lazarus is version 3.2 with FPC 3.2.2 if that makes a difference....

#### wp

• Hero Member
• Posts: 12211
##### Re: Graduated colour depending on offset from original position
« Reply #5 on: July 21, 2024, 01:18:06 pm »
This is OpenGL - simply add the colors to the OpenGL model of the lines, like I showed in the previous post.

#### ranny

• Jr. Member
• Posts: 77
##### Re: Graduated colour depending on offset from original position
« Reply #6 on: July 21, 2024, 01:38:57 pm »
Sorry, I should have mentioned before, all graphics in this project are OpenGl.  It's taking me quite a while to get an understanding it but I am pleased with the results.

For your suggestion I will find a way of linearly moving from, say, red to blue then compare to each orthogonally displaced point.  Will keep me busy for a wee while.

Thanks.

#### wp

• Hero Member
• Posts: 12211
##### Re: Graduated colour depending on offset from original position
« Reply #7 on: July 21, 2024, 02:03:41 pm »
In TAChart, there is a function for interpolating colors between two end colors weighted by a factor ACoeff (0..1):
Code: Pascal  [Select][+][-]
1. function InterpolateRGB(AColor1, AColor2: Integer; ACoeff: Double): Integer;
2. type
3.   TBytes = packed array [1..4] of Byte;
4. var
5.   c1: TBytes absolute AColor1;
6.   c2: TBytes absolute AColor2;
7.   r: TBytes absolute Result;
8.   i: Integer;
9. begin
10.   ACoeff := EnsureRange(ACoeff, 0.0, 1.0);
11.   for i := 1 to 4 do
12.     r[i] := Round(c1[i]  + (c2[i] - c1[i]) * ACoeff);
13. end;

Adapting to your project, I would say, that ACoeff is the relative displacement (displacement at a vertex / max displacement). So, when you want to draw a segment between vertices V1 and V2, calculate the interpolated colors for both vertices and add them to the OpenGL command:
Code: Pascal  [Select][+][-]
1. const
2.   MinDisplColor = clBlue;
3.   MaxDisplColor = clRed;
4. var
5.   MaxDisplacement: Double;
6.
7. procedure DrawSegment(V1, V1: TPoint3d; Displ1, Displ2: Double);
8. var
9.   col1, col2: TColor;
10. begin
11.   col1 := InterpolateRGB(MinDisplColor, MaxDisplColor, Displ1/MaxDisplacement);
12.   col2 := InterpolateRGB(MinDisplColor, MaxDisplColor, Displ2/MaxDisplacement);
13.   glBegin(GL_LINES);
14.     glColor3f(Red(col1)/255, Green(col1)/255, Blue(col1)/255);
15.     glVertex3f(V1.X, V1.Y, V1.Z);
16.     glColor3f(Red(col2)/255, Green(col2)/255, Blue(col2)/255);
17.     glVertex3f(V2.X, V2.Y, V2.Z);
18.   glEnd;
19. end;
20.

#### ranny

• Jr. Member
• Posts: 77
##### Re: Graduated colour depending on offset from original position
« Reply #8 on: July 22, 2024, 07:36:07 am »
That's exactly what I am looking for!  Yesterday I spent the time getting the maximum values for displacement from the array of adjoining nodes and achieved some progress with colour graduation.

Going forward, your routine will be useable for displaying maximum stresses in the structure as well.

Thanks again, I' on the road to getting one of my projects close to completion, and genuinely useful!