首页 > 其他分享 >尺寸标注的文字应该绘制在哪里?

尺寸标注的文字应该绘制在哪里?

时间:2022-11-23 10:12:56浏览次数:76  
标签:P1 Vf double Vt 尺寸 90 绘制 向量 标注

问题引入

在标注尺寸时,我们会在双向箭头中心处的旁边,绘制对应的文本提示。要绘制的文字位置看起来自然舒服,文本的绘制位置并不是简单地从线段中心点偏移固定值。

计算过程分析

 这里,提供一种计算标注文本位置的计算方式。

    

 如上图,绿色的点是文本位置的起点,经观察发现,文本左侧中心点相对于线段中心点的位置遵循一定的规律:

 

 线段起点终点向量角度 V 为 (0,180]:  

[提示文字左侧中心点 P1 ]、[线段中点]、[P1在V在中点法向量投影点]成直角三角形:  
短直角边 a  = text height
长直角边 b  = text length/2  
直角斜边 c                             

向量 V 右侧法向量角度 Vf=(V-90)
a 和 c 的动态角度 k = (V-90)/90 * atan(b/a)   注:这里k值粗略按等比计算

直角斜边c =a/cos(k)

文字左侧中心点 P1 向量 Vt = Vf + k

----k值初步分析----
V 为 (0,90]     时,k <= 0
V 为 (90,180] 时,k > 0
----特殊值验证----
V 为 90           时,k=0,   Vt=Vf,  c=a
V 为 180         时,k= atan(b/a), Vt=Vf+atan(b/a),  c=a/cos(atan(b/a))

最终坐标:
P1.x = mx + cos(Vt)*c
P1.y = my + sin(Vt)*c

文字绘制坐标:
Ptext.x = P1.x
Ptext.y = P1.y - a/2

代码实现(参考)

//计算绘制文本时相对于线段(x1,y1),(x2,y2)中点的偏移点
void calculateTextOffsetForMiddlePt(double x1, double y1, double x2, double y2, int textLength, int textHeight, int& ptOffsetX, int& ptOffsetY)
{
    /*
    线段起点终点向量角度 V 为 (0,180]:  

[提示文字左侧中心点 P1 ]、[线段中点]、[P1在V在中点法向量投影点]成直角三角形:  
短直角边 a  = text height
长直角边 b  = text length/2  
直角斜边 c                             

向量 V 右侧法向量角度 Vf=(V-90)
a 和 c 的动态角度 k = (V-90)/90 * atan(b/a)   注:这里k值粗略按等比计算

直角斜边c =a/cos(k)

文字左侧中心点 P1 向量 Vt = Vf + k

----k值初步分析----
V 为 (0,90]     时,k <= 0
V 为 (90,180] 时,k > 0
----特殊值验证----
V 为 90           时,k=0,   Vt=Vf,  c=a
V 为 180         时,k= atan(b/a), Vt=Vf+atan(b/a),  c=a/cos(atan(b/a))

最终坐标:
P1.x = mx + cos(Vt)*c
P1.y = my + sin(Vt)*c

文字绘制坐标:
Ptext.x = P1.x 
Ptext.y = P1.y - a/2
    
    */

    //特殊情况
    if (ZMath_IsEqual(x1, x2) && ZMath_IsEqual(y1, y2))
        x2 -= 1.0; //重合时,把 (x1,y1),(x2,y2) 作为 180度线段来计算

    //确保:线段起点终点向量角度 V 为(0, 180]:
    double V = 0.0;
    ZMath_GetVectorAngle(x1, y1, x2, y2, &V);
    if (ZMath_IsEqual(V, 0.0) || (V > 180.0 && !ZMath_IsEqual(V, 180.0)))
        std::swap(x1, x2), std::swap(y1, y2);

    ZMath_GetVectorAngle(x1, y1, x2, y2, &V);

    double Vradian = ZMath_AngleToRadian(V);

    //短直角边 a  = text height ;长直角边 b = text length / 2
    double a = textHeight;
    double b = textLength / 2;

    //向量 V 右侧法向量角度 Vf=(V-90)
    double Vf = V - 90.0;
    double Vfradian = ZMath_AngleToRadian(Vf);

    //a 和 c 的动态角度 k = (V-90)/90 * atan(b/a)   注:这里k值粗略按等比计算
    double k = (V - 90) / 90 * atan(b / a);

    //直角斜边c =a/cos(k)
    double c = a / cos(k);

    //文字左侧中心点 P1 向量 Vt = Vf + k
    double Vtarget = Vfradian + k;

    //最终坐标:
    //P1.x = mx + cos(Vt)*c
    //P1.y = my + sin(Vt)*c
    //所以偏移值为
    double offsetX = cos(Vtarget) * c;
    double offsetY = sin(Vtarget) * c * -1; /* 绘制时是以左上角为原点,向上Y为负,向下Y为正,所以这里 Y 值乘以 -1 */

    //文字绘制坐标:
    //Ptext.x = P1.x 
    //Ptext.y = P1.y - a/2
    ptOffsetX = (int)offsetX;
    ptOffsetY = (int)(offsetY + a / 2); /* 绘制时是以左上角为原点,向上Y为负,向下Y为正,所以这里 Y 值加上 a/2 */
}

上述代码中:

ZMath_IsEqual 为判断两个浮点数是否相等,精度为 0.01

ZMath_GetVectorAngle 为获得线段的向量角度

ZMath_AngleToRadian 为角度转弧度

 


 

本文地址:https://www.cnblogs.com/BensonLaur/p/16916827.html

标签:P1,Vf,double,Vt,尺寸,90,绘制,向量,标注
From: https://www.cnblogs.com/BensonLaur/p/16916827.html

相关文章

  • # VS2022手动引入easyX绘制工具
    1.下载EasyX_20220901.exe安装包,手动修改后缀名为7z,解压2、找到vs的安装目录\MicrosoftVisualStudio\2022\Professional\VC\Auxiliary\VS3、把前面解压出来的include......
  • 小程序canvas2D绘制印章,话不多说,直接上代码
    效果图:  CanvasContext是旧版的接口,不维护了,新版Canvas2D接口与Web一致  官方文档: https://developers.weixin.qq.com/miniprogram/dev/api/canvas/......
  • canvas绘制圆角矩形
     canvas绘制圆角矩形Canvas并没有提供绘制圆角矩形的方法,但是通过观察,我们可以发现,其实我们可以将圆角矩形分为四段,可以通过使用arcTo来实现我们假设起点为x,y.绘......
  • PS新手教程-如何使用PS给产品图片加上尺寸标识
    如何使用PS给产品图片加上尺寸标识?给大家介绍如何使用PS给产品图片加上尺寸标识,一起来看看吧。1.Ctrl+O指定打开图像。如下图:2.使用路径“矩形工具”快捷键l“U”,前景色为红......
  • react-native获取屏幕尺寸
    react-native获取屏幕尺寸 项目中需要获取手机的尺寸import{Dimensions}from"react-native"varWINDOW=Dimensions.get("window");varwidth=WINDOW.width;......
  • python 图片点击左键标注序号
    importcv2#引用opencvimportnumpyasnp#图片路径img=cv2.imread('Images\CAD2.png')a=[]b=[]counts=0#生成序号方法deffun():globalcounts#添加......
  • 学习使用d3.arc()绘制图形
    d3.arc()是一个弧度生成器,该生成器在被调用时会返回一个字符串,可以赋值给path元素的d属性,用于生成圆弧、圆形和环形。其中0弧度位于12点钟方向,正弧度沿着顺时针方向设......
  • 1.使用matplotlib绘制折线图
    importmatplotlib.pyplotaspltplt.rcParams['font.sans-serif']=['SimHei']#用来正常显示中文标签plt.rcParams['axes.unicode_minus']=False#用来正常显示负号in......
  • 在Vue中使用Canvas绘制动态背景
    好家伙, 发现了,在created(){}钩子函数中使用canvas画布貌似是错误的行为 vue中canvas的使用-掘金(juejin.cn) 于是我们琢磨一下 找到cancas元素;创建cont......
  • python语言绘图:绘制贝叶斯方法中最大后验密度(Highest Posterior Density, HPD)区间图的
    代码源自:https://github.com/PacktPublishing/Bayesian-Analysis-with-Python  内容接前文:​​python语言绘图:绘制贝叶斯方法中最大后验密度(HighestPosteriorDensity,......