Calculating integral sinx dx using Monte Carlo method? - montecarlo

I'm trying to calculate integral -1 to 6 sinx dx, but the following gives result near -1,14 and the correct solution is -0.41987. Where is the mistake? How to make my code look better and more clear?
float MonteCarlo ( float a , float b, long long int N ) // MonteCarlo(-1,6,200) integral -1 to 6 sinx dx
//N number of random (x,y)
{
srand(time(NULL));
float positive = 0; // number of points (x,y): 0<y<sinx
float negative = 0; // number of points (x,y): sinx<y<0
int i;
for(i=0;i<N;i++)
{
float x= ((float) rand()) / (float) RAND_MAX*(b-a)+a;
float y= ((float) rand()) / (float) RAND_MAX*2 -1 ;
if( sin(x)>0 && y<sin(x) ) positive++;
if( sin(x)<0 && y>sin(x) ) negative++;
}
positive=fabs(a-b)*2*(positive/ (float) N);//positive area
negative=fabs(a-b)*2*(negative/ (float) N);//negative area
return positive-negative;
}

I think you can use an easier approach for MC-integration: You first have to compute the expectation of your samples (= sum/N) and then multiply it with (b-a). But in this case you need many (> 1e6) samples to get an acurate result.
Try this:
// MonteCarlo(-1,6,200) integral -1 to 6 sinx dx
float MonteCarlo ( float a , float b, long long int N )
{
srand(time(NULL));
int i;
float sum = 0;
for(i=0;i<N;i++)
{
x= (float) rand()*(b-a) + a;
sum = sum + sin(x);
}
return sum / N * (b-a);
}

Related

Optimize quadratic curve tracing using numeric methods

I am trying to trace quadratic bezier curves, placing "markers" at a given step length distance. Tried to do it a naive way:
const p = toPoint(map, points[section + 1]);
const p2 = toPoint(map, points[section]);
const {x: cx, y: cy} = toPoint(map, cp);
const ll1 = toLatLng(map, p),
ll2 = toLatLng(map, p2),
llc = toLatLng(map, { x: cx, y: cy });
const lineLength = quadraticBezierLength(
ll1.lat,
ll1.lng,
llc.lat,
llc.lng,
ll2.lat,
ll2.lng
);
for (let index = 0; index < Math.floor(lineLength / distance); index++) {
const t = distance / lineLength;
const markerPoint = getQuadraticPoint(
t * index,
p.x,
p.y,
cx,
cy,
p2.x,
p2.y
);
const markerLatLng = toLatLng(map, markerPoint);
markers.push(markerLatLng);
}
This approach does not work since the correlation of a quadratic curve between t and L is not linear. I could not find a formula, that would give me a good approximation, so looking at solving this problem using numeric methods [Newton]. One simple option that I am considering is to split the curve into x [for instance 10] times more pieces than needed. After that, using the same quadraticBezierLength() function calculate the distance to each of those points. After this, chose the point so that the length is closest to the distance * index.
This however would be a huge overkill in terms of algorithm complexity. I could probably start comparing points for index + 1 from the subset after/without the point I selected already, thus skipping the beginning of the set. This would lower the complexity some, yet still very inefficient.
Any ideas and/or suggestions?
Ideally, I want a function that would take d - distance along the curve, p0, cp, p1 - three points defining a quadratic bezier curve and return an array of coordinates, implemented with the least complexity possible.
OK I found analytic formula for 2D quadratic bezier curve in here:
Calculate the length of a segment of a quadratic bezier
So the idea is simply binary search the parameter t until analytically obtained arclength matches wanted length...
C++ code:
//---------------------------------------------------------------------------
float x0,x1,x2,y0,y1,y2; // control points
float ax[3],ay[3]; // coefficients
//---------------------------------------------------------------------------
void get_xy(float &x,float &y,float t) // get point on curve from parameter t=<0,1>
{
float tt=t*t;
x=ax[0]+(ax[1]*t)+(ax[2]*tt);
y=ay[0]+(ay[1]*t)+(ay[2]*tt);
}
//---------------------------------------------------------------------------
float get_l_naive(float t) // get arclength from parameter t=<0,1>
{
// naive iteration
float x0,x1,y0,y1,dx,dy,l=0.0,dt=0.001;
get_xy(x1,y1,t);
for (int e=1;e;)
{
t-=dt; if (t<0.0){ e=0; t=0.0; }
x0=x1; y0=y1; get_xy(x1,y1,t);
dx=x1-x0; dy=y1-y0;
l+=sqrt((dx*dx)+(dy*dy));
}
return l;
}
//---------------------------------------------------------------------------
float get_l(float t) // get arclength from parameter t=<0,1>
{
// analytic fomula from: https://stackoverflow.com/a/11857788/2521214
float ax,ay,bx,by,A,B,C,b,c,u,k,cu,cb;
ax=x0-x1-x1+x2;
ay=y0-y1-y1+y2;
bx=x1+x1-x0-x0;
by=y1+y1-y0-y0;
A=4.0*((ax*ax)+(ay*ay));
B=4.0*((ax*bx)+(ay*by));
C= (bx*bx)+(by*by);
b=B/(2.0*A);
c=C/A;
u=t+b;
k=c-(b*b);
cu=sqrt((u*u)+k);
cb=sqrt((b*b)+k);
return 0.5*sqrt(A)*((u*cu)-(b*cb)+(k*log(fabs((u+cu))/(b+cb))));
}
//---------------------------------------------------------------------------
float get_t(float l0) // get parameter t=<0,1> from arclength
{
float t0,t,dt,l;
for (t=0.0,dt=0.5;dt>1e-10;dt*=0.5)
{
t0=t; t+=dt;
l=get_l(t);
if (l>l0) t=t0;
}
return t;
}
//---------------------------------------------------------------------------
void set_coef() // compute coefficients from control points
{
ax[0]= ( x0);
ax[1]= +(2.0*x1)-(2.0*x0);
ax[2]=( x2)-(2.0*x1)+( x0);
ay[0]= ( y0);
ay[1]= +(2.0*y1)-(2.0*y0);
ay[2]=( y2)-(2.0*y1)+( y0);
}
//---------------------------------------------------------------------------
Usage:
set control points x0,y0,...
then you can use t=get_t(wanted_arclength) freely
In case you want to use get_t_naive and or get_xy you have to call set_coef first
In case you want to tweak speed/accuracy you can play with the target accuracy of binsearch currently set to1e-10
Here optimized (merged get_l,get_t functions) version:
//---------------------------------------------------------------------------
float get_t(float l0) // get parameter t=<0,1> from arclength
{
float t0,t,dt,l;
float ax,ay,bx,by,A,B,C,b,c,u,k,cu,cb,cA;
// precompute get_l(t) constants
ax=x0-x1-x1+x2;
ay=y0-y1-y1+y2;
bx=x1+x1-x0-x0;
by=y1+y1-y0-y0;
A=4.0*((ax*ax)+(ay*ay));
B=4.0*((ax*bx)+(ay*by));
C= (bx*bx)+(by*by);
b=B/(2.0*A);
c=C/A;
k=c-(b*b);
cb=sqrt((b*b)+k);
cA=0.5*sqrt(A);
// bin search t so get_l == l0
for (t=0.0,dt=0.5;dt>1e-10;dt*=0.5)
{
t0=t; t+=dt;
// l=get_l(t);
u=t+b; cu=sqrt((u*u)+k);
l=cA*((u*cu)-(b*cb)+(k*log(fabs((u+cu))/(b+cb))));
if (l>l0) t=t0;
}
return t;
}
//---------------------------------------------------------------------------
For now, I came up with the below:
for (let index = 0; index < Math.floor(numFloat * times); index++) {
const t = distance / lineLength / times;
const l1 = toLatLng(map, p), lcp = toLatLng(map, new L.Point(cx, cy));
const lutPoint = getQuadraticPoint(
t * index,
p.x,
p.y,
cx,
cy,
p2.x,
p2.y
);
const lutLatLng = toLatLng(map, lutPoint);
const length = quadraticBezierLength(l1.lat, l1.lng, lcp.lat, lcp.lng, lutLatLng.lat, lutLatLng.lng);
lut.push({t: t * index, length});
}
const lut1 = lut.filter(({length}) => !isNaN(length));
console.log('lookup table:', lut1);
for (let index = 0; index < Math.floor(numFloat); index++) {
const t = distance / lineLength;
// find t closest to distance * index
const markerT = lut1.reduce((a, b) => {
return a.t && Math.abs(b.length - distance * index) < Math.abs(a.length - distance * index) ? b.t : a.t || 0;
});
const markerPoint = getQuadraticPoint(
markerT,
p.x,
p.y,
cx,
cy,
p2.x,
p2.y
);
const markerLatLng = toLatLng(map, markerPoint);
}
I think only that my Bezier curve length is not working as I expected.
function quadraticBezierLength(x1, y1, x2, y2, x3, y3) {
let a, b, c, d, e, u, a1, e1, c1, d1, u1, v1x, v1y;
v1x = x2 * 2;
v1y = y2 * 2;
d = x1 - v1x + x3;
d1 = y1 - v1y + y3;
e = v1x - 2 * x1;
e1 = v1y - 2 * y1;
c1 = a = 4 * (d * d + d1 * d1);
c1 += b = 4 * (d * e + d1 * e1);
c1 += c = e * e + e1 * e1;
c1 = 2 * Math.sqrt(c1);
a1 = 2 * a * (u = Math.sqrt(a));
u1 = b / u;
a = 4 * c * a - b * b;
c = 2 * Math.sqrt(c);
return (
(a1 * c1 + u * b * (c1 - c) + a * Math.log((2 * u + u1 + c1) / (u1 + c))) /
(4 * a1)
);
}
I believe that the full curve length is correct, but the partial length that is being calculated for the lookup table is wrong.
If I am right, you want points at equally spaced points in terms of curvilinear abscissa (rather than in terms of constant Euclidean distance, which would be a very different problem).
Computing the curvilinear abscissa s as a function of the curve parameter t is indeed an option, but that leads you to the resolution of the equation s(t) = Sk/n for integer k, where S is the total length (or s(t) = kd if a step is imposed). This is not convenient because s(t) is not available as a simple function and is transcendental.
A better method is to solve the differential equation
dt/ds = 1/(ds/dt) = 1/√(dx/dt)²+(dy/dt)²
using your preferred ODE solver (RK4). This lets you impose your fixed step on s and is computationally efficient.

Quickly determine the approximate maximum of an integer vector

I'd like to use the fact that pmax(x, 0) = (x + abs(x)) / 2 on an integer vector using Rcpp for performance.
I've written a naive implementation:
IntegerVector do_pmax0_abs_int(IntegerVector x) {
R_xlen_t n = x.length();
IntegerVector out(clone(x));
for (R_xlen_t i = 0; i < n; ++i) {
int oi = out[i];
out[i] += abs(oi);
out[i] /= 2;
}
return out;
}
which is indeed performant; however, it invokes undefined behaviour should x contains any element larger than .Machine$integer.max / 2.
Is there a way to quickly determine whether or not the vector would be less than .Machine$integer.max / 2? I considered a bit-shifting but this would not be valid for negative numbers.
As mentioned in the comments you can make use of int64_t for intermediate results. In addition, it makes sense to not copy x to out and don't initilize out to zero everywhere:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
IntegerVector do_pmax0_abs_int(IntegerVector x) {
R_xlen_t n = x.length();
IntegerVector out(clone(x));
for (R_xlen_t i = 0; i < n; ++i) {
int oi = out[i];
out[i] += abs(oi);
out[i] /= 2;
}
return out;
}
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::export]]
IntegerVector do_pmax0_abs_int64(IntegerVector x) {
R_xlen_t n = x.length();
IntegerVector out = no_init(n);
for (R_xlen_t i = 0; i < n; ++i) {
int64_t oi = x[i];
oi += std::abs(oi);
out[i] = static_cast<int>(oi / 2);
}
return out;
}
/***R
ints <- as.integer(sample.int(.Machine$integer.max, 1e6) - 2^30)
bench::mark(do_pmax0_abs_int(ints),
do_pmax0_abs_int64(ints),
pmax(ints, 0))[, 1:5]
ints <- 2L * ints
bench::mark(#do_pmax0_abs_int(ints),
do_pmax0_abs_int64(ints),
pmax(ints, 0))[, 1:5]
*/
Result:
> Rcpp::sourceCpp('57310889/code.cpp')
> ints <- as.integer(sample.int(.Machine$integer.max, 1e6) - 2^30)
> bench::mark(do_pmax0_abs_int(ints),
+ do_pmax0_abs_int64(ints),
+ pmax(ints, 0))[, 1:5]
# A tibble: 3 x 5
expression min median `itr/sec` mem_alloc
<bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt>
1 do_pmax0_abs_int(ints) 1.91ms 3.31ms 317. 3.82MB
2 do_pmax0_abs_int64(ints) 1.28ms 2.67ms 432. 3.82MB
3 pmax(ints, 0) 9.85ms 10.68ms 86.9 15.26MB
> ints <- 2L * ints
> bench::mark(#do_pmax0_abs_int(ints),
+ do_pmax0_abs_int64(ints),
+ pmax(ints, 0))[, 1:5]
# A tibble: 2 x 5
expression min median `itr/sec` mem_alloc
<bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt>
1 do_pmax0_abs_int64(ints) 1.28ms 2.52ms 439. 3.82MB
2 pmax(ints, 0) 9.88ms 10.83ms 89.5 15.26MB
Notes:
Without no_init the two C++ methods are equally fast.
I ave removed the original method from the second benchmark, since bench::mark compares the results by default, and the original method produces wrong results for that particular input.

Finding image pixel coordinates (integers) from UV values (floats) of obj file

I am parsing an obj file which contains the texture coordinates (vt) values. From what I understand, vt values are a mapping into the texture image corresponding to this obj.
Assume, I have image im = 400x300 pixels
and I have a vt value
vt .33345 .8998
The mapping says, in the image, go the coordinate :
imageWidth x .3345 , imageHeight x .8998 and use the value there.
I have loaded the image values in a 2-d array.
The problem is, these mapping coordinates are floating values, how am I suppose to map them to the integer values of the pixel coordinates ? I can always truncate the decimal part, round off etc. But does the standard defines which one of the option is to be done ?
UV coordinates to Pixel coordinates :
pix.x = (uv.x * texture.width) -0.5
pix.y = ((1-uv.y) * texture.height) -0.5
The y axis of uv coordinates is opposite to the Pixel coordinates on an image.
For nearest neighbor interpolation, just round off the pixel coordinates.
For bilinear interpolation, calculate the participation percentage from the four neighbouring pixels and do a weighed average.
When UV coordinates go outside of range, there is a choice on how to handle the "texture wrapping":
Here's some java code for bilinear interpolation with "repeat" texture wrapping:
private static int billinearInterpolation(Point2D uv, BufferedImage texture) {
uv.x = uv.x>0 ? uv.x%1 : 1+(uv.x%1);
uv.y = uv.y>0 ? uv.y%1 : 1+(uv.y%1);
double pixelXCoordinate = uv.x * texture.getWidth() - 0.5;
double pixelYCoordinate = (1-uv.y) * texture.getHeight() - 0.5;
pixelXCoordinate = pixelXCoordinate<0?texture.getWidth()-pixelXCoordinate: pixelXCoordinate;
pixelYCoordinate = pixelYCoordinate<0?texture.getHeight()-pixelYCoordinate : pixelYCoordinate;
int x = (int) Math.floor(pixelXCoordinate);
int y = (int) Math.floor(pixelYCoordinate);
double pX = pixelXCoordinate - x;
double pY = pixelYCoordinate - y;
float[] px = new float[]{(float) (1 - pX), (float) pX};
float[] py = new float[]{(float) (1 - pY), (float) pY};
float red = 0;
float green = 0;
float blue = 0;
float alpha = 0;
for (int i = 0; i < px.length; i++) {
for (int j = 0; j < py.length; j++) {
float p = px[i] * py[j];
if (p != 0) {
int rgb = texture.getRGB((x + i)%texture.getWidth(), (y + j)%texture.getHeight());
alpha += (float) ((rgb >> 24) & 0xFF) * p;
red += (float) ((rgb >> 16) & 0xFF) * p;
green += (float) ((rgb >> 8) & 0xFF) * p;
blue += (float) ((rgb >> 0) & 0xFF) * p;
}
}
}
return (((int) alpha & 0xFF) << 24) |
(((int) red & 0xFF) << 16) |
(((int) green & 0xFF) << 8) |
(((int) blue & 0xFF) << 0);
}
Uv-Coordinates are always in the range [0,1]. This means, you will get the actual pixel coordinates by multiplying them with the image size:
texel_coord = uv_coord * [width, height]
Note, that even here one gets floating point values and there are several ways how to deal with them. The most primitive one is to simply round to the next integer to get the nearest texel. A more sophisticated method would be bilinear filtering.

How do you flatten image coordinates into a 1D array?

My source code is from Heterogeneous Computing with OpenCL Chapter 4 Basic OpenCL Examples > Image Rotation. The book leaves out several critical details.
My major problem is that I don't know how to initialize the array that I supply to their kernel (they don't tell you how). What I have is:
int W = inImage.width();
int H = inImage.height();
float *myImage = new float[W*H];
for(int row = 0; row < H; row++)
for(int col = 0; col < W; col++)
myImage[row*W+col] = col;
which I supply to this kernel:
__kernel void img_rotate(__global float* dest_data, __global float* src_data, int W, int H, float sinTheta, float cosTheta)
{
const int ix = get_global_id(0);
const int iy = get_global_id(1);
float x0 = W/2.0f;
float y0 = H/2.0f;
float xoff = ix-x0;
float yoff = iy-y0;
int xpos = (int)(xoff*cosTheta + yoff*sinTheta + x0);
int ypos = (int)(yoff*cosTheta - xoff*sinTheta + y0);
if(((int)xpos>=0) && ((int)xpos < W) && ((int)ypos>=0) && ((int)ypos<H))
{
dest_data[iy*W+ix] = src_data[ypos*W+xpos];
//dest_data[iy*W+ix] = src_data[iy*W+ix];
}
}
I'm having trouble finding the right value for theta too. An integer would be an appropriate value for theta, right?
float theta = 45; // 45 degrees, right?
float cos_theta = cos(theta);
float sin_theta = sin(theta);
When writing my OpenCL code, I always treat each kernel as reading a 3D set of data, regardless if the data is 1D, 2D, or 3D:
__kernel void TestKernel(__global float *Data){
k = get_global_id(0); //also z
j = get_global_id(1); //also y
i = get_global_id(2); //also x
//Convert 3D to 1D
int linear_coord = i + get_global_size(0)*j + get_global_size(0)*get_global_size(1)*k;
//do stuff
}
When doing the clEnqueueNDKernelRange(...), just set the dimension to be:
int X = 500;
int Y = 300;
int Z = 1;
size_t GlobalDim = {Z, Y, X};
This let's all of my kernels work easily in all dimensions.

How to draw partial-ellipse in CF? (Graphics.DrawArc in full framework)

I hope there will be an easy answer, as often times, something stripped out of Compact Framework has a way of being performed in a seemingly roundabout manner, but works just as well as the full framework (or can be made more efficient).
Simply put, I wish to be able to do a function similar to System.Drawing.Graphics.DrawArc(...) in Compact Framework 2.0.
It is for a UserControl's OnPaint override, where an arc is being drawn inside an ellipse I already filled.
Essentially (close pseudo code, please ignore imperfections in parameters):
FillEllipse(ellipseFillBrush, largeEllipseRegion);
DrawArc(arcPen, innerEllipseRegion, startAngle, endAngle); //not available in CF
I am only drawing arcs in 90 degree spaces, so the bottom right corner of the ellipse's arc, or the top left. If the answer for ANY angle is really roundabout, difficult, or inefficient, while there's an easy solution for just doing just a corner of an ellipse, I'm fine with the latter, though the former would help anyone else who has a similar question.
I use this code, then use FillPolygon or DrawPolygon with the output points:
private Point[] CreateArc(float StartAngle, float SweepAngle, int PointsInArc, int Radius, int xOffset, int yOffset, int LineWidth)
{
if(PointsInArc < 0)
PointsInArc = 0;
if(PointsInArc > 360)
PointsInArc = 360;
Point[] points = new Point[PointsInArc * 2];
int xo;
int yo;
int xi;
int yi;
float degs;
double rads;
for(int p = 0 ; p < PointsInArc ; p++)
{
degs = StartAngle + ((SweepAngle / PointsInArc) * p);
rads = (degs * (Math.PI / 180));
xo = (int)(Radius * Math.Sin(rads));
yo = (int)(Radius * Math.Cos(rads));
xi = (int)((Radius - LineWidth) * Math.Sin(rads));
yi = (int)((Radius - LineWidth) * Math.Cos(rads));
xo += (Radius + xOffset);
yo = Radius - yo + yOffset;
xi += (Radius + xOffset);
yi = Radius - yi + yOffset;
points[p] = new Point(xo, yo);
points[(PointsInArc * 2) - (p + 1)] = new Point(xi, yi);
}
return points;
}
I had this exactly this problem and me and my team solved that creating a extension method for compact framework graphics class;
I hope I could help someone, cuz I spent a lot of work to get this nice solution
Mauricio de Sousa Coelho
Embedded Software Engineer
public static class GraphicsExtension
{
// Implements the native Graphics.DrawArc as an extension
public static void DrawArc(this Graphics g, Pen pen, float x, float y, float width, float height, float startAngle, float sweepAngle)
{
//Configures the number of degrees for each line in the arc
int degreesForNewLine = 5;
//Calculates the number of points in the arc based on the degrees for new line configuration
int pointsInArc = Convert.ToInt32(Math.Ceiling(sweepAngle / degreesForNewLine)) + 1;
//Minimum points for an arc is 3
pointsInArc = pointsInArc < 3 ? 3 : pointsInArc;
float centerX = (x + width) / 2;
float centerY = (y + height) / 2;
Point previousPoint = GetEllipsePoint(x, y, width, height, startAngle);
//Floating point precision error occurs here
double angleStep = sweepAngle / pointsInArc;
Point nextPoint;
for (int i = 1; i < pointsInArc; i++)
{
//Increments angle and gets the ellipsis associated to the incremented angle
nextPoint = GetEllipsePoint(x, y, width, height, (float)(startAngle + angleStep * i));
//Connects the two points with a straight line
g.DrawLine(pen, previousPoint.X, previousPoint.Y, nextPoint.X, nextPoint.Y);
previousPoint = nextPoint;
}
//Garantees connection with the last point so that acumulated errors cannot
//cause discontinuities on the drawing
nextPoint = GetEllipsePoint(x, y, width, height, startAngle + sweepAngle);
g.DrawLine(pen, previousPoint.X, previousPoint.Y, nextPoint.X, nextPoint.Y);
}
// Retrieves a point of an ellipse with equation:
private static Point GetEllipsePoint(float x, float y, float width, float height, float angle)
{
return new Point(Convert.ToInt32(((Math.Cos(ToRadians(angle)) * width + 2 * x + width) / 2)), Convert.ToInt32(((Math.Sin(ToRadians(angle)) * height + 2 * y + height) / 2)));
}
// Converts an angle in degrees to the same angle in radians.
private static float ToRadians(float angleInDegrees)
{
return (float)(angleInDegrees * Math.PI / 180);
}
}
Following up from #ctacke's response, which created an arc-shaped polygon for a circle (height == width), I edited it further and created a function for creating a Point array for a curved line, as opposed to a polygon, and for any ellipse.
Note: StartAngle here is NOON position, 90 degrees is the 3 o'clock position, so StartAngle=0 and SweepAngle=90 makes an arc from noon to 3 o'clock position.
The original DrawArc method has the 3 o'clock as 0 degrees, and 90 degrees is the 6 o'clock position. Just a note in replacing DrawArc with CreateArc followed by DrawLines with the resulting Point[] array.
I'd play with this further to change that, but why break something that's working?
private Point[] CreateArc(float StartAngle, float SweepAngle, int PointsInArc, int ellipseWidth, int ellipseHeight, int xOffset, int yOffset)
{
if (PointsInArc < 0)
PointsInArc = 0;
if (PointsInArc > 360)
PointsInArc = 360;
Point[] points = new Point[PointsInArc];
int xo;
int yo;
float degs;
double rads;
//could have WidthRadius and HeightRadius be parameters, but easier
// for maintenance to have the diameters sent in instead, matching closer
// to DrawEllipse and similar methods
double radiusW = (double)ellipseWidth / 2.0;
double radiusH = (double)ellipseHeight / 2.0;
for (int p = 0; p < PointsInArc; p++)
{
degs = StartAngle + ((SweepAngle / PointsInArc) * p);
rads = (degs * (Math.PI / 180));
xo = (int)Math.Round(radiusW * Math.Sin(rads), 0);
yo = (int)Math.Round(radiusH * Math.Cos(rads), 0);
xo += (int)Math.Round(radiusW, 0) + xOffset;
yo = (int)Math.Round(radiusH, 0) - yo + yOffset;
points[p] = new Point(xo, yo);
}
return points;
}

Resources