我正在尝试创建如下形状:
对于螺旋曲线,我正在使用二次贝塞尔曲线段。
PathGeometry pg1 = new PathGeometry();
PathFigure pf1 = new PathFigure()
{
StartPoint = new Point(Convert.ToDouble(middle) + 500, Convert.ToDouble(middle) + 500)
};
PathSegmentCollection psc1= new PathSegmentCollection();
QuadraticBezierSegment arcs1 = new QuadraticBezierSegment()
{
Point1 = new Point(100, 560),
Point2 = new Point(pf.StartPoint.X - 300, pf.StartPoint.Y + 200)
};
psc1.Add(arcs1);
pf1.Segments = psc1;
pg1.Figures.Add(pf1);
Path spiral1 = new Path()
{
Data = pg1,
Stroke = Brushes.White,
StrokeThickness = 1.5
};
MainScrn.Children.Add(spiral1);
为其中一个路径输出适当的曲线:
我确定我标记错了,但是上面的变量在哪里以及如何与贝塞尔曲线相关联。
现在我想要的是曲线上的点。
我无法从对象那里收到。我试图收集这些点,以便我可以沿Bezier曲线的路径设置物体的运动动画,让它们停在曲线的不同点。我怎样才能做到这一点?
答案 0 :(得分:2)
假设您想要计算从pf1.StartPoint
(P1)到arcs1.Point2
(P3)的三次贝塞尔曲线的五分之一(或任何数量)的控制点{{1 (P2)。
你这样做:
你可以将它减少到polynomial formula,你可以将值插入并得到你的答案,但这可能更具几何直观性,你可以使用{{内置函数轻松实现它1}} class。
答案 1 :(得分:2)
这是完整的答案。我计算了路径的总长度,在路径上分布了30个点(感谢@samgak)。 我通过将长度除以段的数量来找到平均间隔像素长度,然后将其与每个点之间的递增计算(平均值与下一点)的数组进行比较。
这是输出。
这是代码。
PathGeometry pg1 = new PathGeometry();
PathFigure pf1 = new PathFigure()
{
StartPoint = new Point(Convert.ToDouble(middle) + 500, Convert.ToDouble(middle) + 500)
};
PathSegmentCollection psc1= new PathSegmentCollection();
QuadraticBezierSegment arcs1 = new QuadraticBezierSegment()
{
//Point1 = new Point(100, 560),
Point1 = new Point(150, 480),
Point2 = new Point(pf.StartPoint.X - 300, pf.StartPoint.Y + 200)
};
psc1.Add(arcs1);
pf1.Segments = psc1;
pg1.Figures.Add(pf1);
Path spiral1 = new Path()
{
Data = pg1,
Stroke = Brushes.White,
StrokeThickness = 1.5
};
MainScrn.Children.Add(spiral1);
Rectangle[] pnt = new Rectangle[30];
float growth = (float)1 / (float)30;
float loc = 0;
MessageBox.Show(growth.ToString());
double lenOfpath = 0;
Point pntA = new Point(0, 0);
int segments = 8; segments++;
float avgspace = 0;
for (int length = 0; length < pnt.Count(); length++)
{
pnt[length] = new Rectangle();
pnt[length].Fill = Brushes.Red;
pnt[length].Width = 10;
pnt[length].Height = 10;
double t = loc;
double left = (1 - t) * (1 - t) * pf.StartPoint.X + 2 * (1 - t) * t * arcs1.Point1.X + t * t * arcs1.Point2.X;
double top = (1 - t) * (1 - t) * pf.StartPoint.Y + 2 * (1 - t) * t * arcs1.Point1.Y + t * t * arcs1.Point2.Y;
MainScrn.Children.Add(pnt[length]);
Canvas.SetLeft(pnt[length], left);
Canvas.SetTop(pnt[length], top);
loc = loc + growth;
if (length > 0)
{
double x10 = Canvas.GetLeft(pnt[length - 1]);
double x20 = Canvas.GetLeft(pnt[length]);
double y10 = Canvas.GetTop(pnt[length - 1]);
double y20 = Canvas.GetTop(pnt[length]);
lenOfpath = lenOfpath + Math.Sqrt(Math.Pow(x20 - x10, 2) + Math.Pow(y20 - y10, 2));
avgspace = ((float)lenOfpath / (float)segments);
}
}
for (int length = 1; length < pnt.Count(); length++)
{
double total = 0;
double[] smallestpos = new double[pnt.Count()-1];
for (int digger = length + 1; digger < pnt.Count(); digger++)
{
double x11 = Canvas.GetLeft(pnt[length]);
double x22 = Canvas.GetLeft(pnt[digger]);
double y11 = Canvas.GetTop(pnt[length]);
double y22 = Canvas.GetTop(pnt[digger]);
smallestpos[digger-1] = Math.Sqrt(Math.Pow(x22 - x11, 2) + Math.Pow(y22 - y11, 2));
}
int takeposition = FindClosest(avgspace, smallestpos);
double min = smallestpos[takeposition];
while (length < (takeposition+1))
{
pnt[length].Visibility = System.Windows.Visibility.Hidden;
length++;
}
}
}
public static int FindClosest(float given_number, double[] listofflts)
{
// Start min_delta with first element because it's safer
int min_index = 0;
double min_delta = listofflts[0] - given_number;
// Take absolute value of the min_delta
if (min_delta < 0)
{
min_delta = min_delta * (-1);
}
// Iterate through the list of integers to find the minimal delta
// Skip first element because min_delta is set with first element's
for (int index = 1; index < listofflts.Count(); index++)
{
float cur_delta = (float)listofflts[index] - (float)given_number;
// Take absolute value of the current delta
if (cur_delta < 0)
{
cur_delta = cur_delta * (-1);
}
// Update the minimum delta and save the index
if (cur_delta < min_delta)
{
min_delta = cur_delta;
min_index = index;
}
}
return min_index;
}
八角形:
完成所有方面后: