I want to draw text on the outline of a circle at fixed intervals (exactly like a clock)
Is there a simple way to do that?
Whatever graphics library you use, drawing text needs an x and a y to know where to draw the text.
Assume the center of the clock is Cx and Cy. Assume x goes positive to the right and y goes positive up. You may need to offset or reverse those depending on your platform.
So you can use math (trigonometry) to get the x and y of each clock number. You need the degree along the circle and the radius of the circle, and the formula would be:
y = sin(degree) * radius + Cy
x = cos(degree) * radius + Cx
toddmo's math is right. In terms of the implementation, it's not clear exactly what you are asking. If you are starting from scratch, the simplest way of doing this would be:
1) create a Windows Forms app in Visual Studio
2) draw the circle in mspaint, and import the image file as a resource.
3) create a picturebox that shows that resource using the form builder UI. This is an easy way to display the circle on the form.
4) create a 'Label' control by dragging and dropping it onto the form in the form builder UI
5) create a 'Timer' control (can be drag/dropped onto the form from the 'toolbox' window)
6) double-click the Timer control, in it's event, set the Label control's position based on sin and cos as toddmo describes.
7) set the interval of the Timer control to the appropriate value.
This won't scale well if dpi changes, but it's a start.
Related
Is it possible to draw a line at the border of the screen, like an "inline" with a consistent width of lets say 10 pixels, so that it aligns to the edges of the screen, even at the rounded corners?
Like this:
normal screen
with the wanted inline (Orange line)
Is there a unity solution? (Otherwise any other solution would be great too! Android studio maybe?)
What I want to achieve is a line that's always the same shape as the screen borders, on every screen, no matter the radius of the corners
I don't think this is possible in normal ways, since Unity considers the screen as a rectangle, so it will give you no information about the shape of the corners of your screen.
However, it is not impossible. You can use SystemInfo.deviceModel to get the model of a device and then you can retrieve information of its screen shape from a server or something like that.
The only necessary information the server needs to store is the radius of the corner. If its 0, means the screen is a rectangle, otherwise the screen is rounded with the given radius r:
Having this information, you can pass it to a post processing shader that will evaluate the minimum distance from each pixel to the corner of the screen, and if this distance is less than some value you defined, you can paint it differently.
Hi Mathmeticians out there.
I am a little stumped and I was wondering if there was any sort of algorithm that could help me.
First the conceptual problem, Lets say I have a bunch of boxes that lie along an X axis. I want to be able to choose an arbitrary point A on the axis and have everything on the left scaled to 95% of its original width and position and to compensate, everything on the right will have to be scaled to 105%. The width of the resulting boxes is easy to calculate since it is the original width times the scale. The problem I am having is how to calculate the gap which has now been created at point A so that I can shift the second part left to close that gap.
Furthermore, I would like to not only select a point A, but also a B and C, etc.. as well and be able to close their gaps likewise.
--The real reason I am asking--
Now for the actual problem (in case anyone else out there has gone through this.) I have a control in a C# Winforms app that was made by some programmer before I got here. The control can contain any number of child controls that each have their own relative coordinates as a percentage of the Width or Height (i.e. A control with a relative X coordinate of 0.5 will be placed halfway across the parent container.
We desperately need to support multiple monitors and the problem that I am having is that if you dock a control or toolbar next to our proprietary control then the ClientRectangle is smaller so it shifts around the child borders like so
My boss doesn't like that the lines shift over monitor boundaries and wants me to only mess with the lines on the same monitor where the window was docked. I have been able to get 90% of the way using the concept above, but I can't seem to get the re-spacing calculation right.
Here is a Mathematical model of what I think for calculating the gap.
Let's say that you have a starting point A, and lets define it as xA.
Now, let's define the boxes
//Box{x0,x1}
Boxes = {[B1]{0,100},[B2]{100,200},[B3]{200,400},[B4]{400,450},[B5]{450,700}}
Now we have 5 boxes on the X axis.
Let's define;
A = xA = 370;
TotalLength = 700;
If you divide 700 by 2, that makes 350 which makes the mid point, and 370 is bigger than the mid point value. So that is being said, in this case you would need to shift the elements on the left to right. The calculation of the gap is as the following;
IF(Midpoint < A)
Gap = ((A- Midpoint) * 100 ) / TotalLength //This is the gap in percent
ELSE
Gap = ((Midpoint - A) * 100) / TotalLength
This way, you can find the gap. The Axis you need to shift towards will need to be decided based on the point you are selecting, if the selected point less than the Mid point then shift to right, if higher shift to left (to the positive axis route).
I hope this helps.
Thank you for your help Surgeon. Unfortunately I wasn't able to find a solution using your method. On the bright side, I was able to find a solution. The trick was to treat the X coordinate as the width between the Client Rectangle's left edge and the X coordinate's position and calculate it similarly to the child width.
For more specifics, here's the algorithm I have come up with for dealing with the docking problem:
var clientOriginalWidth = what the width of the Client rectangle would be without docks
var clientCompressedWidth = the width of the client now
//Calculate the Compression Ratio for each screen as follows
foreach(var screen in Screens){
var widthOfClientRectOnScreenNow = how much of the client rectangle is on this screen
var widthOfClientRectOnScreenWithoutDocks = how much of the client rectangle was on the screen before the docks were there
var compressionRatio = (widthOfClientRectOnScreenNow / clientCompressedWidth) /
(widthOfClientRectOnScreenWithoutDocks / clientOriginalWidth);
//Assuming control.xScale and control.widthScale are initially 0
foreach(var control in ParentControl){
var controlBounds = where the control was when the client was full width
if(controlBounds.X > screen.right){
var percentOfXPositionOnScreen = screen.right - screen.left / control.x;
controlBounds.xScale += percentOfPositionOnScreen * compressionRatio;
}
else if(control.X > screen.left){
var percentOfXPositionOnScreen = control.x - screen.left / control.x;
controlBounds.xScale += percentOfPositionOnScreen * compressionRatio;
}
if(screen.intersects(controlBounds){
var percentControlIsOnScreen = what percent of the control's width was on this screen
control.widthScale += percentControlIsOnScreen * compressionRatio;
}
}
}
The position is then found by multiplying the original X coordinate by the scale (same for the width). Once the docks are removed, recalculate the scale. When all docks are removed, the scale should be 1.
I have left out some specifics to make it more of a generalized algorithm, but one should be able to work through this on their own system.
I have a chart that displays several lines showing signal strengths over a frequency band.
Each chart is composed of one 'area' and four 'series'. On the parent form there are several graphs like the one shown below. All of them are created dynamically and will have different widths.
What I am trying to do is add a tooltip or annotation (or something) when the mouse hovers over a specific area of the chart as shown in the mockup below:
If the mouse moved to the other side of the chart a different channel number and frequency would be shown in a box surrounding that area of the chart.
It doesn't have to be exactly as shown in the mockup although an outline would be preferred in order to show the user how wide the channel is regardless of the waveform shown in that area at the time. For example, the waveform shown above might only be 8MHz wide but channel 1 itself might have an allocation that is 10MHz wide (the device varies its bandwidth based on its offered load.)
The X axis is MHz and a channel is defined in terms of MHz so it would be ideal to define the outline in terms of the X axis instead of pixels.
Also, note that this is a realtime chart that is updated up to 10 times per second. Therefore it would be best if the information was not required to be updated each time new data arrived.
I was able to combine a couple of items to make the following solution:
[credit LICEcap]
The highlight is a rectangle filled in the 'OnPaint' method of the chart control.
The text is a simple TextAnnotation that is applied during the mousemove event.
It took quite a bit of coordinate conversion to get all the pieces in the right spot - especially the text. I needed to convert between pixels, position and value.
The first conversion was to pixels in order to center the text using MeasureString. I then converted it from pixel location to X axis value and then needed to convert it to position since the annotation requires using 'position' coordinates. There is not a function to convert from pixels to position. There is a pixels to value and a value to position which is the way I went.
I don't claim this to be the best or even a proper way to do it but it works. If anyone else has a better solution or a way to improve my code please post.
Here's my code for positioning the text:
double temp = chart1.ChartAreas[0].AxisX.ValueToPixelPosition(Convert.ToDouble(ce.sChannelFrequency) * 1000);
using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(new Bitmap(1, 1))) {
SizeF size = graphics.MeasureString(freq.Text, new Font("eurostile", 13, FontStyle.Bold, GraphicsUnit.Pixel));
temp -= (size.Width/2+10);
}
if (temp < 0) temp = 0;
temp = chart1.ChartAreas[0].AxisX.PixelPositionToValue(temp);
freq.X = chart1.ChartAreas[0].AxisX.ValueToPosition(temp);
I'm a bit stuck with this one.
I'm writing a visual Semaphore flag signalling application, and I'm having a bit of trouble with the positioning of labels for left and right arms.
This is the code before:
private void leftHandDown()
{
display.DrawLine(penLeftArm, centXCoord, centYCoord, LHDownXCoord, LHDownYCoord);
lblLeftHand.Top = LHDownYCoord;
lblLeftHand.Left = LHDownXCoord;
lblLeftHand.Show();
}
And this is what it looks like:
http://i137.photobucket.com/albums/q221/omar319/sema.png (I don't have any rep to post photos on here). I have set the background to blue, as I'm also trying to pin down another problem (labels leave a white box when they change position, not sure why).
I would like the labels to appear at the end of the hands drawn by the pen (end coordinates LHDownXCoord and LHDownYCoord) but the labels are always offset by -80px on the y-axis. The Right Hand label I have added 75px to the Y axis coordinate.
Any idea what is causing the offset?
Cheers,
Omar
I think the labels need to be offset by the top left coordinates of your display control
i am trying to develop a remote desktop apps with c#. so i have couple of question regarding mouse coordinate calculation based on picture box
suppose i have picture box and i want to capture mouse coordinate when i will move my mouse
on that picture box in c#?
if i click at location (200, 300) on my picture box. then how can i determine
programmatically resolution of picture box and convert that (200,300) coordinate based on
that resolution.
when i will send (x, y) coordinate to other machine and if that pc has resolution have like
1024x768 then what logic i need to use to convert (x, y) according to that pc resolution
if possible help me with small sample code for my question. thanks
This sounds like a trivial question, if it's something homework related, add a tag homework.
int remote_x = local_x * remote_width / local_width;
int remote_y = local_y * remote_height / local_height;
The dimensions of the picture box (local_width and local_height) can be determined e.g. by using pictureBox.Width and pictureBox.Height. The cursor coordinates, local_x and local_y can be requested or are part of the event data (e.g. of the MouseMove event).
Simple, the easiest way is to transform your coordinates to a normalized form (ranging from 0 to 1). Then you can use these normalized coordinates to calculate the mousePosition on another resolution. This way the devices don't need to know the other devices resolution.
So:
//First Normalize the clickPosition using the current resolution
//clickPos(200,300) and resolution(800,600) => normalized(0.25,0.5)
var normalized = clickPos/resolution;
//Now you can send this information to the other device
//The other device uses the normalized parameter to calculate the mouseClick with his resolution
//normalized(0.25,0.5) and otherResolution(1280,720) => otherDeviceClickPos(320, 360)
var otherDeviceClickPos = normalized * otherResolution;
If you know the resolution of the remote screen and you know the size of the picture box then it's simply ratios rounded off to an integer.