drawing squares
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller
drawing squares
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?
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?
Re: drawing squares
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.)
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
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
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
-
- VIP Livecode Opensource Backer
- Posts: 9648
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: drawing squares
Hi.
If you start with the line graphic you mentioned, and put this in a button script:
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
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
Craig
Re: drawing squares
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
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
Re: drawing squares
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
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
-
- VIP Livecode Opensource Backer
- Posts: 9648
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: drawing squares
Daniel.
I am not sure how to use your ideas. How do you drag the vertices of the line graphic in browse mode?
Craig
I am not sure how to use your ideas. How do you drag the vertices of the line graphic in browse mode?
Craig
-
- VIP Livecode Opensource Backer
- Posts: 9648
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: drawing squares
Xero.
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
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?
Craig