|
The problem with using 'structs in this case would be their mutability will require you to update your list with the new copy of the struct created by modifying it.
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
Analytical Geometry to the rescue!
Given point (X0, Y0), return all points (X, Y) such that |X - X0| + |Y - Y0| <= R.
For the row Y == Y0, this is trivially all the points (X, Y0), X0 - R <= X <= X0 + R.
For the rows Y == Y0+/-1, this is trivially all the points (X, Y0+/-1), X0 - R + 1 <= X <= X0 + R - 1.
For the rows Y == Y0+/-n, this is trivially all the points (X, Y0+/-n), X0 - R + n <= X <= X0 + R - n.
And for Y == Y0+/-R, this is trivially the points (X0, Y0+/-R).
No coordinates are explicitly calculated, and no point is visited more than once.
Note that this approach would work for the more conventional distance, as well. Use Bresenham's circle-drawing algorithm to calculate the end-points of each row.
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
@bhiller Without some 'unsafe voodoo, I don't see any way but "brute force;" in this example, I chose to generate a set of rectangles:
public static IEnumerable<Rectangle> GetNearbyPoints(int maxDist, List<Point> points, int nRows, int nColumns)
{
int x, y, w, h;
int half = maxDist / 2;
List<Rectangle> rects = new List<Rectangle>();
for (int i = 0; i < points.Count(); i++)
{
Point pt = points[i];
x = pt.X;
y = pt.Y;
if (x < 0) x = 0;
w = maxDist;
if (x + half > nColumns)
{
w = nColumns - x;
}
if (y < 0) y = 0;
h = maxDist;
if (y + half > nRows)
{
h = nRows - y;
}
yield return (new Rectangle(x,y,w,h));
}
}
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
Thanks, Bill. That could pave the way to a solution.
I really need some kind of "List" of those points - IEnumerable is necessary, Count would be nice, mutability is not required at all. That "list" will be used as a parameter in further calculations.
So, a solution could be:
- create a rectangle enclosing all original points (that's O(n) for number of points)
- create a 2-dimensional array of bool, and map those points (i.e. x and y of the point become indices of the array, and there the value is set to true)
- create a 2-dimensional array of bool for the result. It's bigger, and the size can easily be determined.
- either
- - iterate over all result array and find out if a point of the original array can be reached
- - iterate over the original array and mark all points which can be reached in the result array. In contrast to the HashSet implementation, there is no need to check for duplicates: it does not matter if an item already true is set to true again.
- re-map the array to a List of Point
That should be O(n) for the number of original points (which is my main concern), but stil O(n^2) for the distance (which is a configurable value, and should not vary to much).
Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!
|
|
|
|
|
off the top of my head: from the IEnumerable<Rectangle>
public static IEnumerable<Point> RectanglesToPoints(IEnumerable<Rectangle> rects)
{
return rects.Select(r => RectToPoints(r)).SelectMany(pt => pt);
}
public static IEnumerable<Point> RectToPoints(Rectangle rect)
{
for (int i = rect.X; i < rect.Width + rect.X; i++)
{
for (int j = rect.Y; j < rect.Height + rect.Y; j++)
{
yield return new Point(i,j);
}
}
} I suspect there's a better way; is there something about when you need to go from IEnumerable to List, or other, that is critical here ?
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
Thanks for your input. I think I could have enough information now to improve the original solution (don't need to do it now, but I am sure I'll have to do it some when later).
Regarding your latest code, there a two points to consider: the resulting list will be used in a few places. So I'd have to do a ToList or ToArray call to prevent the Linq statement from being executed multiple times. That's an easy fix.
Also, when I need the amount of points in the resulting list, it should be free of duplicates. A call to Distinct in RectanglesToPoints should do the trick easily again.
Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!
|
|
|
|
|
Hi Bernhard, It was fun to think about this.
I was puzzling over the issue of duplication, since two rectangles could overlap, without being identical. My only thought was to generate the full list of points, and call 'Distinct on that: I tried to ignore the thought of graphic paths that could represent rectangles with chunks taken out of them
cheers, Bill
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
BillWoodruff wrote: It was fun to think about this. That's also my motivation for reading questions / articles / discussions on CodeProject. Nice to hear that I could provide an interesting topic.
Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!
|
|
|
|
|
I need help with a program for a match stick game between the computer and a user. program should ensure that the computer always wins.
Rules for the game are as follows :
•There are 21 match –stick
•The computer asks the player to pick 1,2,3 sticks.
•The computer starts first.
•After the person pick, the computer does is picking.
•Whoever is forced to pick up the last stick win the game.
|
|
|
|
|
We do not do your homework: it is set for a reason. It is there so that you think about what you have been told, and try to understand it. It is also there so that your tutor can identify areas where you are weak, and focus more attention on remedial action.
Try it yourself, you may find it is not as difficult as you think!
If you meet a specific problem, then please ask about that and we will do our best to help. But we aren't going to do it all for you!
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Computers take instructions very literal.
Computer picks 1 stick. 20 left.
User picks 1 stick. 19 left.
Computer picks 2 sticks. 17 left.
User picks 2 sticks. 15 left.
Computer picks 3 sticks. 12 left.
User picks 3 sticks. 9 left.
Everyone wins.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
class Program
{
static void Main(string[] args)
{
Console.WriteLine("I win!");
Console.ReadLine();
}
}
|
|
|
|
|
I have Pdf template with some background design and logo, so we need to pass the data dynamically in to that pdf template using "itextsharp" library. So when we pass the data to the template, it’s overriding the template backgroud design and showing the plain text that we have passed to the
Template instead of merging with the Template.
Any ideas or suggestions to achieve the functionality would be appreciated.
|
|
|
|
|
With so little information it is impossible to guess what your code is doing. Please edit your question and add some proper detail.
|
|
|
|
|
I have written a program the has numerous methods in form1.cs file and it has become somewhat difficult to manage because of its length. Is there a way to move some of these methods to a separate file? If so, what are the mechanics of linking the together? Or is there another approach to manage long programs?
JBD
|
|
|
|
|
To me a good sign of "good practice" would be that someone else reading your code would have some clear ideas about its structure, and what it does, just by looking at the use of namespaces, classes, method names. variable names.
This is a very broad question, and it may well relate to bigger-picture issues in object-oriented design (OOD). Do you know about SOLID, a coherent set of ideas for OOD [^] ?
In WinForms, you can declare a Class as 'partial to get around the restriction on having a single Class definition across multiple files [^].
Other ways commonly used to group Methods, where the Method has no dependencies, include writing Extension Methods in a static Class [^].
Of course, you can also group Methods into a library, compile that to a .dll, load that into your project, and reference the assembly in your Class' code ... as long as those methods have no innate dependency on your app's run-time objects, declarations, etc.
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
just a quick correction: It's not WinForms that defines partial classes, but the languages of C# and VB do. You don't need a WinForms project to make use of the feature.
|
|
|
|
|
Thanks, Josh !
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
When someone starts programming, the first concepts he's learning are "procedural" concepts, i.e. how to control the program flow (if...else, for, do...while etc).
Another concept is "object orientation". Now you have to think of "encapsulation of data" (how to access them, and more important how to change them safely), and eventually of components and their interactions.
Bill mentioned SOLID: those are 5 ways for creating components and having them interact. "S" stands for "single responsibility" and is a good point to start with: a class takes care of one thing only, a function in that class of one action only.
This change in paradigm from mere procedural code to object oriented code is a big step.
Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!
|
|
|
|
|
I have successfully used the InPlaceBitmapMetadataWriter to write Keywords to many photos taken by many cameras, including when I need to extend the metdata padding. However for photos taken by recent cameras the TrySave method always returns false for Keywords. Does anyone know why this might be and how I might solve this?
private bool UpdateMetadataInPlace()
{
bool traySaveSuccessful = false;
string tempPath = PutTogetherTemporaryFilePath();
if (File.Exists(tempPath))
{
File.Delete(tempPath);
}
File.Copy(imageFilePath, tempPath);
using (Stream jpgFileStream = File.Open(tempPath, FileMode.Open, FileAccess.ReadWrite))
{
BitmapDecoder jpgDecoder = BitmapDecoder.Create(jpgFileStream, BitmapCreateOptions.None, BitmapCacheOption.None);
if (jpgDecoder.Frames[0] != null && jpgDecoder.Frames[0].Metadata != null)
{
InPlaceBitmapMetadataWriter metadataJpgWriter = jpgDecoder.Frames[0].CreateInPlaceBitmapMetadataWriter();
metadataJpgWriter.SetQuery("System.Keywords", Keywords.ToArray());
if (metadataJpgWriter.TrySave())
{
traySaveSuccessful = true;
}
}
}
if (traySaveSuccessful == true)
{
File.Delete(imageFilePath);
File.Move(tempPath, imageFilePath);
}
else
{
File.Delete(tempPath);
}
return traySaveSuccessful;
}
modified 29-Oct-18 14:12pm.
|
|
|
|
|
Whenever my application loses focus, the scrolling of a panel is reset to the top position once focus is regained. This is really annoying. I have tried everything I can think of and researched to fix this such as overriding the scroll mechanism and saving coordinates; also doing the same during a mouse wheel scroll and trying to restore with the following method:
private void OnFormActivated(object sender, EventArgs e)
{
panel1.AutoScrollPosition = panelRect.Location;
}
|
|
|
|
|
This works for me: [^].
But, if your Panel is nested inside a Form, or other ContainerControl, with scrolling enabled/visible ... I don't know.
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
Let me start out by saying I am a complete noob. I am taking an online only course so asking someone a question is very difficult and often takes days to get a response, so I am trying here.
I am tasked with creating an array that pulled sales from a .txt file. All of the sale amounts in the .txt file have decimal amounts, so I figured I would use a double. I am getting all kinds of errors saying I cannot convert a double to an int. I don't know where in the code I have gone wrong. Again, I am completely new to this and understand I probably have multiple issues. Any help would be greatly appreciated.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Total_Sales_Homework
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private double Average(double[] iArray)
{
double total = 0.0;
double average;
for (double index = 0; index < iArray.Length; index++)
{
total += iArray[index];
}
average = (double)total / iArray.Length;
return average;
}
private double Highest(double[] iArray)
{
double highest = iArray[0];
for (double index = 1; index < iArray.Length; index++)
{
if (iArray[index] > highest)
{
highest = iArray[index];
}
}
return highest;
}
private double Lowest(double[] iArray)
{
double lowest = iArray[0];
for (double index = 1; index < iArray.Length; index++)
{
if (iArray[index] < lowest)
{
lowest = iArray[index];
}
}
return lowest;
}
private double Total(double[] iArray)
{
double total = iArray[0];
return total;
}
private void salesButton_Click(object sender, EventArgs e)
{
try
{
double totalSales;
double highestSales;
double lowestSales;
double averageSales;
StreamReader inputFile;
const double SIZE = 7;
double[] sales = new double[SIZE];
double index = 0;
inputFile = File.OpenText("Sales.txt");
while (!inputFile.EndOfStream && index < sales.Length)
{
sales[index] = int.Parse(inputFile.ReadLine());
index++;
}
inputFile.Close();
foreach (int value in sales)
{
salesListBox.Items.Add(value);
}
totalSales = Highest(sales);
highestSales = Highest(sales);
lowestSales = Lowest(sales);
averageSales = Average(sales);
totalSalesLabel.Text = totalSales.ToString("n1");
averageSalesLabel.Text = averageSales.ToString("n1");
highestSalesLabel.Text = highestSales.ToString("n1");
smallestSalesLabel.Text = lowestSales.ToString("n1");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
|
|
|
|
|
You seem to be mixing double and int types. You should use an int type to set the size of an array. And you should use Double.TryParse on your input values. It would have been more helpful if you showed the exact error message and which line it occurred on.
|
|
|
|
|
Take your errors one-by-one and look at them closely. If you double click on an error message in the "Error List" pane, it will take you to the line it refers to. The first one will be in your Average Method:
private double Average(double[] iArray)
{
double total = 0.0;
double average;
for (double index = 0; index < iArray.Length; index++)
{
total += iArray[index];
}
average = (double)total / iArray.Length;
return average;
} And will say:
Cannot implicitly convert type 'double' to 'int'. An explicit conversion exists (are you missing a cast?)
What that is saying is that you are using a double value where an int is expected, and that the system will not automatically change that for you because it will result in lost information. And that's true: if you convert the double value 1.5 to an int it will "throw away" the half and leave you with 1. The system wants to be sure you meant to do that, so it gives you an error. And array indexes are always either integer or strings, so you can;t use a double between the square brackets.
You can do what it suggests and explicitly cast it:
total += iArray[(int)index]; But that's a poor solution: change the index to an integer and all will be fine:
private double Average(double[] iArray)
{
double total = 0.0;
double average;
for (int index = 0; index < iArray.Length; index++)
{
total += iArray[index];
}
average = total / iArray.Length;
return average;
} The error message will vanish, and you can move on to the next.
Which is the Lowest method, and exactly the same problem!
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|