I am making a paint program where i can make Rectangle/Ellipse. In that program i can move/resize them but also save them.
My problem is now that i need to make a visitor pattern(Resize/Move and save) But I don't know where i should start.
These are the method i use at the moment:
public abstract void ResizeShape(PosSizableRect posSizableRect, float lastX, float lastY, float newX, float newY);
public abstract void MoveShape(int x, int y);
private void Write(List<Shape> shapes, StreamWriter streamWriter, string tabs = "")
sorry can't give you pictures because of my reputation...
public interface IShape
{
void Resize(PosSizableRect posSizableRect, float lastX, float lastY, float newX, float newY);
void Move(int dx, int dy);
void Write (StreamWriter writer, string tabs ="");
void AcceptVisitor(IVisitor visitor);
}
public interface IVisitor
{
void Visit(IShape shape);
}
Thats the interfaces, now the implementation (one example)
public class MoveVisitor : IVisitor
{
private int dx;
private int dy;
public MoveVisitor(int dx, int dy)
{
this.dx = dx;
this.dy = dy;
}
public void Visit(IShape shape)
{
shape.Move(dx,dy);
}
}
Related
It makes sense that I should not call an overridden function from a base constructor, since the derived class is not yet constructed.
But I want to use this design pattern, where each derived class provides methods for calculating the properties of the base class since the properties should be immutable and assigned at the constructor.
Shape.cs
public abstract class Shape
{
protected Shape()
{
Area = 0f;
Center = Vector2.Zero;
const int n = 36;
float du = 1/(float)n, dv = 1/(float)n;
for (int i = 0; i < n; i++)
{
float u = (i+0.5f)*du;
for (int j = 0; j < n; j++)
{
float v = (i+0.5f)*dv;
float f = GetAreaElement(u, v);
// Warning: Remove this call from a constructor to the overridable 'GetAreaElement' method.
Area += f*du*dv;
Center += GetPosition(u, v)*f*du*dv;
// Warning: Remove this call from a constructor to the overridable 'GetPosition' method.
}
}
Center /= Area;
}
public abstract Vector2 GetPosition(float u, float v);
protected abstract float GetAreaElement(float u, float v);
public float Area { get; }
public Vector2 Center { get; }
}
public class Circle : Shape
{
public Circle(float radius)
{
Radius=radius;
}
public float Radius { get; }
public override Vector2 GetPosition(float u, float v)
{
float r = u*Radius, θ = (float)(2*Math.PI)*v;
return new Vector2(
r*(float)Math.Cos(θ),
r*(float)Math.Sin(θ));
}
protected override float GetAreaElement(float u, float v)
{
return u*Radius;
}
}
public class Rectangle : Shape
{
public Rectangle(float side1, float side2)
{
Side1=side1;
Side2=side2;
}
public float Side1 { get; }
public float Side2 { get; }
public override Vector2 GetPosition(float u, float v)
{
return new Vector2((u-0.5f)*Side1, (v-0.5f)*Side2);
}
protected override float GetAreaElement(float u, float v)
{
return Side1*Side2;
}
}
So what is the solution here? I want to use the base constructor to define the properties, and the calculation depends on the implementation of the derived class.
Workaround 1 - Future calculator
A workaround would be to provide a protected function that calculates the properties, each to be called from each constructor of the derived class, but there is no enforcement here. If one class forgets to call the calculator function the whole thing falls apart. And the properties are now private set which is not immutable really.
public abstract class Shape
{
protected void Calculate()
{
...
float f = GetAreaElement(u, v);
...
Center += GetPosition(u, v)*f*du*dv;
...
}
public abstract Vector2 GetPosition(float u, float v);
protected abstract float GetAreaElement(float u, float v);
public float Area { get; private set; }
public Vector2 Center { get; private set; }
}
public class Circle : Shape
{
public Circle(float radius)
{
Radius=radius;
base.Calculate();
}
public float Radius { get; }
public override Vector2 GetPosition(float u, float v)
{
...
}
protected override float GetAreaElement(float u, float v)
{
...
}
}
Workaround 2 - Function delegates
Another workaround would be to supply the delegates to the required function implementations as arguments to the base class constructor.
public delegate float AreaFactor(float u, float v);
public delegate Vector2 PositionFunc(float u, float v);
public abstract class Shape
{
protected Shape(AreaFactor a, PositionFunc p)
{
this.GetAreaElement = a;
this.GetPosition = p;
...
float f = a(u, v);
this.Center += p(u, v)*f*du*dv;
...
}
public float Area { get; }
public Vector2 Center { get; }
public AreaFactor GetAreaElement { get; }
public PositionFunc GetPosition { get; }
}
public class Circle : Shape
{
public Circle(float radius)
: base(
(u, v) => u*radius,
(u,v)=>
{
float r = u*radius, θ = (float)(2*Math.PI)*v;
return new Vector2(
r*(float)Math.Cos(θ),
r*(float)Math.Sin(θ));
})
{
Radius=radius;
}
public float Radius { get; }
}
This seems a bit clunky to me, and I am not sure I like the function delegate properties, instead of overridden methods.
Question/Challege
Can [SO] provide some other ways of achieving the above-stated goals
Base properties are immutable
Base properties are calculated at the constructor based on the implementation details of the derived classes.
Each derived class holds its own immutable properties used to describe the derived class.
One option is to, instead of calculating the Area and Center in the constructor, lazily calculate them in the property getter. It will require a backing field to know if the property has been calculated or not, but it will get rid of the warning.
It also seems odd to me that you don't pass the center to the Shape constructor, but I don't fully understand the design you're using.
My preference is to go with Option 2 - passing to the base constructor the methods to generate the derived properties. It does satisfy all your requirements. If aesthetics is a concern, perhaps using a Func might make the code easier to read. The key is that the Func's are static methods, which should not be a problem since they calculate immutable properties of the object.
void Main()
{
var square = new Square(5);
}
public abstract class Shape
{
protected Shape(Func<int> areaFunc)
{
Area = areaFunc();
}
public int Area { get; }
}
public class Square : Shape
{
public Square(int side): base( () => CalcArea(side) )
{
Side = side;
}
static int CalcArea(int side) => side * side;
public int Side { get; }
}
I am trying to learn c# and in c# I am trying to implement a factory design pattern to draw basic shapes like circle, rectangle, triangle, etc. I created a IShape Interface class. And other three Circle, Rectangle, and Triangle class. I also created a ShapeFactory static method. These classes sould be called after from compiler class and draw in another window i.e Output window. Below is the code.
//IShape Class
namespace CPaint.Class
{
public interface IShape
{
void Draw();
}
}
//Cicle Class
namespace CPaint.Class
{
internal class Circle : IShape
{
//public Output outputWindow;
private float x;
private float y;
private Color color;
private float radius;
private Graphics graphics;
public Circle(Color color, float x, float y, float radius)
{
this.color = color;
this.x = x;
this.y = y;
this.radius = radius;
}
public void Draw()
{
Pen pen = new Pen(Color.Black, 4);
SolidBrush brush = new SolidBrush(color);
graphics.FillEllipse(brush, x, y, radius, radius);
graphics.DrawEllipse(pen, x, y, radius, radius);
}
}
}
//Triangle class
namespace CPaint.Class
{
internal class Triangle : IShape
{
private float x;
private float y;
private Color color;
private float side1;
private float side2;
private float side3;
public Triangle(Color color, float x, float y, float side1, float side2, float side3)
{
this.color = color;
this.x = x;
this.y = y;
this.side1 = side1;
this.side2 = side2;
this.side3 = side3;
}
public void Draw()
{
//will write drawing code here...
}
}
}
//Shape Factory Class
namespace CPaint.Class
{
public class ShapeFactory
{
public static IShape GetShape(string shapeType, Color color, float x, float y, float height, float width, float radius, float side1, float side2, float side3)
{
if (shapeType == null)
{
return null;
}
if (shapeType.Equals("circle"))
{
return new Circle(color, x, y, radius);
}
else if (shapeType.Equals("rectangle"))
{
return new Rectangle(color, x, y, height, width); ;
}
else if (shapeType.Equals("triangle"))
{
return new Triangle(color, x, y, side1, side2, side3);
}
else
{
return null;
}
}
}
}
//Compiler Class
if (code[0].Trim().ToLower().Equals("circle"))
{
try
{
int parameter1 = Int32.Parse(code[1]);
IShape shape = ShapeFactory.GetShape("circle", color, initX, initY, 0, 0, parameter1, 0, 0, 0);
outputWindow.Show();
//outputWindow.outputArea.Image=new ShapeFactory.GetShape("circle", color, initX, initY, 0, 0, parameter1, 0, 0, 0);
//outputWindow.outputArea.Image = shape;
output = "command executed successfully: parameter is" + parameter1;
//output = "is numeric ";
}
catch (Exception ex)
{
Console.WriteLine("Exception Message: " + ex.Message);
output = "\n Parameter Error : Invalid/Insufficient Parameter. \n";
}
}
Here in Compiler class, I want to open output window by outputWindow.show(); and then draw the shape in window by outputWindow.OutputArea.Image=...
I got stuck. Please help.
This post explains differences between
Factory,
Factory Method, and
Abstract Factory
design patterns.
Since you want to be able to create a whole family of objects that need to be of "the same kind", this can be done with Abstract Factory pattern.
The factory can have multiple creator methods. You can add parameters to the creator method(s) of the factory.
IShapesFactory.cs is the interface of the Abstract Factory:
public interface IShapesFactory
{
Circle MakeCircle(Color color, float x, float y, float radius);
Triangle MakeTriangle(Color color, float x, float y, float side1, float side2, float side3);
}
The implementation of the factory would handle passing the Graphics object to the shapes it creates.
ShapeFactory.cs
public class ShapeFactory: IShapeFactory
{
private Graphics _graphics;
public ShapeFactory(Graphics graphics)
{
_graphics = graphics;
}
public Circle MakeCircle(Color color, float x, float y, float radius)
{
// pass the Graphics object in the constructor of Circle
return new Circle(_graphics, color, x, y, radius);
}
[..other methods of the factory interface]
}
The factory in use:
IShapeFactory factory = new ShapeFactory(graphics);
var circle = factory.MakeCircle(Color.Blue, 10, 10, 20);
circle.Draw();
Consider the following code:
public struct Vector2
{
public float X;
public float Y;
}
public class Sprite
{
private Vector2 position;
public ref Vector2 Position => ref position;
private void DoStuffWhenPositionChanges() { /*...code...*/ }
}
The ref return allows me to do the following set operations:
someSprite.Position.X++;
someSprite.Position.Y = 42;
I would like to invoke DoStuffWhenPositionChanges whenever either the X or Y components of the Position struct are set. Note, Vector2 is a library-level struct, and cannot be changed in my code.
I am looking for a solution similar to:
public class Sprite
{
private Vector2 position;
public Vector2 Position
{
get => position; //ref return not possible!
set
{
position = value;
DoStuffWhenPositionChanges();
}
}
private void DoStuffWhenPositionChanges() { /*...code...*/ }
}
...but with a ref return, to avoid having to do the following in the calling code:
someSprite.Position = new Vector2(someSprite.Position.X, someSprite.Position.Y + 1);
I've considered INotifyPropertyChanged, but as I cannot modify the library-level Vector2 struct, I need an alternative solution. I also considered a proxy type, implicitly convertible to Vector2, that would implement INotifyPropertyChanged, but that seems ...cumbersome; perhaps there's a cleaner solution I am not aware of.
Is it possible to know when the underlying value of the ref return property changes, given the above setup?
One way is to create a wrapper for Struct and then implement RaisePropertyChanged method or INotifyPropertyChanged:
public struct Vector2
{
public float X;
public float Y;
}
public class VectorWrapper
{
private Vector2 thing;
public var X
{
get { return thing.X; }
set { thing.X = value; RaisePropertyChanged(SomePropertyName); }
}
public var Y
{
get { return thing.Y; }
set { thing.Y = value; RaisePropertyChanged(SomePropertyName); }
}
}
It's a bit of a hack but this will get the job done.
static void Main(string[] args)
{
var s = new Sprite();
s.DoStuffWhenPositionChanges(s.Position.X++);
}
public struct Vector2
{
public float X;
public float Y;
}
public class Sprite
{
private Vector2 position;
public ref Vector2 Position => ref position;
public void DoStuffWhenPositionChanges(float f = default)
{
}
}
I wanted to start developing an opengl basic game. After some coding i ran into an error.
I wanted to add a projection matrix and after I created it, the rendered image went white and even the transformation matrix didn't work correctly.
I tested the location IDs with GL.GetUniformLocation(Variable Names) and both of them were -1.
The way I add the projection matrix:
projectionMatrix = Matrix4.CreatePerspectiveFieldOfView((float)(Math.PI / 180) * FOV, aspectRatio, NEAR_PLANE, FAR_PLANE);
The way I add the transformation matrix:
Matrix4 matrix = Matrix4.CreateRotationX(MathHelper.DegreesToRadians(rx)) * Matrix4.CreateRotationY(MathHelper.DegreesToRadians(ry)) * Matrix4.CreateRotationZ(MathHelper.DegreesToRadians(rz));
Matrix4 translationsMatrix = Matrix4.CreateTranslation(translation);
Matrix4 scaleMatrix = Matrix4.CreateScale(scale);
matrix *= scaleMatrix;
matrix *= translationsMatrix;
This(the transformation matrix) works fine by it's own.
And here is my renderer class:
TexturedModel texturedModel = entity.Model;
RawModel model = texturedModel.Model;
GL.BindVertexArray(model.VaoID);
GL.EnableVertexAttribArray(0);
GL.EnableVertexAttribArray(1);
Matrix4 transformationMatrix = Maths.CreateTransformationMatrix(entity.Position, entity.RotationX, entity.RotationY, entity.RotationZ, entity.Scale);
shader.LoadTransformationMatrix(transformationMatrix);
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, texturedModel.Texture.ID);
GL.DrawElements(PrimitiveType.Triangles, model.VertexCount, DrawElementsType.UnsignedInt, 0);
GL.DisableVertexAttribArray(0);
GL.DisableVertexAttribArray(1);
GL.BindVertexArray(0);
Why does it behave like this and how can I "fix" it?
EDIT
Here are my shader codes. (I have forgotten them previously)
VertexShader:
#version 400 core
in vec3 position;
in vec2 textureCoords;
out vec2 pass_textureCoords;
uniform mat4 transformationMatrix;
unfiorm mat4 projectionMatrix;
void main(void){
gl_Position = projectionMatrix * transformationMatrix * vec4(position, 1.0);
pass_textureCoords = textureCoords;
}
Abstract Shader Class:
abstract class ShaderProgram
{
private int programID;
private int vertexShaderID;
private int fragmentShaderID;
public ShaderProgram(string vertexShaderFile, string fragmentShaderFile)
{
vertexShaderID = LoadShader(vertexShaderFile, ShaderType.VertexShader);
fragmentShaderID = LoadShader(fragmentShaderFile, ShaderType.FragmentShader);
programID = GL.CreateProgram();
GL.AttachShader(programID, vertexShaderID);
GL.AttachShader(programID, fragmentShaderID);
BindAttributes();
GL.LinkProgram(programID);
GL.ValidateProgram(programID);
GetAllUniformLocations();
}
protected abstract void GetAllUniformLocations();
protected int GetUniformLocation(string uniformName)
{
return GL.GetUniformLocation(programID, uniformName);
}
public void Start()
{
GL.UseProgram(programID);
}
public void Stop()
{
GL.UseProgram(0);
}
public void CleanUp()
{
Stop();
GL.DetachShader(programID, vertexShaderID);
GL.DetachShader(programID, fragmentShaderID);
GL.DeleteShader(vertexShaderID);
GL.DeleteShader(fragmentShaderID);
GL.DeleteProgram(programID);
}
protected abstract void BindAttributes();
protected void BindAttribute(int attribute, string variableName)
{
GL.BindAttribLocation(programID, attribute, variableName);
}
protected void LoadFloat(int location, float value)
{
GL.Uniform1(location, value);
}
protected void LoadVector(int location, Vector3 vector)
{
GL.Uniform3(location, vector);
}
protected void LoadBoolean(int location, bool value)
{
GL.Uniform1(location, value ? 1 : 0);
}
protected void LoadMatrix(int location, Matrix4 matrix)
{
GL.UniformMatrix4(location, false, ref matrix);
}
private static int LoadShader(String file, ShaderType type)
{
string shaderSource = File.ReadAllText(file);
int shaderID = GL.CreateShader(type);
GL.ShaderSource(shaderID, shaderSource);
GL.CompileShader(shaderID);
return shaderID;
}
}
Static Shader:
class StaticShader : ShaderProgram
{
private static string vertexFile = "f/shaders/vertexShader.txt";
private static string fragmentFile = "f/shaders/fragmentShader.txt";
private int location_transformationMatrix;
private int location_projectionMatrix;
public StaticShader()
: base(vertexFile, fragmentFile)
{
}
protected override void BindAttributes()
{
base.BindAttribute(0, "position");
base.BindAttribute(1, "textureCoords");
}
protected override void GetAllUniformLocations()
{
location_transformationMatrix = base.GetUniformLocation("transformationMatrix");
location_projectionMatrix = base.GetUniformLocation("projectionMatrix");
}
public void LoadTransformationMatrix(Matrix4 matrix)
{
base.LoadMatrix(location_transformationMatrix, matrix);
}
public void LoadProjectionMatrix(Matrix4 projection)
{
base.LoadMatrix(location_projectionMatrix, projection);
}
}
I am trying to have a C++ function call a method on a form in C# in order to update the GUI. For some reason, the function call from C++ sends the parameters in reversed order.
So the UpdateDROCallback() function gets 3.0 for the first parameter, 2.0 for the second, and 1.0 for the last when it was called with function(1.0, 2.0, 3.0).
What am I missing here?
[C#]
public partial class Form1 : Form
{
delegate void DROUpdateDelegate(double x, double y, double z);
DROUpdateDelegate m_DROUpdateDelegate;
static DROUpdateDelegate s_DROUpdateDelegate;
public Form1()
{
InitializeComponent();
m_DROUpdateDelegate = new DROUpdateDelegate(UpdateDROCallback);
s_DROUpdateDelegate = new DROUpdateDelegate(UpdateDRO);
}
private void btnGo_Click(object sender, EventArgs e)
{
int address = m_DROUpdateDelegate.Method.MethodHandle.GetFunctionPointer().ToInt32();
TestDll.RegisterScaleUpdateCallback(address);
}
private static void UpdateDROCallback(double x, double y, double z)
{
s_DROUpdateDelegate(x, y, z);
}
private void UpdateDRO(double x, double y, double z)
{
BeginInvoke(
new Action(
() =>
{
lblDROX.Text = x.ToString("0.0000");
lblDROY.Text = y.ToString("0.0000");
lblDROZ.Text = z.ToString("0.0000");
}));
}
}
TestDll.cs:
public static class TestDll
{
(...)
[DllImport("test.dll", EntryPoint = "RegisterScaleUpdateCallback")]
public static extern void RegisterScaleUpdateCallback(int address);
(...)
}
[C++]
StrobeTest.h:
#pragma once
class StrobeTest
{
typedef void (__stdcall *DROUpdate)(double x, double y, double z);
private:
static DROUpdate s_CallbackFunction;
public:
StrobeTest(void);
~StrobeTest(void);
static void InitializeStrobe(void);
static void MoveXAtSpeed(double velocity);
static void CALLBACK RegisterScaleUpdateCallback(DROUpdate function);
};
StrobeTest.cpp
(...)
void StrobeTest::RegisterScaleUpdateCallback(DROUpdate function)
{
StrobeTest::s_CallbackFunction = function;
StrobeTest::s_CallbackFunction(1.0, 2.0, 3.0);
}
(...)
Show the code of TestDll, especially the declaration of TestDll.RegisterScaleUpdateCallback in it. There will be the cause. Make sure that the calling conventions match.