Is it possible to have some variable shared between some objects of the same class such that, when the value is changed in one object, it will also change in the other object? Static variables would not work in this case, because there could be 2 objects that all have some related variable and another 2 objects that have a different related variable.
For example, say I have 4 squares that are arranged to make one large square, and the squares coordinates lie in an x,y,z plane. When the 4 squares are together, they would all have a point that lies in the center of the biggest square.
Pretend this square also has a z coordinate. Now, the squares will all share the point that lies in the center. The top left square's bottom right corner, the top right square's bottom left corner, etc., will all have the same (x, y, z) value.
Now what I want, is such that if the z value of one square changes, they will all change without any extra code, like they all point to the same memory location, so they "automatically" update in a sense.
Is something like this possible?
Here is one way you could do this. Each square's data property is pointing to the same reference.
class Square
{
private SharedData Data;
public Square(SharedData data)
{
this.Data = data;
}
}
class SharedData
{
public double Z { get; set; }
}
SharedData data = new SharedData() { Z = 100.0 }
Square topLeft = new Square(data);
Square topRight = new Square(data);
Square bottomLeft = new Square(data);
Square bottomRight = new Square(data);
You can put SharedData behind an interface that provides read-only access to the squares if you wish. If the squares are not supposed to modify the value of Z this would be a safer approach.
interface IReadOnlyData
{
double GetZ();
}
class SharedData : IReadOnlyData
{
public double Z { get; set; }
IReadOnlyData.GetZ() { return Z; }
}
class Square
{
private IReadOnlyData Data;
public Square(IReadOnlyData data)
{
this.Data = data;
}
}
I think you are thinking about this the wrong way. If all of the squares are to be treated as logically one object, make one object that encapsulates all of them and provides the logic you want. You shouldn't have objects sneakily mutating other objects' values behind their backs, IMO.
Implement the observable pattern.
Check this post:
Super-simple example of C# observer/observable with delegates
Hope it helps you.
Related
I want to create a 2D map of tiles. Example:
Cell[,] cells;
for(int x = 0; x < columns; x++)
{
for(int y = 0; y < rows; y++)
{
cells[x, y] = new Cell();
}
}
The first cell would be at (0|0). What if I want to have this cell as my center and create new cells on the left and top side? These cells would have negative indices.
One way to fix this would be a value that determines the maximum length of one direction. Having a map of 100 tiles per side would place the center of the map at (50|50).
Let's say there would be no hardware limitations and no maximum length per side, what is the best way to create a 2D map with a (0|0) center? I can't image a better way than accessing a cell by its x and y coordinate in a 2D array.
Well, Arrays are logical constructs, not physical ones.
This means that the way we look at the the 0,0 as the top left corner, while might help visualize the content of a 2-D array (and in fact, a 2-D array is also somewhat of a visualization aid), is not accurate at all - the 0,0 "cell" is not a corner, and indexes are not coordinates, though it really helps to understand them when you think about them like they are.
That being said, there is nothing stopping you from creating your own class, that implement an indexer that can take both positive and negative values - in fact, according to Indexers (C# Programming Guide) -
Indexers do not have to be indexed by an integer value; it is up to you how to define the specific look-up mechanism.
Since you are not even obligated to use integers, you most certainly can use both positive and negative values as your indexer.
I was testing an idea to use a list of lists for storage and dynamically calculate the storage index based on the class indexer, but it's getting too late here and I guess I'm too tired to do it right. It's kinda like the solution on the other answer but I was attempting to do it without making you set the final size in the constructor.
Well, you can't use negative indices in an array or list, they're just not the right structure for a problem like this... You could, however, write your own class that handles something like this.
Simply pass in the size of the grid into the constructor, and then use the index operator to return a value based off of an an adjusted index... Something like this... Wrote it up really fast, so it probably isn't ideal in terms of optimization.
public class Grid<T> {
T[,] grid { get; }
int adjustment { get; }
int FindIndex(int provided) {
return provided + adjustment;
}
public Grid(int dimension) {
if (dimension <= 0)
throw new ArgumentException("Grid dimension cannot be <= 0");
if (dimension % 2 != 0)
throw new ArgumentException("Grid must be evenly divisible");
adjustment = dimension / 2;
grid = new T[dimension, dimension];
}
public T this[int key, int key2] {
get {
return grid[FindIndex(key), FindIndex(key2)];
}
set {
grid[FindIndex(key), FindIndex(key2)] = value;
}
}
}
I used these to test it:
var grid = new Grid<int>(100);
grid[-50, -50] = 5;
grid[0, 1] = 10;
You can just switch it to:
var grid = new Grid<Cell>(100);
This only works for a grid with equal dimensions... If you need separate dimensions, you'll need to adjust the constructor and the FindIndex method.
I think that an infinitely sized grid would be dangerous. If you increase the size to the right, you'd have to reposition the center.. Which means, what you think will be at 0,0 will now be shifted as the grid is no longer properly centered.
Additionally, performance of such a structure would be a nightmare as you cannot rely on an array to be infinite (as it inherently isn't). So you'd either have to continuously copy the array (like how a list works) or use a linked list.. If using a linked list, you would have to do enormous amounts of iteration to get whatever value you want.
Sorry for the long question! I've been trying my hand at using get/set accessors, but I've run into a problem.
To give an example, I have a Vector2D class which has private double x and y values and public accessors X and Y for those values. I also have a public Direction property (of a custom type Angle which itself has public double Degrees and Radians properties). This Direction property has a get accessor which returns a new Angle object based on the values of X and Y, and a set accessor which changes the X and Y values based on the new Angle value passed in.
So if you have a Vector2D called vector you can use vector.Direction = new Angle(0), which works fine. But naturally it's also possible to write vector.Direction.Degrees = 0. This doesn't cause errors but it also doesn't work as intended, since the x and y values of the vector aren't updated.
After thinking about it I understand why this happens. When you write vector.Direction.Degrees, it uses the get accessor in Vector2D, which returns a new Angle based on X and Y, and then it accesses the Degrees property and its set accessor on that object, not the set accessor for the Direction property on the original vector object. In other words, the set accessor on vector.Direction doesn't get used in that scenario at all, and so the x and y values aren't updated. And that makes sense I suppose.
It's clearly confusing that you can access vector.Direction.Degrees and attempt to set it to a different value yet this doesn't actually do anything. But I also see that this behaviour is intended. My question is, what is a good way to deal with this problem?
Thanks in advance!
EDIT - Here's the relevant part of my class definition:
Vector2D class
private double x;
private double y;
public double X { get => x; set => x = value; }
public double Y { get => y; set => y = value; }
public Angle Direction
{
get
{
return new Angle(X, Y);
}
set
{
double previousMagnitude = Magnitude;
X = Math.Cos(value.Radians) * previousMagnitude;
Y = Math.Sin(value.Radians) * previousMagnitude;
}
}
The (most) right thing to do is to make the Angle immutable, so that its Degrees and Radians couldn't be changed after creation. You'll probably need static factory methods Angle.FromDegrees() and Angle.FromRadians() to, as both degrees and radians are double so you can't use .ctor overloads.
Failing that, you'll need to create Changed event on Angle,subscribe the Vector2D to this event, raise it every time Degrees or Radians are set. Also unsubscribe from it when Vector2D.Angle is re-assigned... which seems to be a huge overkill, esp. if Angle objects could be shared between Vectors.
Since you are returning a new Direction value every time you access it anyways, I suggest not having a public set in Direction.Degrees and Direction.Radians at all, like this:
public double Degrees
{
get { /* return degrees */ }
private set { /* set degrees, but only from somewhere in the struct, for example the constructor */ }
}
And use it like this:
public Angle(double X, double Y)
{
this.Degrees = /*do computation based on X and Y*/;
this.Radians = /*do computation...*/
}
Gives an error due to property inaccessible because of protection level:
myVector2D.Direction.Degrees = x;
Works:
myVector2D.Direction = new Angle(x, y);
This way you can force your users to use the set of Vector2D.Direction rather than that of Angle.Degrees, so you can detect and react to any changes.
Sorry for any formatting errors, I'm on mobile.
For each word I am creating an object of LocationTextExtractionStrategy class to get its coordinates but the problem is each time I pass a word it is returning coordinates of all the chunks of that word present in pdf. How can i get coordinates of the word present at specific position or in a specific line?
I found a code somewhere
namespace PDFAnnotater
{
public class RectAndText
{
public iTextSharp.text.Rectangle Rect;
public string Text;
public RectAndText(iTextSharp.text.Rectangle rect, string text)
{
this.Rect = rect;
this.Text = text;
}
}
public class MyLocationTextExtractionStrategy : LocationTextExtractionStrategy
{
public List<RectAndText> myPoints = new List<RectAndText>();
public string TextToSearchFor { get; set; }
public System.Globalization.CompareOptions CompareOptions { get; set; }
public MyLocationTextExtractionStrategy(string textToSearchFor, System.Globalization.CompareOptions compareOptions = System.Globalization.CompareOptions.None)
{
this.TextToSearchFor = textToSearchFor;
this.CompareOptions = compareOptions;
}
public override void RenderText(TextRenderInfo renderInfo)
{
base.RenderText(renderInfo);
var startPosition = System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(renderInfo.GetText(), this.TextToSearchFor, this.CompareOptions);
//If not found bail
if (startPosition < 0)
{
return;
}
var chars = renderInfo.GetCharacterRenderInfos().Skip(startPosition).Take(this.TextToSearchFor.Length).ToList();
//Grab the first and last character
var firstChar = chars.First();
var lastChar = chars.Last();
//Get the bounding box for the chunk of text
var bottomLeft = firstChar.GetDescentLine().GetStartPoint();
var topRight = lastChar.GetAscentLine().GetEndPoint();
//Create a rectangle from it
var rect = new iTextSharp.text.Rectangle(
bottomLeft[Vector.I1],
bottomLeft[Vector.I2],
topRight[Vector.I1],
topRight[Vector.I2]
);
this.myPoints.Add(new RectAndText(rect, this.TextToSearchFor));
}
}
}
I am passing words from an array to check for its coordinates. The problem is that RenderText() method is automatically called again and again for each chunk and returns the list of coordinates of the word present at different places in the pdf. For example if i need coordinate of '0' it is returning 23 coordinates. What should I do or modify in the code to get the exact coordinate of the word?
Your question is a bit confusing.
How can I get coordinates of the word present at specific position
In that statement you're basically saying "How can I get the coordinates of something that I already know the coordinates of?" Which is redundant.
I'm going to interpret your question as "How can I get the coordinates of a word, if I know the approximate location?"
I'm not familiar with C#, but I assume there are methods similar to the ones in Java for working with Rectangle objects.
Rectangle#intersects(Rectangle other)
Determines whether or not this Rectangle and the specified Rectangle intersect.
and
Rectangle#contains(Rectangle other)
Tests if the interior of the Shape entirely contains the specified Rectangle2D.
Then the code becomes trivially easy.
You use LocationTextExtractionStrategy to fetch all the iText based rectangles
you convert them to native rectangle objects (or write your own class)
for every rectangle you test whether the given search region contains that rectangle, keeping only those that are within the search region
If you want to implement your second use-case (getting the location of a word if you know the line) then there are two options:
you know the rough coordinates of the line
you want this to work given a line number
For option 1:
build a search region. Use the bounds of the page to get an idea of the width (since the line could stretch over the entire width), and add some margin y)-coordinates (to account for font differences, subscript and superscript, etc)
Now that you have a search region, this reverts to my earlier answer.
For option 2:
you already have the y coordinate of every word
round those (to the nearest multiple of fontsize)
build a Map where you keep track of how many times a certain y-coordinate is used
remove any statistical outliers
put all these values in a List
sort the list
This should give you a rough idea of where you can expect a given line(number) to be.
Of course, similar to my earlier explanation, you will need to take into account some padding and some degree of flexibility to get the right answer.
I'm working on a Windows Store App (C#) using Bing Maps.
I want to be able to, given collection of Locations (latitude and longitude pairs), determine what the zoom level for the map should be, and what its center point (Location) should be.
From the collection of Location values, I extract the four "extreme" cardinal points that need to be displayed (furthest north, south, east, and west).
IOW, if I want to display pushpins throughout San Francisco, I want to get the zoom level to show just that city and nothing more. If I want to display pushpins scattered across the U.S., ... you get the picture.
This is what I have so far (just a rough draft/pseudocode, as you can see):
Determine the extreme cardinal values of a set of Locations (code not shown; should be trivial). Create an instance of my custom class:
public class GeoSpatialBoundaries
{
public double furthestNorth { get; set; }
public double furthestSouth { get; set; }
public double furthestWest { get; set; }
public double furthestEast { get; set; }
}
...then call these methods, passing that instance:
// This seems easy enough, but perhaps my solution is over-simplistic
public static Location GetMapCenter(GeoSpatialBoundaries gsb)
{
double lat = (gsb.furthestNorth + gsb.furthestSouth) / 2;
double lon = (gsb.furthestWest + gsb.furthestEast) / 2;
return new Location(lat, lon);
}
// This math may be off; just showing my general approach
public static int GetZoomLevel(GeoSpatialBoundaries gsb)
{
double latitudeRange = gsb.furthestNorth - gsb.furthestSouth;
double longitudeRange = gsb.furthestEast - gsb.furthestWest;
int latZoom = GetZoomForLat(latitudeRange);
int longZoom = GetZoomForLong(longitudeRange);
return Math.Max(latZoom, longZoom);
}
Here's where I really get lost, though. How do I determine the zoom level to return (between 1..20) based on these vals? Here's a very rough idea (GetZoomForLat() is basically the same):
// Bing Zoom levels range from 1 (the whole earth) to 20 (the tippy-top of the cat's whiskers)
private static int GetZoomForLong(double longitudeRange)
{
// TODO: What Zoom level ranges should I set up as the cutoff points? IOW, should it be something like:
if (longitudeRange > 340) return 1;
else if (longitudeRange > 300) return 2;
// etc.? What should the cutoff points be?
else return 1;
}
Does anyone have any suggestions or links that can point me to how to implement these functions?
I wrote a blog post on how to do this a while ago here: http://rbrundritt.wordpress.com/2009/07/21/determining-best-map-view-for-an-array-of-locations/
You can use the LocationRect class to set the bounding box, see the MSDN:
http://msdn.microsoft.com/en-us/library/hh846491.aspx
Then you use the Map class and its SetView() method, see the MSDN:
http://msdn.microsoft.com/en-us/library/hh846504.aspx
Here is a code that would work (where map is your map control instance):
var collection = new LocationCollection();
collection.Add(new Location(47.5, 2.75));
collection.Add(new Location(48.5, 2.75));
collection.Add(new Location(43.5, 5.75));
map.SetView(new LocationRect(collection));
So you can use each coordinates of the elements that you want to display on your map in the collection to generate the bounding box and set the view accordingly.
Before I start, I must say that for those with a background of linear algebra, this is NOT matrix decomposition as you know it. Please read the following paragraphs to get a clearer understanding of the problem I am trying to solve.
Here are the salient properties/definitions of the matrix and its submatrices:
I have an SxP matrix which forms a grid like structure of S.P "boxes". This is the main matrix.
This is what the (empty) main matrix looks like. Each square in the matrix is simply referred to as a box. The matrix can be viewed as a a kind of "gameboard" e.g. a chess board. The vertical axis is measured using an interval scale (i.e. real numbers), and the horizontal axis is measured using monotonically increasing non-negative integers.
There is an additional concept of submatrices (as explained earlier). A submatrix is simply a collection of boxes in a particular configuration, and with specific numbers and piece types (see black and white pieces below), assigned to the boxes. I have a finite set of these sub matrices - which I refer to as my lexicon or vocabulary for carrying out valid matrix composition/decompositions.
The "formal" definition of a sub matrix is that it is a configuration of M boxes contained within the main matrix, that satisfy the criteria:
1 <=M<= 4
the "gap" G (i.e. distance) between any two adjacent boxes satisfies: 1<= G<= 2*(vertical units).
A vertical unit is the gap between the vertical axis lines in the main matrix. In the image below, the vertical unit is 100.
The image immediately above illustrates a simple sub matrix addition. The units with orange boarders/boxes are sub matrices - the recognized units that form part of my lexicon. You will notice that I have introduced further annotation in my sub matrices. This is because (using the chess analogy), I have two types of pieces I can use on the board. B means a black piece, and W (not shown in the image), represents a white piece. A recognized unit (or lexeme/sub matrix) There is a simple equivalence relation that allows conversion between a white piece and a black piece. This relationship can be used to further decompose a submatrix to use either exclusively black pieces, white pieces or a combination of both.
For the sake of simplicity, I have omitted specifying the equivalence relationship. However, if someone feels that the problem as posed is not "too difficult" without additional details, I shall gladly broaden the scope. For now, I am trying to keep things as simple as possible, to avoid confusing people with "information overload".
Each box in a sub matrix contains a signed integer, indicating a number of units of an item. Each "configuration" of boxes (along with its signed integers and piece type i.e. black or white pieces) is said to be a "recognized unit".
Submatrices can be placed in the main matrix in a way such that they overlap. Wherever the "boxes" overlap, the number of units in the resulting submatrix box is the sum of the number of units in the constituent boxes (as illustrated in the second image above).
The problem becomes slightly difficult because, the "recognized units" defined above themselves are sometimes combined with other "recognized units" to form another "recognized unit" - i.e. the sub matrices (i.e.recognized units) are "holons". For example, in the second image above, the recognized unit being added to the matrix can itself be further decomposed into "smaller" submatrices.
This sort of holarchy is similar to how (in Physical chemistry), elements form compounds, which then go on to form ever more complicated compounds (amino acids, proteins etc).
Back to our problem, given a main matrix M, I want to be able to do the following:
i. identify the submatrices (or recognized units) that are contained within the main matrix. This is the first "matrix decomposition". (Note: a submatrix has to satisfy the criteria given above)
ii. For each identified submatrix, I want to be able to recognize whether it can be decomposed further into 2 or more recognized submatrices. The idea is to iteratively decompose submatrices found in step i above, until either a specified hierarchy level is reached, or until we have a finite set of submatrices that can not be decomposed further.
I am trying to come up with an algorithm to help me do (i) and (ii) above. I will implement the logic in either C++, Python or C# (in increasing level of preference), depending on which ever is the easiest to do and/or in which I happen to get snippets to get me started in implementing the algorithm.
I am not sure if i have a understand correctly the problem.
So first ypu want to find all submatrixes that conform with your 2 criterea.
Thats like a graph decomposition problem or a set coverage problem i think, where you can have a recursive function and iterate the matrix to find all available submatrixes.
enum PieceTypes
{
White,
Black
}
class Box
{
public PieceTypes PieceType { get; set; }
public uint Units { get; set; }
public int s, p;
public Box(PieceTypes piecetype, uint units)
{
PieceType = piecetype;
Units = units;
}
}
class Matrix
{
public Box[,] Boxes;
public int Scale, S, P, MaxNum, MaxDist;
public List<List<Box>> Configurations;
public Matrix(int s, int p, int scale, int maxnum, int maxdist)
{
S = s;
P = p;
Scale = scale;
Boxes = new Box[S, P];
MaxNum = maxnum;
MaxDist = maxdist;
Configurations = new List<List<Box>>();
}
public void Find(List<Box> Config, int s, int p)
{
// Check the max number thats valid for your configuration
// Check that the current p and s are inside matrix
if (Config.Count() < MaxNum && s >= 0 && s < S && p >= 0 && p < P)
{
foreach (Box b in Config)
{
if (Valid(b, Boxes[s, p]))
{
Boxes[s, p].s = s;
Boxes[s, p].p = p;
Config.Add(Boxes[s, p]);
break;
}
}
Find(Config, s + 1, p);
Find(Config, s - 1, p);
Find(Config, s, p + 1);
Find(Config, s, p - 1);
}
if (Config.Count() > 0) Configurations.Add(Config);
Config.Clear();
}
public bool Valid(Box b1, Box b2)
{
// Create your dist funtion here
// or add your extra validation rules like the PieceType
if (Math.Sqrt((b1.s - b2.s) ^ 2 + (b1.p - b2.p) ^ 2) <= MaxDist && b1.PieceType == b2.PieceType) return true;
else return false;
}
}
I haven't used the best data structures and i have simplified the solution. I hope its some way helpful.