Recent

Author Topic: Clearing a 'Canvas'  (Read 3976 times)

jamie

  • Hero Member
  • *****
  • Posts: 7663
Re: Clearing a 'Canvas'
« Reply #15 on: February 25, 2026, 12:11:41 am »
any reason why a Polygon isn't used over plotting the points line by line?

Jamie
The only true wisdom is knowing you know nothing

J-G

  • Hero Member
  • *****
  • Posts: 992
Re: Clearing a 'Canvas'
« Reply #16 on: February 25, 2026, 02:50:33 pm »
J-G, from your original post in this thread it seems to me that you are visually representing a triangle "being solved" (including labelled lengths and angles).

Are you "storing" this data? For example like:
Code: Pascal  [Select][+][-]
  1. type
  2.   TTriangle = record
  3.     pts : array [1..3] of TPoint;
  4.     lengths : array [1..3] of double;
  5.     angles : array [1..3] of double;
  6.   end;

If you do this, then whenever the OnPaint event is triggered, you can use this information to (re)draw the triangle. This should mean that the graphics would never disappear - if another window covers the form or whatever.

cheers
S.

You are quite correct @Speter - as far as the object of the program is concerned - and Yes I am storing the data, though not in a 'Record' as your example shows, similar but since my programming style is 'organic' and 'iterative' I seldom re-visit code to make it more efficient :)

I do actually have the Side and Angle dimensions stored in arrays of record but not under the umbrerella of 'Triangle' :
Code: Pascal  [Select][+][-]
  1.   S_Dims : array[1..5] of record        
  2.                             Dim  : string;
  3.                             Size : single;
  4.                             Pix  : word;
  5.                             Rot  : word;
  6.                           end;
  7.  
  8.   A_Dims : array[1..3] of Record  
  9.                             Dim  : string;
  10.                             Size : single;
  11.                             Rot  : word;
  12.                           end;
  13.  

You may now be wondering why I have 5 'sides'  -  the extra 2 are Width & Height which in the case of anything other than a 'Right Triangle' may well be different from A, B or C - for scaling within the display area those figures are vital.

The original program was intended to simply solve triangles given any three of the six potential dimensions and just returning all of them. Only later when discussing it with my grandson did I consider adding a 'visual' aspect. This was initially as 6 pre-drawn images. 

Adding a complete list of the various 'functions' (Sin, Cos, Tan) for all three angles  came much later - though I had previously written a separate program to calculate such, given any angle in Degrees or Radians - and that included Cotan, Secant, Cosec plus Astronomical equivalent in days,hours, minutes & seconds !!

Only laterly have I come to drop the pre-drawn images to show a more accurate representation of the triangle.

As far as the image being cleared, this only happens when I drag the main program window outside the screen area, dragging another window of any kind over the top of my main window leaves the image 'as is'.


To answer @Jamie's question - - -  since there are only three 'points', I didn't even concider using 'DrawPolly' which may well be more efficient (though I would still have to calculate the same number of points) but maybe not as 'flexible'. From what I have read, DrawPolly just uses the current pen colour/size, whereas in my use case it may well be more informative to have each side of the triangle a different colour/size. I haven't used that as yet but it is an option.




FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

speter

  • Hero Member
  • *****
  • Posts: 522
Re: Clearing a 'Canvas'
« Reply #17 on: February 25, 2026, 11:07:00 pm »
[...]
As far as the image being cleared, this only happens when I drag the main program window outside the screen area, dragging another window of any kind over the top of my main window leaves the image 'as is'.
Hmmmm, I don't understand this. I would have thought that dragging the window outside the screen AND dragging another window over the top, would both trigger the OnPaint event, which should (re)draw your figure.

Is the figure being drawn in the (form or panel) OnPaint method?

cheers
S.

PS: Over the past month I have been reviewing my Sudoko solver, looking specifically at the "Unique Rectangle" pattern. This pattern has 6 different tests (I had implemented 5 before). I was surprised when I realised that each test looks for the pattern in its own way, then acts on the pattern if found. In other words the code is probably bloated; but it (mostly) works. Which brings to mind the classic "if it ain't broke, don't fix it". So, while it might be better to reorganise your data structures, I don't bother (unless you want to do a total rewrite - which I will need to do with my sudoku solver ;( ).
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

J-G

  • Hero Member
  • *****
  • Posts: 992
Re: Clearing a 'Canvas'
« Reply #18 on: February 26, 2026, 03:27:48 am »
[...]
As far as the image being cleared, this only happens when I drag the main program window outside the screen area, dragging another window of any kind over the top of my main window leaves the image 'as is'.

Hmmmm, I don't understand this. I would have thought that dragging the window outside the screen AND dragging another window over the top, would both trigger the OnPaint event, which should (re)draw your figure.

Is the figure being drawn in the (form or panel) OnPaint method?

cheers
S.

PS: Over the past month I have been reviewing my Sudoko solver, looking specifically at the "Unique Rectangle" pattern. This pattern has 6 different tests (I had implemented 5 before). I was surprised when I realised that each test looks for the pattern in its own way, then acts on the pattern if found. In other words the code is probably bloated; but it (mostly) works. Which brings to mind the classic "if it ain't broke, don't fix it". So, while it might be better to reorganise your data structures, I don't bother (unless you want to do a total rewrite - which I will need to do with my sudoku solver ;( ).

:)  We seem to be of a similar mind as far as creating 'bloated' code  :o

I have no doubt that most (all?) of my programs do contain code that could be deleted - or at least made simpler with just a little thought 'after the event' as it were - but as you suggest, the 'Aint broke, don't fix it' mentality persists.

No, I'm not using the 'OnPaint' Event to draw the image;  This is the actual drawing code :
Code: Pascal  [Select][+][-]
  1.  
  2. with TriangleSolution.Display.Canvas do
  3.     begin
  4.       Pen.Width:=3;
  5.       Pen.Color:=clBlue;
  6.       MoveTo(Origin);
  7.       LineTo(P1);
  8.       LineTo(P2);
  9.       LineTo(Origin);
  10.       Draw_Dim_Lines;
  11.     end;
  12.  

which is called imediately after calculating the location of the Origin & the 2 Points (P1 & P2)  -  all very simple.

I have yet to add the annotation of the sides & angles along with the dimension lines for all the Triangle types other than 'Right'  -  I still have to complete the testing (and trapping) of 'silly' input.

I'll attach a screen-shot of the output.

I've found another occasion when the image is wiped out - - - still not by dragging another window over the [Display] TPanel  -  It is cleared when Windows closes down any non-active window during a period of 'dithering' about where to move a window to. ie. when all open windows are minimised.

Again that's no big deal. 
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

krolikbest

  • Sr. Member
  • ****
  • Posts: 276
Re: Clearing a 'Canvas'
« Reply #19 on: February 26, 2026, 12:24:37 pm »
I'd suggest you to use OnPaint metod of TImage to avoid draving's disappear. So after calculation set some logical var to (for example) True and in mentioned method if this var is True draw on image's canvas

speter

  • Hero Member
  • *****
  • Posts: 522
Re: Clearing a 'Canvas'
« Reply #20 on: February 27, 2026, 02:26:15 am »
J-G,

I agree with krolikbest (and WP) that you'd be better off using the OnPaint event's method; though I would not use a TImage (I'd stick with the TPanel).

Have a look at the attached project: it is (I think) a simplified version of what you are doing; but it only handles right-angle triangles and doesn't bother with displaying the Trig data. BUT, when data (the length of the triangle's sides) is changed it calls procedure calculate (to calc the new info), then simply refreshes the panel (which calls the panel's OnPaint method).

So, the OnPaint method, just draws the current triangle on the panel; _and_ the calculate procedure doesn't draw anything on the panel (it does update the various labels on the right though).

If you have a look at the way my project separates calculation and drawing, I think you'll see how you can do something similar! :)

cheers
S.

PS: My project also makes it fun to resize the form. But if you make the form really small, it comes off the tracks :o
« Last Edit: February 27, 2026, 02:29:32 am by speter »
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

creaothceann

  • Sr. Member
  • ****
  • Posts: 335
Re: Clearing a 'Canvas'
« Reply #21 on: February 27, 2026, 07:26:00 am »
Afaik when you have several places in the code that can cause a visual change, it's slightly better to call Invalidate instead of Refresh (Invalidate just marks the window as "to be refreshed").

J-G

  • Hero Member
  • *****
  • Posts: 992
Re: Clearing a 'Canvas'
« Reply #22 on: February 27, 2026, 12:21:34 pm »
I've had a quick look at your project @Speter - and thanks for your continued interest.

The first thing I noticed I'm sure you'll appreciate is the fact that the display of the value of the angles is 'swapped'   :)    A simple matter to correct of course.

Regrettably I'm going to be tied up with very different problems today (I have to manufacture a new frame locking latch for my grandson's cycle) and tomorrow (I have a concert - singing 'The Creation')  so won't be able to evaluate your suggestions for a while  -  though my first instinct is that since I don't have 'other parts' of my code wanting to draw anything, my current method is 'OK'  -  I'm sure I'll learn quite a lot from your methods of string handling etc. though.



FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

speter

  • Hero Member
  • *****
  • Posts: 522
Re: Clearing a 'Canvas'
« Reply #23 on: February 27, 2026, 11:24:15 pm »
... The first thing I noticed I'm sure you'll appreciate is the fact that the display of the value of the angles is 'swapped'   :)
LOL; thanks for that - I am amazed that I didn't notice this. I'll post an undated project later today.

Quote
my first instinct is that since I don't have 'other parts' of my code wanting to draw anything, my current method is 'OK'
I absolutely agree with this sentiment; BUT, you did mention (re)drawing issues, which would (presumably) be fixed when you move the drawing code to inside the OnPaint method...

cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

speter

  • Hero Member
  • *****
  • Posts: 522
Re: Clearing a 'Canvas'
« Reply #24 on: February 28, 2026, 01:43:57 am »
Attached is a corrected project:
  • the angles are correctly labelled;
  • I'm using invalidate (instead of refresh);
  • if the panel is too small, the app doesn't draw the content;
  • creating a TTriangle class;
  • plus sundry cleanups ;)
cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

J-G

  • Hero Member
  • *****
  • Posts: 992
Re: Clearing a 'Canvas'
« Reply #25 on: March 02, 2026, 02:45:38 am »
@Speter  -  I've done a bit more work and as I said a couple of posts back, thought to look at some of your string handling  -  specifically the TextWidth which I hadn't come across previously.

Using it in the way that you seems to do at (say) line 135  - "len := textwidth(s);"

My code is "L := Textwidth(S_Dims[5].Dim);" 

The compiler returns    ' Error: Identifier not found "Textwidth" '

In case I am using an older version of the 'Graphics' Unit, I have checked that there is such a procedure in my version and can confirm that it is at line 1137, so I cannot fathom why your code compiles without error and mine doesn't.

I appreciate that this is at a tangent from 'Clearing a Canvas' but it make sense to continue the discussion here.
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

Thausand

  • Hero Member
  • *****
  • Posts: 503
Re: Clearing a 'Canvas'
« Reply #26 on: March 02, 2026, 03:16:03 am »
The compiler returns    ' Error: Identifier not found "Textwidth" '
Peter code is use https://lazarus-ccr.sourceforge.io/docs/lcl/graphics/tcanvas.textwidth.html so work when is scope canvas.

speter

  • Hero Member
  • *****
  • Posts: 522
Re: Clearing a 'Canvas'
« Reply #27 on: March 02, 2026, 08:05:39 am »
J-G, Thausand is absolutely correct. If you look at the beginning of the procedure, you should find:
Code: Pascal  [Select][+][-]
  1.   with panel_drawing.canvas do
followed by a (block) begin.

canvas.textwidth() works (more or less) the same as the old turbo pascal (graph) textwidth() function.

Note that there is also:
  canvas.textextent(); and
  canvas.textheight()

cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

J-G

  • Hero Member
  • *****
  • Posts: 992
Re: Clearing a 'Canvas'
« Reply #28 on: March 02, 2026, 12:58:11 pm »
Understood !   :-[

I really should spend more 'quality' time evaluating code before trying a simple 'copy'  :o

The reason for the error flagging up is now easy to see - although I'm using the 'Canvas' to draw the triangle, I'm using TLabels for the dimensions and even though these are 'transparent' the bounding box still interferes with the canvas image so I suspect that I would be better off writing the text directly to the canvas, probaly using 'TextOut'  -  but I'll have to do some more reading/research  ::)

I got around the problem by calling the 'Length' and then multiplying that by an average number of pixels  -  actually ½ of that - since I only want to know how far from the centre to start the label.  The end result is effectly correct but as I've mentioned it's not as clean as it could be - witness the attached screen-grabs - still some refinement needed as far as anotation position is concerned but that may well be sorted when I switch to writing direct to the Canvas.

As it happens these screen-grabs also show the issue I have with @WP's Decimal Places string handling  - discussed in a separate thread.


« Last Edit: March 02, 2026, 01:02:16 pm by J-G »
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

 

TinyPortal © 2005-2018