Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C#
  4. Designing a shape object class in C#

Designing a shape object class in C#

Scheduled Pinned Locked Moved C#
csharpdesignquestion
5 Posts 4 Posters 10 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Stephen Holdorf
    wrote on last edited by
    #1

    Given a large number of shapes that can be defined by vertices and edges how would you design the class structure for that?

    B L 2 Replies Last reply
    0
    • S Stephen Holdorf

      Given a large number of shapes that can be defined by vertices and edges how would you design the class structure for that?

      B Offline
      B Offline
      BillWoodruff
      wrote on last edited by
      #2

      Hi, i happen to be working on a shape library for WinForms C# right now; i'll eventually publish it here, but, can't predict when. Let me offer some general ideas: 1) choice of Framework is important: a lot depends on what you want to do with your shapes. my usage is for custom ring design; for example, i need to calculate equally spaced points along a path like an oval, and that point's tangent (requires calculus); i deal primarily with polygons, circles and ellipses; my goal is to have mock-ups i can take to my manufacturers. so, i'm not concerned with 3d rendering on screen, texturing, etc. and i'm not concerned with interacting with selecting/moving/duplicating shapes on-screen as you expect in a drawing program, 2) for other purposes, like the ones i just said i'm not concerned with, WPF offers a superior graphics engine and facilities; and, for 3d; use Unity. if you do need to select/move/duplicate/dock etc., shapes on-screen: don't use WinForms, use WPF. 3) the interface i am using now: the use of System.Windows requires your WinForm project to have a reference to WindowsBase.dll

      using System;
      using System.Drawing;
      using System.Drawing.Drawing2D;
      using System.Windows;

      using SdPoint = System.Drawing.Point;
      using SwPoint = System.Windows.Point;
      using SdSize = System.Drawing.Size;
      using SwSize = System.Windows.Size;

      using GraphicsPath = System.Drawing.Drawing2D.GraphicsPath;
      using GReg = System.Drawing.Region;
      using GMat2d = System.Drawing.Drawing2D.Matrix;
      using GMatMed = System.Windows.Media.Matrix;

      namespace GeomLib_August_2021_III
      {
      public enum ShapeType
      {
      Line,
      Arc,
      Rectangle,
      Parallelogram,
      Circle,
      Ellipse,
      RegPolygon,
      IrregPolygon,
      Grid,
      Star
      }

      public interface IShape
      {
          string ShpName { get; }
          string ShpComment { get; }
          DateTime ShpTimeStamp { get; }
          ShapeType ShpType { get; }
      
          Rect SwRect { get; }
          SwPoint CenterF { get; }
          SwPoint\[\] PathPoints { get; }
      
          double GetArea();
          double GetPerimeter();
          SwPoint GetCenter();
          GraphicsPath GetGPath();
          Region GetRegion();
      
          IShape GetUnion(IShape s1, IShape s2);
          IShape GetIntersection(IShape s1, IShape s2);
      
          IShape Translate(IShape s1, Matrix m1);
          IShape Rotate(IShape s1, Matrix m1);
          IShape Scale(IShape s1, Matrix m1);
      
          SwPoint\[\] Flatten();
          void Ren
      
      P 1 Reply Last reply
      0
      • S Stephen Holdorf

        Given a large number of shapes that can be defined by vertices and edges how would you design the class structure for that?

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #3

        I find that "super" controls that you can morph at run time (color, scale, content) are more manageable than trying to build things from lots of primitives. You need a "focus"; e.g. military units already have many predefined shapes and derivatives. In architecture, there are door, window, etc. "patterns".

        It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

        1 Reply Last reply
        0
        • B BillWoodruff

          Hi, i happen to be working on a shape library for WinForms C# right now; i'll eventually publish it here, but, can't predict when. Let me offer some general ideas: 1) choice of Framework is important: a lot depends on what you want to do with your shapes. my usage is for custom ring design; for example, i need to calculate equally spaced points along a path like an oval, and that point's tangent (requires calculus); i deal primarily with polygons, circles and ellipses; my goal is to have mock-ups i can take to my manufacturers. so, i'm not concerned with 3d rendering on screen, texturing, etc. and i'm not concerned with interacting with selecting/moving/duplicating shapes on-screen as you expect in a drawing program, 2) for other purposes, like the ones i just said i'm not concerned with, WPF offers a superior graphics engine and facilities; and, for 3d; use Unity. if you do need to select/move/duplicate/dock etc., shapes on-screen: don't use WinForms, use WPF. 3) the interface i am using now: the use of System.Windows requires your WinForm project to have a reference to WindowsBase.dll

          using System;
          using System.Drawing;
          using System.Drawing.Drawing2D;
          using System.Windows;

          using SdPoint = System.Drawing.Point;
          using SwPoint = System.Windows.Point;
          using SdSize = System.Drawing.Size;
          using SwSize = System.Windows.Size;

          using GraphicsPath = System.Drawing.Drawing2D.GraphicsPath;
          using GReg = System.Drawing.Region;
          using GMat2d = System.Drawing.Drawing2D.Matrix;
          using GMatMed = System.Windows.Media.Matrix;

          namespace GeomLib_August_2021_III
          {
          public enum ShapeType
          {
          Line,
          Arc,
          Rectangle,
          Parallelogram,
          Circle,
          Ellipse,
          RegPolygon,
          IrregPolygon,
          Grid,
          Star
          }

          public interface IShape
          {
              string ShpName { get; }
              string ShpComment { get; }
              DateTime ShpTimeStamp { get; }
              ShapeType ShpType { get; }
          
              Rect SwRect { get; }
              SwPoint CenterF { get; }
              SwPoint\[\] PathPoints { get; }
          
              double GetArea();
              double GetPerimeter();
              SwPoint GetCenter();
              GraphicsPath GetGPath();
              Region GetRegion();
          
              IShape GetUnion(IShape s1, IShape s2);
              IShape GetIntersection(IShape s1, IShape s2);
          
              IShape Translate(IShape s1, Matrix m1);
              IShape Rotate(IShape s1, Matrix m1);
              IShape Scale(IShape s1, Matrix m1);
          
              SwPoint\[\] Flatten();
              void Ren
          
          P Offline
          P Offline
          Pete OHanlon
          wrote on last edited by
          #4

          Good morning Bill. Thanks for posting this code - it's great to see people sharing code like this. I have a couple of comments that I'd like to address. The code sample here has a lot of shorthand in it so things like GetGPath have to be interpreted. Is there a reason why this isn't called GetGraphicsPath or just GetPath? On that note, why have you chosen to implement Get methods over property getters? I'm just curious as to your reasoning here. The Shp properties all feel like they should be in a separate class. Again, it feels to me like these are metadata items, rather than being intrinsic parts of the base interface. I would probably move these out into a separate metadata class and drop the Shp parts of the name. The Union and Intersection methods also appear to be wrong, unless you are looking to determine whether this shape intersects with more than one shape - the first parameter of these methods is probably going to be the current instance so why pass it in? I would expect to see a method that looks more like this

          IShape Union(IShape shape);

          Advanced TypeScript Programming Projects

          B 1 Reply Last reply
          0
          • P Pete OHanlon

            Good morning Bill. Thanks for posting this code - it's great to see people sharing code like this. I have a couple of comments that I'd like to address. The code sample here has a lot of shorthand in it so things like GetGPath have to be interpreted. Is there a reason why this isn't called GetGraphicsPath or just GetPath? On that note, why have you chosen to implement Get methods over property getters? I'm just curious as to your reasoning here. The Shp properties all feel like they should be in a separate class. Again, it feels to me like these are metadata items, rather than being intrinsic parts of the base interface. I would probably move these out into a separate metadata class and drop the Shp parts of the name. The Union and Intersection methods also appear to be wrong, unless you are looking to determine whether this shape intersects with more than one shape - the first parameter of these methods is probably going to be the current instance so why pass it in? I would expect to see a method that looks more like this

            IShape Union(IShape shape);

            Advanced TypeScript Programming Projects

            B Offline
            B Offline
            BillWoodruff
            wrote on last edited by
            #5

            Hi Pete, i'm delighted to have feedback like this ! I'll study it carefully, and respond in more detail later. current version calculating equally spaced points points on an ellipse: [^] Context: currently this is very much in initial development, and, "final polishing" may address your concerns about my use of short aliases instead of longer, more mnemonic, names. For unknown reasons, my memory, at age 78, handles such short aliases without cognitive effort (just don't ask me where i left my house keys) ... and, it saves typing time :omg:

            Quote:

            The Shp properties all feel like they should be in a separate class. Again, it feels to me like these are metadata items, rather than being intrinsic parts of the base interface. I would probably move these out into a separate metadata class and drop the Shp parts of the name.

            Excellent points ! As the design progresses, i may "break out" the IShape interface into component interfaces like IIdentity for ShpName, ShpComment, ShpTimeStamp (those i would call "metadata"). Right now, things like SwPoint, CenterF seem essential. "Shp" as prefix: I often "go Hungarian" simply because when i view an object's contents at run-time when a breakpoint is hit, they appear grouped together in the alpha-ordered inspector dropdown, Same idea with public Properties i want exposed in a design-time PropertyGrid. 'Get methods instead of Property getters: somewhere along the line years ago (influenced by Richter ?), i decided to never do extensive calculations, or call external methods, in Properties (except for OnPropertyChanged). That "feels right," and, i believe that contributes to maintainability in the long run ... perhaps i should reevaluate that "habit/decision" ?

            Quote:

            The Union and Intersection methods also appear to be wrong, unless you are looking to determine whether this shape intersects with more than one shape - the first parameter of these methods is probably going to be the current instance so why pass it in?

            As of now, i have not implemented any "current ..." state/object facility. That is something I really like ever since my little career led me into specializing in PostScript. My intent is to take two shape instances as input, and return a new shape which is the intersection/union of the two

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups