This project is read-only.

Creating a rectangle

Nov 4, 2010 at 5:42 PM

Hi Kirill,

I have been working with the Live Geometry code base for a few months.  I have studied all layers and objects and code flow.  I am so impressed with your work.  I've also studied the elegant "Undo" library, which works surprisingly well.  So, thank you very much for open sourcing your code.  I don't think I could have learned as much as I have about drawing shapes if not for your code.

I am struggling with how to convert "drawing a square" to "drawing a rectangle".  The "points" that are used in a box have special functionality where they auto expand to keep the true shape of a square.  That's terrific ... for squares :-) ... but, how can I go about modifying that pattern to allow a user to draw a rectangle (or trapazoid).  I understand the different polygon objects, but, those are too free form.  I want to preserve the shape of a rectangle no matter how the user moves the points or lines.

Your time and effort are evident in this fine project.  I need you to know that I really appreciate all you've done.

Best regards,

Chris

Nov 8, 2010 at 6:27 AM
Edited Nov 8, 2010 at 6:55 AM

Hi Chris,

sorry for the delayed reply. Take a look at this drawing (save as .LGF and load in http://livegeometry.com) and tell me if this is what you're looking for:

<?xml version="1.0" encoding="utf-8"?>
<Drawing>
  <Viewport Left="-19.9375000001" Top="7.4583333334" Right="19.9791666668" Bottom="-7.4375" />
  <Styles>
    <PointStyle Size="10" Fill="#FFFFFF00" IsFilled="true" Color="#FF000000" StrokeWidth="1" Name="1" />
    <PointStyle Size="10" Fill="#FF00FF00" IsFilled="true" Color="#FF000000" StrokeWidth="1" Name="2" />
    <PointStyle Size="10" Fill="#FFC0C0C0" IsFilled="true" Color="#FF000000" StrokeWidth="1" Name="3" />
    <LineStyle Color="#FF000000" StrokeWidth="1" Name="4" />
    <ShapeStyle Fill="#FFFFFF00" IsFilled="true" Color="#00FFFFFF" StrokeWidth="1" Name="5" />
    <ShapeStyle Fill="#FFFFFF00" IsFilled="true" Color="#FF000000" StrokeWidth="1" Name="6" />
    <TextStyle FontSize="18" Color="#FF000000" FontFamily="Arial" Bold="false" Italic="false" Underline="false" Name="7" />
    <TextStyle FontSize="18" Color="#FF000000" FontFamily="Arial" Bold="false" Italic="false" Underline="false" Name="8" />
    <ShapeStyle Fill="#FF22FF00" IsFilled="true" Color="#00FFFFFF" StrokeWidth="1" Name="9" />
  </Styles>
  <Figures>
    <FreePoint Name="A" Style="1" X="-11" Y="-0.9166666667" />
    <FreePoint Name="B" Style="1" X="-7.0833333334" Y="-2.1666666667" />
    <Segment Name="Segment8" Style="4">
      <Dependency Name="A" />
      <Dependency Name="B" />
    </Segment>
    <PerpendicularLine Name="PerpendicularLine10" Visible="false" Style="4">
      <Dependency Name="Segment8" />
      <Dependency Name="A" />
    </PerpendicularLine>
    <PointOnFigure Name="C" Style="2" X="-9.9683101553635" Y="2.315961513106" Parameter="-0.825351875709198">
      <Dependency Name="PerpendicularLine10" />
    </PointOnFigure>
    <ParallelLine Name="ParallelLine12" Visible="false" Style="4">
      <Dependency Name="PerpendicularLine10" />
      <Dependency Name="B" />
    </ParallelLine>
    <ParallelLine Name="ParallelLine14" Visible="false" Style="4">
      <Dependency Name="Segment8" />
      <Dependency Name="C" />
    </ParallelLine>
    <IntersectionPoint Name="D" Style="3" Algorithm="IntersectLineAndLine">
      <Dependency Name="ParallelLine14" />
      <Dependency Name="ParallelLine12" />
    </IntersectionPoint>
    <Polygon Name="Polygon31" Style="9">
      <Dependency Name="A" />
      <Dependency Name="C" />
      <Dependency Name="D" />
      <Dependency Name="B" />
    </Polygon>
    <Segment Name="Segment32" Style="4">
      <Dependency Name="A" />
      <Dependency Name="C" />
    </Segment>
    <Segment Name="Segment33" Style="4">
      <Dependency Name="C" />
      <Dependency Name="D" />
    </Segment>
    <Segment Name="Segment34" Style="4">
      <Dependency Name="D" />
      <Dependency Name="B" />
    </Segment>
    <FreePoint Name="E" Style="1" X="-3.7708333335" Y="0.8541666667" />
    <PointByCoordinates Name="F" Visible="false" Style="1" X="E.X+1" Y="E.Y">
      <Dependency Name="E" />
    </PointByCoordinates>
    <LineTwoPoints Name="LineTwoPoints36" Visible="false" Style="4">
      <Dependency Name="E" />
      <Dependency Name="F" />
    </LineTwoPoints>
    <PointOnFigure Name="G" Style="2" X="3.6874999998" Y="0.8541666667" Parameter="7.4583333333">
      <Dependency Name="LineTwoPoints36" />
    </PointOnFigure>
    <PerpendicularLine Name="PerpendicularLine40" Visible="false" Style="4">
      <Dependency Name="LineTwoPoints36" />
      <Dependency Name="G" />
    </PerpendicularLine>
    <PointOnFigure Name="H" Style="2" X="3.6874999998" Y="2.7291666667" Parameter="-1.875">
      <Dependency Name="PerpendicularLine40" />
    </PointOnFigure>
    <ParallelLine Name="ParallelLine42" Visible="false" Style="4">
      <Dependency Name="PerpendicularLine40" />
      <Dependency Name="E" />
    </ParallelLine>
    <ParallelLine Name="ParallelLine44" Visible="false" Style="4">
      <Dependency Name="LineTwoPoints36" />
      <Dependency Name="H" />
    </ParallelLine>
    <IntersectionPoint Name="I" Style="3" Algorithm="IntersectLineAndLine">
      <Dependency Name="ParallelLine44" />
      <Dependency Name="ParallelLine42" />
    </IntersectionPoint>
    <Polygon Name="Polygon61" Style="5">
      <Dependency Name="E" />
      <Dependency Name="I" />
      <Dependency Name="H" />
      <Dependency Name="G" />
    </Polygon>
    <Segment Name="Segment62" Style="4">
      <Dependency Name="E" />
      <Dependency Name="I" />
    </Segment>
    <Segment Name="Segment63" Style="4">
      <Dependency Name="I" />
      <Dependency Name="H" />
    </Segment>
    <Segment Name="Segment64" Style="4">
      <Dependency Name="H" />
      <Dependency Name="G" />
    </Segment>
    <Segment Name="Segment65" Style="4">
      <Dependency Name="G" />
      <Dependency Name="E" />
    </Segment>
  </Figures>
</Drawing>
The secret is in using a point on a figure (PointOnFigure). You can create one by selecting the point tool and clicking on a line or any other figure.

Let me know if this helps.

Kirill 

Nov 9, 2010 at 5:21 AM

Hi Kirill,

Thank you for taking the time to put together this sample.  This is "exactly" what I'm looking for.  Well, actually, a combination of both the green and yellow rectangles is what is desired.  Let me explain, the yellow rectangle is nicely resizable independently by width and height while still keeping the rigid structure of a rectangle.  Awesome!  However, it doesn't rotate like the green rectangle does.  So, I like the features of the yellow rectangle because of the way it resizes width and height independently.  However, I like the ability to rotate the rectangle aS with the green one.

I studied your suggestion "The secret is in using a point on a figure (PointOnFigure). You can create one by selecting the point tool and clicking on a line or any other figure.".  Sadly, I wasn't able to get the PointOfFigure to stick.  Let me outline my steps so I can see where I am going wrong:

1) Click "Shapes" icon tab
2) Select "Square"
3) Draw a square.
4) Select "Points" icon tab
5) Select "Point"
6) Click inside one of the points of the square (one of the points that resizes the square).
7) I give the new point a style of green.
8) This doesn't seem to have any effect.

I've also tried putting a point on one of the segments, but, the point simply slides up and down the segment.

I studied the .LGF file and I see where each PointOnFigure node has a Dependency node.  But, I don't know how to make PointOnFigure alter the resizing of the square.

I had hoped I could tell you "I got it!" ... but, I wasn't able to reproduce your sample.

Any additional instructions would be greatly appreciated.

Best regards,

Chris

Nov 9, 2010 at 7:19 AM
Don't start with a square :)
 
1. Draw a point
2. Draw another point
3. Connect 1 and 2 with a Ray or a Line (doesn't matter)
4. Draw a perpendicular line to line 3 and passing through point 1
5. Select the Point tool and click anywhere on line 3 (it will create a PointOnFigure)
6. Select the Point tool and click anywhere on line 4
7. Draw a parallel line to line 3 passing through point 6
8. Draw a parallel line to line 4 passing through point 5
9. Select the Point tool and click in the intersection of line 7 and line 8
10. Ctrl+Click to select line 3, line 4, line 7, line 8
11. In the properties grid deselect the Visible checkbox to hide the auxiliary lines
12. Use the Polygon tool to connect points 1, 5, 6, and 9
 
If you look at the XML more closely, the algorithm is encoded right there, step by step - dependencies for a perpendicular line, for example, mean a line and a point. The Point tool is used for "free points", points on figures and intersection points, depending on whether you click on zero figures, one figure or two figures.
 
Hope this helps!
Kirill
Nov 9, 2010 at 4:43 PM

Thanks for your reply Kirill.  It seems like I was way off! :-)… I will apply your recommendation (above) and study the xml .lgf file even more to see the sequence of events (as you suggest). Once I get this down I would be very interested to know how to develop a macro (as you mentioned in your email).  My goal is to allow a user to see a "rectangle icon" and drag and drop it onto the drawing canvas and have the rectangle constructed automatically.  

Also, in your original sample there were two rectangles, green and yellow.  The yellow rectanlge was ideal, but, did not rotate (like the green one).  What enables the green rectangle to rotate?

Best regards,

Chris