求平移后的直线方程

ahao 2010-08-06 11:18:50
C++版学生朋友多,问个直线方程问题

已知一个直线的普通式方程 ax+by+c=0 和一个点(m,n)
现在把直线向点方向平移 r 个距离,求这个新的直线的方程,
需要考虑直线垂直于坐标轴的情况

题目描述可能不太正确,但就是这个意思
这个版我只能发200分的,如果能解决问题,另外开贴再送上200分
...全文
903 24 打赏 收藏 举报
写回复
24 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
baihacker 2010-08-07
结果必然是

k * (ax + by + (c +- r * sqrt(a*a+b*b))) = 0的形式。


如果要避免开方,自己看着办。
  • 打赏
  • 举报
回复
baihacker 2010-08-07

中间的直线向上或者向下移动r。
不失一般性而假设p点在中间的直线的上方。
显然只有两种情况,而显然有
P1A < P1B
P2D < P2E
根据对称性,在下方也行。
显然,就是距离近的为所求。
  • 打赏
  • 举报
回复
最帅马老师 2010-08-07
感觉baihacker你的算法有问题,这个没必要开方,这样操作会带入更多误差,且程序效率比较低。
  • 打赏
  • 举报
回复
baihacker 2010-08-07

//重新适当化简后的
//r >= 0
//a*a+b*b > 0
Line solve(Line l, Pt p, Ct r)
{
if (dbcmp(l.online(p)) == 0 || dbcmp(r) == 0) return l;//点在直线上或者平移距离为零
/*
|l.c - c| = r * sqrt(a*a+b*b)
=> c = l.c - r * sqrt(a*a+b*b)或者 l.c + r * sqrt(a*a+b*b)
*/
double delta = sqrt(l.a * l.a + l.b * l.b);
double dist = r * delta;
Line ans1(l.a, l.b, l.c + dist), ans2(l.a, l.b, l.c - dist);

//距离近的为所求:分上有delta,忽略掉。
double x1 = fabs(ans1.online(p)), x2 = fabs(ans2.online(p));
return x1 < x2 ? ans1 : ans2;
}
  • 打赏
  • 举报
回复
ahao 2010-08-07
飞雪你刚写的?厉害
我先理解理解
  • 打赏
  • 举报
回复
baihacker 2010-08-07

double delta = sqrt(l.a * l.a + l.b * l.b);
double dist = r * delta;
之后的代码可以进一步化简:
首先把c1, c2求出来。
再分别计算t1 = l.a * p.x + l.b * p.y + c1, t2 = l.a * p.x + l.b * p.y + c2;

其实后面的计算就是找t1和t2中绝对值较小的,返回绝对值较小对应的方程就是了,这样就避免了那个除以delta的计算。
点在直线上用的是不除以delta的比较,而点到直线的距离是用除以delta的比较,说白了就是计算绝对值较小的。
  • 打赏
  • 举报
回复
baihacker 2010-08-07
//p到目标直线的距离近
double dist1 = p2l(p, ans1);
return dist1 > r ? ans2 : ans1;
//这里写错老,应该是把dist1, dist2都求出来,返回较小的对应的直线。
  • 打赏
  • 举报
回复
hukui161 2010-08-07
接分。。
  • 打赏
  • 举报
回复
ahao 2010-08-07
综合大家的讨论,问题已经解决了,谢谢!
qinken547给的公式和kktemp234的方法对我来说更方便些,
不过baihacker给出的代码和思路更完整些,请baihacker去
http://topic.csdn.net/u/20100807/02/cc971be2-c963-466e-b3f9-ce9bf1c88e65.html
接分
  • 打赏
  • 举报
回复
liutengfeigo 2010-08-07
  • 打赏
  • 举报
回复
baihacker 2010-08-06
typedef double Ct;
struct Pt
{
Pt(Ct _x = 0, Ct _y = 0) : x(_x), y(_y){}
Ct x, y;
};
struct Line
{
Line(Ct _a = 0, Ct _b = 0, Ct _c = 0) : a(_a), b(_b), c(_c){}
Ct online(const Pt& p) const {return a * p.x + b * p.y + c;}
Ct a, b, c;
};
const double pi = acos(-1);
typedef Pt Vec;
#define SQ(x) ((x)*(x))
inline int dbcmp(double x)
{
if (fabs(x) < 1e-8) return 0;
return x > 0 ? 1 : -1;
}
inline Pt operator - (const Pt& a, const Pt& b)
{
return Pt(a.x-b.x, a.y-b.y);
}
inline Pt operator + (const Pt& a, const Pt& b)
{
return Pt(a.x+b.x, a.y+b.y);
}
inline Ct dot(const Pt& a, const Pt& b)
{
return a.x*b.x + a.y*b.y;
}
inline Ct dot(const Pt& a, const Pt& b, const Pt& c)
{
return dot(b-a, c-a);
}
inline Ct cross(const Pt& a, const Pt& b)
{
return a.x * b.y - a.y * b.x;
}
inline Ct cross(const Pt& a, const Pt& b, const Pt& c)
{
return cross(b-a, c-a);
}
inline double norm(const Pt& a)
{
return sqrt(dot(a, a));
}
inline Ct norm2(const Pt& a)
{
return dot(a, a);
}
inline double p2l(const Pt& a, const Line& l)
{
return fabs(l.online(a))/norm(Pt(l.a, l.b));
}
inline Line make_line(const Pt& a, const Pt& b)
{
Line ret;
ret.a = b.y-a.y;
ret.b = -(b.x-a.x);
ret.c = cross(b-a, a);
return ret;
}
inline Pt get_symmetry(const Pt& a, const Line& l)
{
Pt x(l.a, l.b), y(dot(x, a)+2*l.c, cross(x, a));
double t = norm2(x);
return Pt(-dot(y, x)/t, -cross(y, x)/t);
}
inline Vec rotate(const Vec& v, double sita)
{
Pt r(cos(sita), -sin(sita));
return Pt(dot(v, r), -cross(v, r));
}
ostream& operator << (ostream& o, const Pt& p)
{
return o << "(" << p.x << "," << p.y << ")";
}

Line solve(Line l, Pt p, Ct r)
{
if (dbcmp(l.online(p)) == 0 || dbcmp(r) == 0) return l;//点在直线上或者平移距离为零

double delta = sqrt(l.a * l.a + l.b * l.b);
double dist = r * delta;
Line ans1(l.a, l.b, l.c + dist), ans2(l.a, l.b, l.c - dist);//求出两点可能的直线

int x1 = dbcmp(ans1.online(p)), x2 = dbcmp(ans2.online(p));//p就在其中一条直线上
if (x1 == 0) return ans1;
if (x2 == 0) return ans2;

//p到目标直线的距离近
double dist1 = p2l(p, ans1);
return dist1 > r ? ans2 : ans1;
}
  • 打赏
  • 举报
回复
qinken547 2010-08-06
[Quote=引用 10 楼 kktemp234 的回复:]

疏忽了,点的条件不多余,可以判断是加还是减,即在图像平移时该往左移还是往右移,如果这个点恰好在直线上,则左右均可
[/Quote]
楼主说了这点不在直线上....
而且方向只要直线和点是已经的不是未知道数就可以知道点是在直线的上方还是下方,移动方向就只有一个...
但要是都是未知数,讨论情况就多了.....
  • 打赏
  • 举报
回复
qinken547 2010-08-06

  • 打赏
  • 举报
回复
ahao 2010-08-06
[Quote=引用 9 楼 kktemp234 的回复:]

另外,这个和C或C++没多大关系啊,楼主干么发这儿,应发在算法的地儿
[/Quote]

因为这个也算不上很复杂的算法,只是以前学过的东东,现在都忘光了,
我知道c++版学生多,所以来这里问问:)

上面几位的回答,我先想想
  • 打赏
  • 举报
回复
最帅马老师 2010-08-06
疏忽了,点的条件不多余,可以判断是加还是减,即在图像平移时该往左移还是往右移,如果这个点恰好在直线上,则左右均可
  • 打赏
  • 举报
回复
最帅马老师 2010-08-06
另外,这个和C或C++没多大关系啊,楼主干么发这儿,应发在算法的地儿
  • 打赏
  • 举报
回复
最帅马老师 2010-08-06
我认为楼上的理解有问题,下面是我的理解。

已知一个直线的普通式方程 ax+by+c=0 和一个点(m,n)
并没有说这个点在直线上。

对于将直线平移的问题,都是求这个直线的平行簇,设这个直线簇为ax+by+k=0;k为不等于c的任意实数。
直线斜率为-a/b,与x轴夹角为A,则直线向此点平移等效于沿点做此直线的垂线,在垂线上求出距离为r的点。解三角形,由正弦定理可得直线在x方向平移的距离r/sinA,设这个值为k

对于一个函数,当图像在x轴作平移时,平移量为k,则方程为f(x+-k)
因此新的直线方程为a(x+-r/sinA)+by+c=0

点的条件多余,因为总有一条经过点(m,n)且与原直线平行的直线存在

个人理解

  • 打赏
  • 举报
回复
qinken547 2010-08-06
[Quote=引用 6 楼 ahao 的回复:]

我想的办法是,根据直线的角度,用sin和cos计算r在两轴上的位移,对不对?
惭愧得很,解析几何已经全部还给老师了。
[/Quote]
这个方法也可以,不过要先求出已知直线与垂线的交点,然后利用你所说法的方法求出要求的直线与垂线的交点,这样要求的直线已经一个点和斜率就可以求出来了....
  • 打赏
  • 举报
回复
ahao 2010-08-06
我想的办法是,根据直线的角度,用sin和cos计算r在两轴上的位移,对不对?
惭愧得很,解析几何已经全部还给老师了。
  • 打赏
  • 举报
回复
qinken547 2010-08-06

先利用已知直线和已知点求出过已经点直线的垂线,平移r就是按垂线的方向移动,然后再利用r和已经直接的关系求出平移后的直线...可以利用点斜式求出....
坐标轴的情况就更简单了,不说了....
  • 打赏
  • 举报
回复
加载更多回复
相关推荐
发帖
C++ 语言
加入

6.1w+

社区成员

C++ 语言相关问题讨论,技术干货分享,前沿动态等
申请成为版主
帖子事件
创建了帖子
2010-08-06 11:18
社区公告
暂无公告