drawing squares

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Post Reply
danielrr
Posts: 140
Joined: Mon Mar 04, 2013 4:03 pm

drawing squares

Post by danielrr » Thu Mar 11, 2021 11:46 pm

This may be in page one of some livecode manual for drawing figures, and I'm introducing the question also in the hope to find that manual!

if I have a graphic with any two-line set of points (like "613,404;661,704") defining a line A, What's the simplest algorythm to draw another graph which is a square having A as one of it's sides?

Xero
Posts: 152
Joined: Sat Jun 23, 2018 2:22 pm

Re: drawing squares

Post by Xero » Fri Mar 12, 2021 3:33 am

Depends on how you want to square to be drawn. A horizontal line could be either the top or the bottom of the square...
If you are drawing orthogonal lines (horizontal or vertical), the answer will be pretty simple.
Take the points of the line, work out how far apart they are, and create a second set of points offset in the other direction that same distance.
i.e. horizontal line 0,0 ; 100,0 (i.e. x1,y1 ; x2,y2)
100-0 = 100,
create points 0,100 ; 100,100
use the start set of points 0,0 ; 100,0 and the end 100,0 ; 100,100 and draw a rectangle (in this instance it will end up as a square) with those points
To code, you would either need to limit movement only in the x direction, or limit it in the x or y and work out which direction you went (if x1-x2 is not 0 then... else if y1-y2 is not 0 then...)
If you go off orthogonal, into oblique lines, you'll just need to do maths.
Any line is defined by y=mx+b (m being slope, b being y intercept. To work it out from points...
m= y2-y1/x2-x1
b= the formula when x=0 OR... plug in one set of points, and the abovementioned slope
b= y1-(y2-y1/x2-x1)*x1
Then proceed as above, but work out the opposing oblique slope (original slope = m, perpendicular slope = 1/m) and the distance between the two will be sqrt((x2-x1)^2 + (y2-y1)^2) (i.e. Pythagoras)
(insert super maths here... I won't show my working because it's long winded.)

Code: Select all

--put this in card/stack script
global pDrawRect

on opencard --or openstack--
put "False" into pDrawRect
end opencard --or openstack--

--Draw a rectangle to act as a drawing area, and put this script on it:
global pDrawrect
local tInitialPoints

on mousedown
   if there is a grc "Square1" then delete grc "Square1"
   if there is a grc "Square2" then delete grc "Square2"
   if there is a grc "Square3" then delete grc "Square3"
   if there is a grc "Square4" then delete grc "Square4"
   if pDrawrect = "False" then
      put "true" into pDrawrect
      put empty into tInitialPoints
      put the mouseloc into tInitialPoints
   end if
end mousedown

on mouseup
   if pDrawrect = "True" then
      put empty into tEndPoints
      put empty into tRectPoints
      put the mouseloc into tEndPoints
      put tInitialPoints & comma & tEndPoints into tRectPoints
      set the style of the templateGraphic to "line"
      create grc "Square1"
      set the points of grc "Square1" to tRectPoints
      set the itemdel to comma
      put ((item 4 of tRectPoints - item 2 of tRectPoints)/(item 3 of tRectPoints - item 1 of tRectPoints)) into pSlope
      put (sqrt((item 3 of tRectPoints- item 1 of tRectPoints)^2+(item 4 of tRectPoints- item 2 of tRectPoints)^2)) into pDistance
      put comma & (item 3 of tRectPoints + (sqrt(pDistance^2/(1+((-(1/pSlope))^2))))) after tRectPoints
      put comma & (-(1/pSlope)*item 5 of tRectPoints+(item 4 of tRectPoints-(-(1/pslope)*item 3 of tRectPoints))) after tRectPoints
      put comma & (item 1 of tRectPoints + (sqrt(pDistance^2/(1+((-(1/pSlope))^2))))) after tRectPoints
      put comma & (-(1/pSlope)*item 7 of tRectPoints+(item 2 of tRectPoints-(-(1/pslope)*item 1 of tRectPoints))) after tRectPoints
      create grc "Square2"
      put item 3 of tRectPoints & comma & item 4 of tRectPoints & comma & item 5 of tRectPoints & comma & item 6 of tRectPoints into tLinePoints2
      set the points of grc "Square2" to tLinePoints2
      create grc "Square3"
      put item 5 of tRectPoints & comma & item 6 of tRectPoints & comma & item 7 of tRectPoints & comma & item 8 of tRectPoints into tLinePoints2
      set the points of grc "Square3" to tLinePoints2
      create grc "Square4"
      put item 7 of tRectPoints & comma & item 8 of tRectPoints & comma & item 1 of tRectPoints & comma & item 2 of tRectPoints into tLinePoints2
      set the points of grc "Square4" to tLinePoints2
   end if
   put "False" into pDrawRect
end mouseup
Save the stack and reopen so the initial true/false statement is placed into the pDrawRect- this will decide whether or not to draw something.
To use, click in a place, hold and drag the mouse to a new location, and a square will be drawn when you release.
There will most likely be an issue with the mouse moving one direction or another. I have code to sort this out, just not handy. You basically add a shuffling code that works out what order to put the points to make sure you don't run into maths issues. You also need to NOT move horizontally or vertically, as this creates a divide by zero error. Again, you can throw in some code to work out whether or not the x / y values are the same and handle those states differently of needs be.
Anyway... I have tried the code and it worked for me...
Hope that helped.
XdM

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9648
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: drawing squares

Post by dunbarx » Fri Mar 12, 2021 5:50 am

Hi.

If you start with the line graphic you mentioned, and put this in a button script:

Code: Select all

on mouseup
   clone grc 1
   revRotatePoly the long id of last grc,90
   set the topRight of last grc to the topLeft of grc 1
   
   clone grc 1
   revRotatePoly the long id of last grc,90
   set the topRight of last grc to the botRight of grc 1
   
   clone grc 1
   set the topleft of last grc to the botLeft of grc 2
end mouseup
We are using some simple built-in LC functionality to build a square. Surely some extra stuff might be added to be able to build the square the "other" way, that sort of thing.

Craig

Xero
Posts: 152
Joined: Sat Jun 23, 2018 2:22 pm

Re: drawing squares

Post by Xero » Fri Mar 12, 2021 10:33 am

Damn you Craig and your simpicity!!!
Ha ha ha.
Out of curiosity, does that work regardless of which way you move (L-R, top-Bottom, TL-BR, etc.) and does it work in oblique, not just orthogonal?
So if you have a line going top left to bottom right, and you are rotating it 90degrees around top right, does it spin off into space?
I have used a similar method to the way I did above to draw rectangles and it is laborious in relation to your method. I also have been drawing them in-real-time using a mousemove command, so I am wondering if your method may also work with my other script...
XdM

danielrr
Posts: 140
Joined: Mon Mar 04, 2013 4:03 pm

Re: drawing squares

Post by danielrr » Fri Mar 12, 2021 10:44 am

Very sweet, Xero, Cgraig. Nice birthday present. Since I'm using it on a didactic stack (in order to visually show Pythagoras theorem in action, I'll go for the first solution (since I need to calculate the areas and then do some stuff).

So, this is a draft of my approach. Draw a graphic (mine is three points thick), call it "hipotenusa" and create another graphic (again three points thick, but of a different colour, like blue) Call it "cuadradoHipotenusa".
Then put this code on the script of the first graphic (hipotenusa). Try dragging the vertices of this line while holding down the mouse

Code: Select all

on mouseDown
   global hipotenusa
   put the points of me into losPuntos
   put the mouseLoc into posicRaton
   put miraSiEstaEnElVertice(line 1 of losPuntos,posicRaton) into arriba
   if arriba
   then
      put false into abajo
   else
      put miraSiEstaEnElVertice(line 2 of losPuntos,posicRaton) into abajo
   end if
   if arriba then
      beep
      set cursor to plus
      put "arriba" into hipotenusa
   else if abajo then
      beep
      set cursor to plus
      put "abajo" into hipotenusa
   else
      put "" into hipotenusa
   end if
end mouseDown

on mouseLeave
   global hipotenusa
   if hipotenusa = "" then exit mouseLeave
   put the points of me into losPuntos
   put the mouseLoc into posicRaton
   put the rect of this card into elRect
   if item 1 of posicRaton < 1 then put 1 into item 1 of posicRaton
   if item 2 of posicRaton < 1 then put 1 into item 2 of posicRaton
   if item 1 of posicRaton >= item 3 of elRect then put (item 3 of elRect -1) into item 1 of posicRaton
   if item 2 of posicRaton >= item 4 of elRect then put (item 4 of elRect -1) into item 2 of posicRaton
   if hipotenusa = "arriba"
   then
      put line 2 of losPuntos into losPuntos
      checkPosition losPuntos,posicRaton
      set the points of me to posicRaton & return & losPuntos
   else
      put line 1 of losPuntos into losPuntos
      checkPosition losPuntos,posicRaton
      set the points of me to losPuntos & return & posicRaton
   end if
   put colocaCuadrado ("cuadradoHipotenusa",the points of me) into resultado
   put "" into hipotenusa
end mouseLeave

on checkPosition losPuntos,posicRaton
   if abs (item 1 of losPuntos - item 1 of posicRaton) < 10 then exit to top
   if abs (item 2 of losPuntos - item 2 of posicRaton) < 10 then exit to top
end checkPosition
   on mousewithin
   global hipotenusa
   if the mouse = up
   then
      put "" into hipotenusa
      pass mousewithin
   end if
end mousewithin

function colocaCuadrado  cuadrado,tRectPoints
   put line 1 of tRectPoints &","&line 2 of tRectPoints into tRectPoints
   set the itemdel to comma
   put ((item 4 of tRectPoints - item 2 of tRectPoints)/(item 3 of tRectPoints - item 1 of tRectPoints)) into pSlope
   put (sqrt((item 3 of tRectPoints- item 1 of tRectPoints)^2+(item 4 of tRectPoints- item 2 of tRectPoints)^2)) into pDistance
   put "," & (item 3 of tRectPoints + (sqrt(pDistance^2/(1+((-(1/pSlope))^2))))) after tRectPoints
   put "," & (-(1/pSlope)*item 5 of tRectPoints+(item 4 of tRectPoints-(-(1/pslope)*item 3 of tRectPoints))) after tRectPoints
   put "," & (item 1 of tRectPoints + (sqrt(pDistance^2/(1+((-(1/pSlope))^2))))) after tRectPoints
   put "," & (-(1/pSlope)*item 7 of tRectPoints+(item 2 of tRectPoints-(-(1/pslope)*item 1 of tRectPoints))) after tRectPoints
   put item 3 to 4 of tRectPoints & return & item 5 to 6 of tRectPoints & return & item 7 to 8 of tRectPoints & return &  \
         item 1 to 2 of tRectPoints into tRectPoints
   set the points of graphic "cuadradoHipotenusa" to tRectPoints
end colocaCuadrado

   
function miraSiEstaEnElVertice vertice,posicRaton
   --checks if the user is trying to move one of the vertices of the line
   put 7 into margen
   if abs (item 1 of vertice - item 1 of posicRaton) < margen
   then
      if abs (item 2 of vertice - item 2 of posicRaton) < margen
      then
         return true
      else
         return false
      end if
   else
      return false
   end if
end miraSiEstaEnElVertice

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9648
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: drawing squares

Post by dunbarx » Sat Mar 13, 2021 5:38 pm

Daniel.

I am not sure how to use your ideas. How do you drag the vertices of the line graphic in browse mode?

Craig

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9648
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: drawing squares

Post by dunbarx » Sat Mar 13, 2021 5:45 pm

Xero.

Code: Select all

Out of curiosity, does that work regardless of which way you move 
(L-R, top-Bottom, TL-BR, etc.) and does it work in oblique, not just orthogonal?
The small offering I made only works with a line graphic oriented slanting right and downward (this was the OP's original line), or for one vertical or horizontal. That is why I mentioned it needed tweaking if built "the other way", that is, sloping down to the left. I only spent about five minutes on this, but another five could be spent changing the "topLefts" to "topRights", or whatever is appropriate.

Craig

Post Reply

Return to “Getting Started with LiveCode - Complete Beginners”