折线平行线的计算方法

article/2025/8/31 12:07:03

给定一个简单多边形,多边形按照顺时针或者逆时针的数许排列

内部等距离缩小或者外部放大的多边形,实际上是由距离一系列平行已知多边形的边,并且距离为L的线段所构成的。


外围的是原多边形,内侧是新的多边形

算法构造

多边形的相邻两条边,L1和L2,交于Pi点

做平行于L1和L2,平行线间距是L的,并且位于多边形内部的两条边,交于Qi

我们要计算出Qi的坐标

如图,


PiQi向量,显然是等于平行四边形的两个相邻边的向量v1和v2的和的

v1和v2向量的方向,就是组成多边形的边的方向,可以用顶点差来表示

v1和v2向量的长度是相同的,等于平行线间距L与两个线段夹角的sin值的除法。

即: Qi = Pi + (v1 + v2)

    Qi = Pi + L / sinθ * ( Normalize(v2) + Normalize(v1))

    Sin θ = |v1 × v2 | /|v1|/|v2|

计算步骤:

⑴、获取多边形顶点数组PList;

⑵、计算DPList[Vi+1-Vi];

⑶、单位化NormalizeDPList,得到NDP[DPi];(用同一个数组存储)

⑷、Sinα = Dp(i+1) X DP(i);

⑸、Qi = Pi + d/sinα (NDPi+1-NDPi)

⑹、这样一次性可以把所有顶点计算完。

注意,交换Qi表达式当中NDPi+1-NDPi的顺序就可以得到外部多边形顶点数组。

用Swift实现的代码如下,在playground可直接运行


import Foundation


class Point2D  {

    var x:Double =0

    var y:Double =0

    init(_ x:Double,_ y:Double){self.x=x;self.y=y}

    init( point:Point2D){x=point.x;y=point.y}

}


//func += (inout left:Point2D, right:Point2D )     { left.x+=right.x;left.y += right.y;}

func +  (left:Point2D, right:Point2D)->Point2D   {return Point2D(left.x+right.x, left.y+right.y)}

func -  (left:Point2D, right:Point2D)->Point2D   {return Point2D(left.x-right.x, left.y-right.y)}

func *  (left:Point2D, right:Point2D)->Double    {return left.x*right.x + left.y*right.y}

func *  (left:Point2D, value:Double )->Point2D   {return Point2D(left.x*value, left.y*value)}


// 自定义的向量差乘运算符号,

infix operator ** {}

func ** (left:Point2D, right:Point2D)->Double {return left.x*right.y - left.y*right.x}


var pList   = [Point2D]()  // 原始顶点坐标, initPList函数当中初始化赋值

var dpList  = [Point2D]() // 边向量dpListi1 dpLIsti  initDPList函数当中计算后赋值

var ndpList = [Point2D]() // 单位化的边向量, initNDPList函数当中计算后肤质,实际使用的时候,完全可以用dpList来保存他们

var newList = [Point2D]()  // 新的折线顶点,compute函数当中,赋值


// 初始化顶点队列

func initPList(){

    pList  = [ Point2D(0,0),

               Point2D(0,100),

               Point2D(100,100),

               Point2D(50,50),

               Point2D(100,0),

             ]

}


// 初始化dpList  两顶点间向量差

func initDPList()->Void{

    print("计算dpList")

    var index  : Int

    for index=0; index<pList.count; ++index{

        dpList.append(pList[index==pList.count-1 ? 0: index+1]-pList[index]);

        print("dpList[\(index)]=(\(dpList[index].x),\(dpList[index].y))")

    }

}


// 初始化ndpList单位化两顶点向量差

func initNDPList()->Void{

    print("开始计算ndpList")

    var index=0;

    for ; index<dpList.count; ++index {

        ndpList.append(dpList[index] * ( 1.0 /sqrt(dpList[index]*dpList[index])));

        print("ndpList[\(index)]=(\(ndpList[index].x),\(ndpList[index].y))")

    }

}


// 计算新顶点, 注意参数为负是向内收缩, 为正是向外扩张

func computeLine(dist:Double)->Void{

    print("开始计算新顶点")

    var index = 0

    let count = pList.count;

    for ; index<count; ++index {

        var point:Point2D

        let startIndex = index==0 ? count-1 : index-1

        let endIndex   = index

        

        let sina =ndpList[startIndex] **ndpList[endIndex]

        let length = dist / sina

        let vector =ndpList[endIndex] -ndpList[startIndex]

        point = pList[index] + vector*length

        newList.append(point);

        print("newList[\(index)] = (\(point.x),\(point.y))")

    }

}


// 整个算法的调用顺序

func run()->Void {

    initPList();

    initDPList()

    initNDPList()

    computeLine(-5)  // 负数为内缩, 正数为外扩。 需要注意算法本身并没有检测内缩多少后折线会自相交,那不是本代码的示范意图

}


run()





http://chatgpt.dhexx.cn/article/GRY10hb6.shtml

相关文章

两个平面之间的关系—平行、垂直、相交

两个平面可能存在三种关系&#xff1a;平行、垂直、相交。下面介绍这三种关系的判定方法。 平面1的方程为&#xff1a;A1xB1yC1*zD1 0 平面2的方程为&#xff1a;A2xB2yC2*zD2 0 对应的法向量分别为&#xff1a;n1(A1,B1,C1)&#xff0c;n2(A2,B2,C2) 两平面平行的充要条件…

学习OpenCV3:判断两条直线平行,并计算平行距离

一、问题 已知两条直线 l 1 ( x 1 , y 1 , x 2 , y 2 ) l_1(x_1,y_1,x_2,y_2) l1​(x1​,y1​,x2​,y2​)和 l 2 ( x 3 , y 3 , x 4 , y 4 ) l_2(x_3,y_3,x_4,y_4) l2​(x3​,y3​,x4​,y4​)&#xff0c;现希望判断 l 1 l_1 l1​与 l 2 l_2 l2​间是否平行。若平行&#xff0c…

数学空间向量--两条异面直线距离,以及相交并垂直与两条直线的直线。

1.两条异面直线的距离 &#xff08;1&#xff09;第一步先在两条直线上各取一点&#xff0c;&#xff08;如果为点向式方程或者参数方程&#xff0c;我们可以直接用t0的情况取点&#xff09;&#xff0c;然后求两点之间向量。 &#xff08;2&#xff09;第二步求出两条线的方…

空间两直线最近的两个点、距离

已知空间中有直线lineA和直线lineB&#xff0c;求两直线间最近的两点和距离。 using System.Collections; using System.Collections.Generic; using UnityEngine;public class TwoLineMinDis : MonoBehaviour {[SerializeField]private Vector3[] _lineA new Vector3[2];[Ser…

计算空间中两线段之间的距离

最近在建立气凝胶的有限元模型中需要计算每两根纤维&#xff08;线段&#xff09;之间的距离&#xff0c;最初参考的两篇文章确实提供了关于一些数值方法的计算思路&#xff08;文章1 && 文章2&#xff09;&#xff0c;但忽略了线段距离问题的理论推导&#xff0c;导致…

空间两个直线之间的距离和公垂线

已知 直线1&#xff1a;直线任意一点 P 1 P_1 P1​直线方向 V 1 V_1 V1​ (单位向量) 直线2&#xff1a;直线任意一点 P 2 P_2 P2​直线方向 V 2 V_2 V2​ (单位向量) 求解过程 需要用到点到直线的距离和垂足相关内容&#xff0c;参考 这里 下文中 ⋅ \centerdot ⋅代表点…

两点间距离、点到直线距离、点到线段距离、线段到线段距离

两点之间的距离 直接运用两点间距离公式 (x2-x1)^ 2(y2-y1)^ 2开根号 //两点间距离 double getDistancePP(Point a,Point b) { //这个代码是部分代码,有些逻辑没有展现完全,大家往下看!Point c(b.x-a.x,b.y-a.y);//返回一个新的点return c.abs();//取模 }点到直线距离 通常给出…

两平行平面间的距离

两平行平面方程为AxByCzD10&#xff0c;AxByCzD20 转载于:https://www.cnblogs.com/qiu-hua/p/8006040.html

两条平行线相交于一点

2019独角兽企业重金招聘Python工程师标准>>> 欧几里德几何说&#xff0c;两条平行的直线永远无法相交&#xff0c;爱因斯坦站在宇宙空间的角度猜测两条平行线有可能能相交&#xff0c;但到底如何相交&#xff0c;爱因斯坦也没有给出证明&#xff0c;科学家们至今也无…

【opencv】两条平行线之间的距离

问题&#xff1a;一张输入图片&#xff0c;图片上有两条平行线&#xff0c;求出这两条平行线之间的距离 解决思路&#xff1a; 1. 对图像中的直线进行细化 2. 提取直线的轮廓坐标 3. 对轮廓上的坐标进行直线集合&#xff0c;从而得到直线方程 4. 计算两条直线之间的距离 …

OpenCV计算两条平行线之间的距离

代码来自www.opencvchina.com #include "cv.h" #include "highgui.h" #include "cxcore.h" #include <stdlib.h> #include <stdio.h>#ifndef LINESDISHEADER#define LINESDISHEADER//对输入图像进行细化 void ThinImage(IplImage* s…

用vue实现tab切换

用vue实现tab切换 html代码 <div id"app"><ul class"tab-tilte"><li click"cur0" :class"{active:cur0}">html</li><li click"cur1" :class"{active:cur1}">css</li><li…

tab切换(用jQuery实现)?

页面中经常用到的tab栏&#xff0c;来分类展示内容 我认为掌握tab栏切换算是从静态页面到动态页面所迈出的第一步&#xff0c;并且在以后的工作中(jQuery框架开发)会作为jQuery中的常用事件和方法&#xff0c;反复的使用&#xff0c;所以掌握tab栏切换至关重要&#xff01;&am…

JQUERY实现TAB切换

博主是一枚前端小菜鸟&#xff0c;因为挺长时间没接触页面布局了&#xff0c;居然连tab栏切换都给忘了&#xff0c;后来博主看了一些前端资料还有书&#xff0c;发现网上的很多方法都杂乱无章&#xff0c;看的云里雾里的&#xff0c;冗余代码太多&#xff0c;这让新手小白会很苦…

React实现tab切换

下面来编写一个tab选项卡切换效果&#xff0c;效果如下图所示&#xff1a; 下面我放上该组件的代码&#xff1a; import React, { Component } from react; import { Link } from react-router; import ../scss/base.scss; import ../scss/tab.scss;class TabController exten…

vue实现Tab切换功能

在项目开发中&#xff0c;我们经常会碰到Tab切换的功能&#xff0c;而在Vue中想实现这样的功能也应该有很多种&#xff0c;常用的三种应该是 Tab路由切换、Tab动态组件切换、通过v-show设置Tab显示隐藏。每种方法实现起来其实都不难&#xff0c;看看官网介绍或看几篇博客应该就…

tab切换效果

1.效果图 2.分析步骤 1.首先写vue先引入&#xff1a;<script src"https://cdn.jsdelivr.net/npm/vue2.6.14/dist/vue.js"></script> 2.接着写静态布局 3.挂载dom 4.添加指令 5.肯定要储存数据 6. 最后效果实现 3.代码块部分 按步骤操作 1.首先&#xf…

vue中如何实现tab切换功能?

一、v-show控制内容切换 1&#xff09;简单版原理&#xff1a;用点击事件改变num值作为开关&#xff0c;控制tab样式和内容显示隐藏。 2&#xff09;数据渲染原理&#xff1a;主要利用v-for绑定的index来控制&#xff0c;跟上面差不多。 二、组件切换。 知识点主要是vue中is的…

点击tabs切换不同的内容

1.通过v-for遍历posts,然后渲染数据 2.定义currentTabs变量 3.运用computed计算属性 4.点击按钮时&#xff0c;切换下边的内容 5.点击切换tabs时&#xff0c;高亮当前tabs 4.将切换tabs的文件封装成组件&#xff0c;可以使用keep-alive进行缓存数据 5.使用keep-alive触发的生命…

Tab选项卡切换

Tab选项卡切换 基本代码 HTML代码&#xff1a; <div id"notice" class"notice"><!-- 标题--><div id"notice-tit" class"notice-tit"><ul><li><a href"#">公告</a></li>…