Mountain wind farm wind turbine chain layout data optimization calculation method

By constructing elevation driving vector rules and wake propagation models to optimize the chain layout of wind turbines, the problem of wind turbine layout in mountainous wind farms being difficult to adapt to terrain features was solved, achieving efficient chain distribution and wake suppression, and improving the power generation efficiency and resource utilization of wind farms.

CN120874681BActive Publication Date: 2025-12-12武汉智博创享科技股份有限公司
View PDF 2 Cites 0 Cited by

Patent Information

Application Number
CN202511371290.5
Authority / Receiving Office
CN · China
Patent Type
Patents(China)
Current Assignee / Owner
Filing Date
2025-09-24
Publication Date
2025-12-12
Estimated Expiration
2045-09-24

AI Technical Summary

Technical Problem

Existing technologies fail to establish a linkage rule between elevation change vector and wake effect analysis in the wind turbine layout of mountain wind farms. This makes it difficult for wind turbine layout to adapt to the characteristics of mountainous terrain, and it is impossible to achieve efficient chain distribution and to take into account the synergistic optimization of terrain adaptability and wake suppression.

Method used

By constructing elevation driving vector rules, extracting ridgeline elevation vectors based on DEM data, and combining them with a wake propagation model, the chain layout path of wind turbines is optimized. By adopting a staggered arrangement of wind turbines and dynamically adjusting the spacing and direction, the three-dimensional coordinate calculation and visualization optimization of wind turbines are realized.

Benefits of technology

It improves the utilization rate of wind energy resources, reduces wake loss, enhances the power generation efficiency of wind farms, shortens the design cycle, optimizes the layout efficiency, and provides a scientific paradigm for the layout of mountain wind farms.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN120874681B_ABST
    Figure CN120874681B_ABST
Patent Text Reader

Abstract

The present application relates to the field of new energy development and construction, and discloses a mountainous wind farm wind turbine chain layout data optimization calculation method, comprising the following steps: S1: ridge line extraction and elevation driving vector construction, S2: starting point determination and initial direction calibration, S3: chain layout path planning, S4: wind turbine coordinate calculation, S5: application of wake effect suppression algorithm, S6: wind turbine screening, state marking and coordinate output. The present application constructs an elevation driving vector rule, extracts a ridge line elevation vector based on DEM data, makes the wind turbines present a chain distribution along the main terrain features, accurately adapts to the mountainous undulating morphology, and avoids wind energy loss caused by terrain obstruction. At the same time, combined with automatic chain planning, the wind turbine three-dimensional coordinates are automatically calculated by chain expansion along the ridge line from the starting point, which improves the complex mountainous data processing efficiency by more than 3 times compared with the traditional manual method, greatly shortens the preliminary design cycle, and significantly optimizes the layout efficiency.
Need to check novelty before this filing date? Find Prior Art

Description

TECHNICAL FIELD

[0001] The present application relates to the field of new energy development and construction, in particular to a mountainous wind farm wind turbine chain layout data optimization calculation method. BACKGROUND

[0002] The mountainous wind farm is a wind energy development project constructed in a mountainous environment with large terrain undulations and complex elevation changes. The distribution of wind energy resources is significantly affected by factors such as terrain cutting, elevation gradient, and slope direction. Wind turbine layout needs to consider the dual effects of terrain shielding and wake effect to achieve efficient utilization of wind energy resources. It is a planning and design scenario with high terrain adaptability requirements in the field of new energy development.

[0003] In the existing technology, geographic information system (GIS) and digital elevation model (DEM) are used for terrain analysis in the layout of wind turbines in mountainous wind farms. By extracting terrain features such as ridge lines and combining with empirical rules, the wind turbine layout is determined. At the same time, some methods use wake propagation models to calculate the wake effect between wind turbines to provide a reference for spacing adjustment, which to some extent improves the scientificity of the layout.

[0004] The most critical deficiency of the existing technology is that it fails to form a linkage rule between the elevation change vector and the wake effect analysis, making it impossible to achieve dynamic coupling of "elevation - wake - layout". This results in the difficulty of self-adapting to the mountainous terrain features to form an efficient chain distribution, and the difficulty of balancing the terrain adaptability and wake suppression. In view of this, we propose a mountainous wind farm wind turbine chain layout data optimization calculation method. SUMMARY

[0005] To overcome the deficiencies of the prior art, the present application provides a mountainous wind farm wind turbine chain layout data optimization calculation method, which solves the problem that the prior art fails to form a linkage rule between the elevation change vector and the wake effect analysis.

[0006] To achieve the above purpose, the present application is implemented by the following technical scheme: a mountainous wind farm wind turbine chain layout data optimization calculation method, comprising the following steps:

[0007] S1: Ridge line extraction and elevation driven vector construction, obtain the digital elevation model data of the target area, extract the ridge line by the drainage analysis method, calculate the elevation gradient and slope direction vector of each point along the ridge line based on the three-dimensional coordinates of the ridge line, and form the elevation driven vector field to provide terrain data support for S2;

[0008] S2: Start point determination and initial direction calibration, based on the ridge line and elevation driven vector field obtained in S1, select the maximum elevation point within the ridge line range as the starting point, and calibrate the initial direction along the positive elevation vector of the ridge line with the starting point as the origin, to provide the starting reference for S3;

[0009] S3: chain layout path planning, based on the starting point and initial direction determined in S2, the main chain path is determined along the ridge line elevation positive vector, and when the terrain is mutated, the branch path is generated along the elevation gentle slope direction perpendicular to the main chain to provide path basis for S4;

[0010] S4: fan coordinate calculation, starting from the starting point determined in S2, along the main chain and branch path planned in S3, combining the elevation gradient obtained in S1 to calculate the coordinates of each fan;

[0011] S5: application of wake effect suppression algorithm, based on the fan coordinates obtained in S4, the elevation difference and actual distance of adjacent fans are calculated, the position is adjusted according to the upwind and leeward spacing rules, and the cross staggered arrangement is adopted;

[0012] S6: fan screening, state marking and coordinate output, based on the adjustment results of S5, the fan is screened and marked, and the three-dimensional coordinates of the fan meeting the conditions and the related list and layout diagram are output.

[0013] Preferably, in the S1 ridge line extraction and elevation driving vector construction, when processing digital elevation model data, the cell size and neighborhood search radius need to be set, the digital elevation model grid is constructed, the slope and slope direction of each point are calculated, and then the ridge line is extracted by applying watershed analysis. The elevation driving vector field includes slope, slope direction and elevation gradient parameters.

[0014] Preferably, in the S1 ridge line extraction and elevation driving vector construction, when extracting the ridge line, the digital elevation model grid is traversed to determine the ridge point by judging whether the elevation of a point is greater than the elevations of its surrounding 8 neighbors, and then the continuous ridge line is formed by connecting the ridge points according to the elevation vector field.

[0015] Preferably, in the S2 starting point determination and initial direction calibration, the starting point is the point with the maximum elevation in the ridge line range, and its three-dimensional coordinates are X0, Y0, Z0. The initial direction calibration needs to calculate the elevation gradient vector of the starting point, and combine the dominant wind direction angle range 0-360 degrees, with north as 0, clockwise increase adjustment, so that the calibrated direction is not perpendicular to the dominant wind direction.

[0016] Preferably, in the S3 chain layout path planning, the width of the main chain path is 3 times the fan impeller diameter, the terrain mutation refers to the elevation difference > 50m, the branch path is generated along the elevation gentle slope direction perpendicular to the main chain and the slope < 15°, and the angle between the branch path and the main chain is 30°-45°.

[0017] Preferably, in the S3 chain layout path planning, the ridge line points are sorted from high to low in elevation when generating the main chain path, and the chain is expanded along the ridge line from the starting point; the direction of the main chain at the branch point is calculated first when generating the branch path, then a plurality of possible directions perpendicular to the main chain are generated, and the optimal direction is selected by evaluating the slope and direction consistency.

[0018] Preferably, in the S4 fan coordinate calculation, the main chain path has a basic step length of 3D, where D is the diameter of the fan impeller, and the branch path has a basic step length of 2D, and when the slope is greater than 20°, the step length increases by 20%, and the coordinates are calculated by moving along the path from the starting point, combining with the elevation gradient to correct the actual distance, and dynamically updating the advancing direction until the path endpoint.

[0019] Preferably, in the application of the S5 wake effect suppression algorithm, the upwind fan spacing is greater than or equal to 10 times the elevation difference, and the downwind fan spacing is greater than or equal to 20 times the elevation difference, the elevation difference is the absolute value of the elevation difference between adjacent fans, and the actual distance is the straight line distance in three-dimensional space between adjacent fans; if the spacing does not meet the requirements, the fan position is moved along the path direction to meet the requirements.

[0020] Preferably, in the application of the S5 wake effect suppression algorithm, the cross staggered arrangement is achieved by calculating a vector perpendicular to the branch direction, and a lateral offset of 0.5D is applied to the branch fan, where D is the staggered offset of the fan impeller diameter, and the offset directions of adjacent branch fans are opposite to form alternating positive and negative offsets.

[0021] Preferably, in the S6 fan screening, state marking and coordinate output, the screening marking rule is: the fan with a spacing less than 10 times the elevation difference in the upwind direction is marked red and removed, the fan with a spacing less than 20 times the elevation difference in the downwind direction is marked yellow and needs to be optimized, and the fan that meets the spacing requirements is marked green and retained; the coordinate output content includes the three-dimensional coordinates X, Y, Z of the green fan, the chain layout coordinate list, including the fan number, coordinate value, elevation difference and layout diagram.

[0022] The present application provides a mountain wind farm fan chain layout data optimization calculation method. It has the following beneficial effects:

[0023] 1、The present application constructs an elevation driving vector rule, extracts the ridge line elevation vector based on DEM data, makes the fan chain distributed along the terrain dominant feature, accurately adapts to the mountain undulating form, and avoids the loss of wind energy caused by terrain obstruction. At the same time, combined with automatic chain planning, the three-dimensional coordinates of the fan are automatically calculated along the ridge line chain from the starting point, which improves the complex mountain data processing efficiency by more than 3 times compared with the traditional manual method, greatly shortens the pre-design cycle, and significantly optimizes the layout efficiency.

[0024] 2. This invention quantifies the correlation between the elevation difference and distance between wind turbines. Based on the 10x / 20x elevation difference rule, it dynamically optimizes the spacing and staggered angle of the chain arrangement using a wake propagation model, reducing the wake interference of upstream turbines on downstream turbines. The main chain and branch turbines are arranged in a staggered manner, further reducing the wake overlap area, which can reduce wake loss by more than 30% and improve the overall power generation efficiency of the wind farm by 5% to 7%.

[0025] 3. This invention integrates 3D visualization functionality via a web interface, displaying in real-time the wind turbine deployment location, elevation vector direction, and wake influence range. It allows users to adjust deployment parameters, improving the feasibility of the plan. Simultaneously, through elevation-driven terrain-adaptive design, it increases wind energy resource utilization by 8%–12% compared to traditional empirical ridgeline deployment methods, providing a scientific deployment paradigm for complex mountain wind farms and promoting technological upgrades in mountain wind power development. Attached Figure Description

[0026] Figure 1 Flowchart of the data optimization calculation method for chain-type wind turbine deployment in this mountainous wind farm;

[0027] Figure 2 This is a schematic diagram of ridgeline extraction according to the present invention;

[0028] Figure 3 This is a schematic diagram of the chain-like deployment path planning of the present invention;

[0029] Figure 4 This is a schematic diagram of the wind turbine selection rules of the present invention;

[0030] Figure 5 This is a flowchart illustrating the technical process of the present invention. Detailed Implementation

[0031] The technical solutions in the embodiments of the present invention will be clearly and completely described below with reference to the accompanying drawings. Obviously, the described embodiments are only some embodiments of the present invention, and not all embodiments. Based on the embodiments of the present invention, all other embodiments obtained by those skilled in the art without creative effort are within the scope of protection of the present invention.

[0032] Example:

[0033] Please see the appendix Figure 1 - Appendix Figure 5 This invention provides a method for optimizing the calculation of wind turbine chain deployment data in mountainous wind farms, comprising the following steps:

[0034] S1: Ridgeline extraction and elevation driving vector construction. Obtain digital elevation model data of the target area, extract ridgelines through watershed analysis, calculate the elevation gradient and aspect vector of each point along the ridgeline based on the three-dimensional coordinates of the ridgeline, and form an elevation driving vector field to provide terrain data support for S2.

[0035] In the extraction of the S1 ridgeline and the construction of the elevation driving vector, when processing the digital elevation model data, it is necessary to set the cell size and the neighborhood search radius. By constructing the digital elevation model grid, calculating the slope and aspect of each point, and then applying watershed analysis to extract the ridgeline, the elevation driving vector field includes slope, aspect, and elevation gradient parameters.

[0036] In the S1 ridgeline extraction and elevation driving vector construction, when extracting the ridgeline, the ridge point is determined by traversing the digital elevation model grid and judging whether the elevation of a certain point is greater than the elevations of its eight neighboring points. Then, the ridge points are connected according to the elevation vector field to form a continuous ridgeline. The algorithm includes the following:

[0037] /

[0038] Process DEM data, extract ridgelines and calculate elevation vector fields.

[0039] @param {Array} demData - An array of DEM data points in the format {x, y, z}.

[0040] @param {number} cellSize - DEM cell size (meters)

[0041] @param {number} searchRadius - Neighborhood search radius (used to calculate gradient)

[0042] @returns {Object} - The resulting object containing the ridgeline and elevation vector fields.

[0043] /

[0044] function processDEMAndExtractRidges(demData, cellSize = 10,searchRadius = 30) {

[0045] / / 1. Construct the DEM grid (if the data has not yet been gridded)

[0046] const demGrid = buildDEMGrid(demData, cellSize);

[0047] / / 2. Calculate the slope and aspect at each point.

[0048] const gradientField = calculateGradientField(demGrid, cellSize);

[0049] / / 3. Apply watershed analysis to extract ridge lines

[0050] const ridgeLines = extractRidgeLines(demGrid, gradientField,cellSize);

[0051] / / 4. Calculate the dominant direction of extension of the ridge lines

[0052] const dominantDirection = calculateDominantDirection(ridgeLines);

[0053] / / 5. Optimize the ridge lines and elevation vector field based on the dominant direction

[0054] const optimizedRidgeLines = optimizeRidgeLines(ridgeLines,dominantDirection);

[0055] const elevationVectorField = calculateElevationVectorField(optimizedRidgeLines, gradientField, searchRadius);

[0056] return {

[0057] demGrid,

[0058] gradientField,

[0059] ridgeLines: optimizedRidgeLines,

[0060] dominantDirection,

[0061] elevationVectorField

[0062] };

[0063] }

[0064] /

[0065] Extract ridge lines

[0066] /

[0067] function extractRidgeLines(demGrid, gradientField, cellSize) {

[0068] const { grid, width, height} = demGrid;

[0069] const ridgePoints = [];

[0070] / / Find local maxima (ridge points)

[0071] for (let row = 1; row < height - 1; row++) {

[0072] for (let col = 1; col < width - 1; col++) {

[0073] const currentHeight = grid[row][col];

[0074] const isPeak =

[0075] currentHeight >= grid[row-1][col] &&

[0076] currentHeight >= grid[row+1][col] &&

[0077] currentHeight >= grid[row][col-1] &&

[0078] currentHeight >= grid[row][col+1] &&

[0079] currentHeight >= grid[row-1][col-1] &&

[0080] currentHeight >= grid[row-1][col+1] &&

[0081] currentHeight >= grid[row+1][col-1] &&

[0082] if (isPeak) { ridgePoints.push({ row, col, height: currentHeight});}}} return ridgePoints;}currentHeight >= grid[row+1][col+1];

[0083] if (isPeak) {

[0084] ridgePoints.push({

[0085] x: col cellSize + demGrid.minX,

[0086] y: row cellSize + demGrid.minY,

[0087] z: currentHeight,

[0088] row,

[0089] col

[0090] });

[0091] }

[0092] }

[0093] }

[0094] / / Connecting ridge points forms a ridgeline

[0095] const ridgeLines = connectRidgePoints(ridgePoints, gradientField,demGrid);

[0096] return ridgeLines;

[0097] }

[0098] S2: Determination of starting point and calibration of initial direction. Based on the ridgeline and elevation driving vector field obtained in S1, the point with the maximum elevation value within the ridgeline range is selected as the starting point. The initial direction is calibrated along the positive elevation vector of the ridgeline with the starting point as the origin, providing the starting reference for S3.

[0099] In the determination of the S2 starting point and initial direction calibration, the starting point is the point with the highest elevation within the ridgeline area, and its three-dimensional coordinates are X0, Y0, Z0. Initial direction calibration requires calculating the elevation gradient vector of the starting point, combined with the prevailing wind direction angle range of 0-360 degrees, with due north as 0, and adjusting clockwise to ensure that the calibrated direction is not perpendicular to the prevailing wind direction. This includes the following algorithms:

[0100] /

[0101] Highest point identification and starting vector calibration algorithm

[0102] @param {Array} ridgePoints - Ridge line point set, format as an array of points in {x, y, z}

[0103] @param {number} windDirection - Dominant wind direction (angle, 0-360 degrees, true north is 0, increasing clockwise)

[0104] @returns {Object} - Object containing the highest point and the calibrated initial vector

[0105] / function identifyHighestPointAndCalibrateVector(ridgePoints,windDirection) {

[0106] / / 1. Highest point identification

[0107] const highestPoint = findHighestPoint(ridgePoints);

[0108] / / 2. Calculate the elevation gradient vector (slope vector) at the highest point

[0109] const slopeVector = calculateSlopeVector(ridgePoints,highestPoint);

[0110] / / 3. Calibrate the initial vector to avoid being perpendicular to the dominant wind direction

[0111] const calibratedVector = calibrateVectorWithWindDirection(slopeVector, windDirection);

[0112] return {

[0113] highestPoint,

[0114] initialVector: calibratedVector

[0115] };}

[0116] /

[0117] Finding the highest point in a point set

[0118] @param {Array} points - Point set, array of points in the format {x, y, z}

[0119] @returns {Object} - Highest point {x, y, z}

[0120] / function findHighestPoint(points) {

[0121] if (!points || points.length === 0) {

[0122] throw new Error("Point set cannot be empty");

[0123] }

[0124] let highestPoint = points[0];

[0125] for (const point of points) {

[0126] if (point.z > highestPoint.z) {

[0127] highestPoint = point;

[0128] }

[0129] }

[0130] return highestPoint;}

[0131] /

[0132] Calculates the elevation gradient vector (slope vector) for a given point

[0133] @param {Array} points - Point set, array of points in the format {x, y, z}

[0134] @param {Object} targetPoint - Target point {x, y, z}

[0135] @param {number} searchRadius - Search radius (meters) to determine neighborhood range

[0136] @returns {Object} - Gradient vector {x, y, magnitude}

[0137] / function calculateSlopeVector(points, targetPoint, searchRadius =50) {

[0138] / / Find points within a specified radius around the target point

[0139] const neighbors = points.filter(point => {

[0140] const dx = point.x - targetPoint.x;

[0141] const dy = point.y - targetPoint.y;

[0142] return Math.sqrt(dx × dx + dy × dy) <= searchRadius;

[0143] });

[0144] if (neighbors.length < 3) {

[0145] / / Too few points in the neighborhood to calculate the gradient

[0146] return { x: 0, y: 0, magnitude: 0};

[0147] }

[0148] / / Fit the plane using the least squares method and calculate the gradient vector.

[0149] let sumX = 0, sumY = 0, sumZ = 0;

[0150] let sumX2 = 0, sumXY = 0, sumYZ = 0, sumXZ = 0;

[0151] for (const point of neighbors) {

[0152] const x = point.x - targetPoint.x;

[0153] const y = point.y - targetPoint.y;

[0154] const z = point.z - targetPoint.z;

[0155] sumX += x;

[0156] sumY += y;

[0157] sumZ += z;

[0158] sumX2 += x × x;

[0159] sumXY += x × y;

[0160] sumYZ += y × z;

[0161] sumXZ += x × z;

[0162] }

[0163] const n = neighbors.length;

[0164] const denominator = sumX2 × n - sumX × sumX;

[0165] if (denominator === 0) {

[0166] / / Prevent division by zero error

[0167] return { x: 0, y: 0, magnitude: 0};

[0168] }

[0169] / / Calculate the coefficients a and b in the plane equation z = ax + by + c

[0170] const a = (sumXZ × n - sumX × sumZ) / denominator;

[0171] const b = (sumYZ - b × sumXY) / (sumY × sumY - n × sumXY);

[0172] / / The gradient vector is in the negative direction of (a, b) (pointing in the direction of increasing elevation).

[0173] const gradientX = -a;

[0174] const gradientY = -b;

[0175] const magnitude = Math.sqrt(gradientX × gradientX + gradientY ×gradientY);

[0176] / / Normalize the vector

[0177] if (magnitude > 0) {

[0178] return {

[0179] x: gradientX / magnitude,

[0180] y: gradientY / magnitude,

[0181] magnitude: magnitude

[0182] };

[0183] } else {

[0184] return { x: 0, y: 0, magnitude: 0};

[0185] }}

[0186] /

[0187] Align the vector direction to avoid being perpendicular to the dominant wind direction

[0188] @param {Object} vector - Original vector {x, y, magnitude}

[0189] @param {number} windDirection - Dominant wind direction (angle, 0-360 degrees)

[0190] @param {number} minAngle - Minimum allowed angle (degrees), the angle with the dominant wind direction should be greater than this value

[0191] @returns {Object} - Aligned vector {x, y, magnitude}

[0192] / function calibrateVectorWithWindDirection(vector, windDirection,minAngle = 30) {

[0193] if (vector.magnitude === 0) {

[0194] / / If the vector is a zero vector, return a vector based on the dominant wind direction

[0195] const windRad = (windDirection - 90) × Math.PI / 180; / / Convert to radians, adjust so that true north is 0

[0196] return {

[0197] x: Math.cos(windRad),

[0198] y: Math.sin(windRad),

[0199] magnitude: 1

[0200] };

[0201] }

[0202] / / Calculate the direction angle (in radians) of the vector

[0203] const vectorAngle = Math.atan2(vector.y, vector.x);

[0204] / / Calculate the angle (in radians) between the vector and the dominant wind direction

[0205] const windRad = (windDirection - 90) × Math.PI / 180; / / Adjust so that true north is 0

[0206] let angleDiff = Math.abs(vectorAngle - windRad);

[0207] / / Ensure the angle difference is within the [0, π] range

[0208] if (angleDiff > Math.PI) {

[0209] angleDiff = 2 × Math.PI - angleDiff;

[0210] }

[0211] / / Convert minimum angle to radians

[0212] const minAngleRad = minAngle × Math.PI / 180;

[0213] / / If the angle difference is less than the minimum allowed angle, adjust the vector direction

[0214] if (angleDiff < minAngleRad || Math.abs(angleDiff - Math.PI) <minAngleRad) {

[0215] / / Calculate two possible adjustment directions

[0216] const perpendicular1 = windRad + Math.PI / 2;

[0217] const perpendicular2 = windRad - Math.PI / 2;

[0218] / / Choose the adjustment direction that is closer to the original vector direction

[0219] const diff1 = Math.abs(vectorAngle - perpendicular1);

[0220] const diff2 = Math.abs(vectorAngle - perpendicular2);

[0221] const newAngle = diff1 < diff2? perpendicular1 : perpendicular2;

[0222] / / Return the adjusted vector

[0223] return {

[0224] x: Math.cos(newAngle),

[0225] y: Math.sin(newAngle),

[0226] magnitude: vector.magnitude

[0227] };

[0228] }

[0229] / / Angle difference is acceptable, return original vector

[0230] return vector;}

[0231] S3: Chain layout path planning, based on the starting point and initial direction determined in S2, the main chain path is drawn along the ridge line elevation positive vector, and when encountering terrain mutation, branch paths are generated along the elevation gentle slope direction perpendicular to the main chain to provide path basis for S4;

[0232] In the S3 chain layout path planning, the main chain path width is 3 times the fan impeller diameter, the terrain mutation refers to the elevation difference > 50m, the branch path is generated along the elevation gentle slope direction perpendicular to the main chain and the slope is < 15°, and the angle between the branch path and the main chain is 30°~45°;

[0233] In the S3 chain layout path planning, when generating the main chain path, the points of the ridge line need to be sorted from high to low according to the elevation, and the chain is expanded along the ridge line from the starting point; when generating the branch path, the direction of the main chain at the branch point needs to be calculated first, then multiple possible directions perpendicular to the main chain are generated, and the optimal direction is selected through evaluation of the slope and direction consistency, including the following algorithms:

[0234] /

[0235] Generate turbine layout path (main chain and branch)

[0236] @param {Array} ridgePoints - Ridge line point set, format is an array of points in {x, y, z} format

[0237] @param {number} turbineDiameter - Fan impeller diameter (meters)

[0238] @returns {Object} - An object containing the main chain and branch paths

[0239] / function generateTurbinePaths(ridgePoints, turbineDiameter) {

[0240] const pathWidth = turbineDiameter × 3; / / Path width is 3 times the impeller diameter

[0241] const elevationThreshold = 50; / / Elevation difference threshold (meters)

[0242] const slopeThreshold = 15; / / Maximum slope threshold (degrees)

[0243] const minBranchAngle = 30; / / Minimum branch angle (degrees)

[0244] const maxBranchAngle = 45; / / Maximum branch angle (degrees)

[0245] / / 1. Sort ridge line points by elevation (optional, to ensure processing from high to low)

[0246] const sortedPoints = [...ridgePoints].sort((a, b) => b.z - a.z);

[0247] / / 2. Generate main path

[0248] const mainPath = generateMainPath(sortedPoints, pathWidth, elevationThreshold);

[0249] / / 3. Generate branch paths

[0250] const branchPaths = generateBranchPaths(mainPath, ridgePoints, pathWidth,

[0251] elevationThreshold, slopeThreshold, minBranchAngle, maxBranchAngle);

[0252] return {

[0253] mainPath,

[0254] branchPaths,

[0255] pathWidth

[0256] };}

[0257] /

[0258] Generate main path

[0259] @param {Array} ridgePoints - Set of ridge line points

[0260] @param {number} pathWidth - Path width (meters)

[0261] @param {number} elevationThreshold - Elevation drop threshold (meters)

[0262] @returns {Array} - Main path point set

[0263] / function generateMainPath(ridgePoints, pathWidth,elevationThreshold) {

[0264] if (ridgePoints.length < 2) return [];

[0265] const mainPath = [ridgePoints[0]]; / / Start from the highest point

[0266] let currentPoint = ridgePoints[0];

[0267] let previousDirection = null;

[0268] for (let i = 1; i < ridgePoints.length; i++) {

[0269] const nextPoint = findNextMainPathPoint(currentPoint,ridgePoints, i,

[0270] pathWidth, elevationThreshold, previousDirection);

[0271] if (nextPoint) {

[0272] mainPath.push(nextPoint);

[0273] currentPoint = nextPoint;

[0274] / / Update direction vector

[0275] if (mainPath.length >= 2) {

[0276] const prev = mainPath[mainPath.length - 2];

[0277] previousDirection = {

[0278] x: currentPoint.x - prev.x,

[0279] y: currentPoint.y - prev.y

[0280] };

[0281] / / Normalization

[0282] const magnitude = Math.sqrt(previousDirection.x

[0283] previousDirection.x +

[0284] previousDirection.y previousDirection.y);

[0285] if (magnitude > 0) {

[0286] previousDirection.x / = magnitude;

[0287] previousDirection.y / = magnitude;

[0288] }

[0289] }

[0290] }

[0291] }

[0292] return mainPath;

[0293] /

[0294] Find the next point on the main chain path.

[0295] @param {Object} currentPoint - Current point

[0296] @param {Array} ridgePoints - Ridge Point Set

[0297] @param {number} startIndex - The index to start the search

[0298] @param {number} pathWidth - Path width

[0299] @param {number} elevationThreshold - Elevation Threshold

[0300] @param {Object} previousDirection - Previous direction vector

[0301] @returns {Object|null} - Next point or null

[0302] / function findNextMainPathPoint(currentPoint, ridgePoints,startIndex,

[0303] pathWidth, elevationThreshold, previousDirection) {

[0304] / / Search range (meters)

[0305] const searchRadius = pathWidth × 2;

[0306] Let closestPoint = null;

[0307] Let minDistance = Infinity;

[0308] for (let i = startIndex; i < ridgePoints.length; i++) {

[0309] const point = ridgePoints[i];

[0310] / / Calculate distance

[0311] const dx = point.x - currentPoint.x;

[0312] const dy = point.y - currentPoint.y;

[0313] const distance = Math.sqrt(dx × dx + dy × dy);

[0314] / / Check distance and elevation drop

[0315] if (distance <= searchRadius &&

[0316] Math.abs(point.z - currentPoint.z) <= elevationThreshold) {

[0317] / / Check direction consistency (if there is a previous direction)

[0318] if (previousDirection && distance > 0) {

[0319] const currentDirection = { x: dx / distance, y: dy / distance};

[0320] const dotProduct = currentDirection.x × previousDirection.x +

[0321] currentDirection.y × previousDirection.y;

[0322] / / Ensure the directions are roughly consistent (angle less than 60 degrees)

[0323] if (dotProduct < 0.5) continue;

[0324] }

[0325] if (distance < minDistance) {

[0326] minDistance = distance;

[0327] closestPoint = point;

[0328] }

[0329] }

[0330] }

[0331] return closestPoint;

[0332] /

[0333] Generate branch paths

[0334] @param {Array} mainPath - Main chain path

[0335] @param {Array} ridgePoints - Ridge line point set

[0336] @param {number} pathWidth - Path width

[0337] @param {number} elevationThreshold - Elevation drop threshold

[0338] @param {number} slopeThreshold - Slope threshold (degrees)

[0339] @param {number} minBranchAngle - Minimum branch angle (degrees)

[0340] @param {number} maxBranchAngle - Maximum branch angle (degrees)

[0341] @returns {Array} - Array of branch paths

[0342] / function generateBranchPaths(mainPath, ridgePoints, pathWidth,

[0343] elevationThreshold, slopeThreshold,

[0344] minBranchAngle, maxBranchAngle) {

[0345] const branchPaths = [];

[0346] / / Iterate through the main chain path to find branch points

[0347] for (let i = 1; i < mainPath.length - 1; i++) {

[0348] const currentPoint = mainPath[i];

[0349] const nextPoint = mainPath[i + 1];

[0350] / / Calculate elevation drop

[0351] const elevationDrop = Math.abs(nextPoint.z - currentPoint.z);

[0352] / / If elevation drop exceeds threshold, attempt to generate branch

[0353] if (elevationDrop > elevationThreshold) {

[0354] const branchPath = createBranchPath(currentPoint, mainPath, ridgePoints,

[0355] pathWidth, slopeThreshold,

[0356] minBranchAngle, maxBranchAngle);

[0357] if (branchPath.length > 1) {

[0358] branchPaths.push(branchPath);

[0359] }

[0360] }

[0361] }

[0362] return branchPaths;}

[0363] /

[0364] Create a single branch path

[0365] @param {Object} branchPoint - Branch starting point

[0366] @param {Array} mainPath - Main chain path

[0367] @param {Array} ridgePoints - Ridge line points set

[0368] @param {number} pathWidth - Path width

[0369] @param {number} slopeThreshold - Slope threshold (degrees)

[0370] @param {number} minBranchAngle - Minimum branch angle (degrees)

[0371] @param {number} maxBranchAngle - Maximum branch angle (degrees)

[0372] @returns {Array} - Set of branch path points

[0373] / function createBranchPath(branchPoint, mainPath, ridgePoints, pathWidth,

[0374] slopeThreshold, minBranchAngle, maxBranchAngle) {

[0375] / / Calculate main direction

[0376] const mainDirection = calculateMainDirection(branchPoint, mainPath);

[0377] / / Calculate perpendicular directions (two possible directions left and right)

[0378] const perpendicularDirections = calculatePerpendicularDirections(mainDirection,

[0379] minBranchAngle,

[0380] maxBranchAngle);

[0381] / / Select the best branch direction

[0382] const bestDirection = selectBestBranchDirection(branchPoint,

[0383] perpendicularDirections,

[0384] ridgePoints,

[0385] slopeThreshold);

[0386] if (!bestDirection) return [];

[0387] / / Generate a branch path along that direction

[0388] const branchPath = [branchPoint];

[0389] let currentPoint = branchPoint;

[0390] let searchRadius = pathWidth;

[0391] for (let i = 0; i < 10; i++) { / / Limit branch length

[0392] const nextPoint = findNextBranchPoint(currentPoint,bestDirection,

[0393] ridgePoints, searchRadius,

[0394] slopeThreshold);

[0395] if (nextPoint) {

[0396] branchPath.push(nextPoint);

[0397] currentPoint = nextPoint;

[0398] searchRadius = 1.2; / / Increase search radius

[0399] } else {

[0400] break; / / No suitable next point found

[0401] }

[0402] }

[0403] return branchPath;}

[0404] /

[0405] Computing the direction of the main chain at the branch point

[0406] @param {Object} branchPoint - Branch point

[0407] @param {Array} mainPath - Main chain path

[0408] @returns {Object} - Direction vector {x, y}

[0409] / function calculateMainDirection(branchPoint, mainPath) {

[0410] / / Find the position of the branch point in the main chain

[0411] const index = mainPath.findIndex(p => p === branchPoint);

[0412] if (index < 0 || index >= mainPath.length - 1) {

[0413] return { x: 1, y: 0}; / / Default direction

[0414] }

[0415] const nextPoint = mainPath[index + 1];

[0416] const dx = nextPoint.x - branchPoint.x;

[0417] const dy = nextPoint.y - branchPoint.y;

[0418] / / Normalize

[0419] const magnitude = Math.sqrt(dx × dx + dy × dy);

[0420] if (magnitude > 0) {

[0421] return { x: dx / magnitude, y: dy / magnitude};

[0422] } else {

[0423] return { x: 1, y: 0};

[0424] }}

[0425] /

[0426] Calculate possible directions perpendicular to the main chain, considering 30-45 degree angles

[0427] @param {Object} mainDirection - Main chain direction vector

[0428] @param {number} minAngle - Minimum angle in degrees

[0429] @param {number} maxAngle - Maximum angle in degrees

[0430] @returns {Array} - Array of possible direction vectors

[0431] / function calculatePerpendicularDirections(mainDirection, minAngle,maxAngle) {

[0432] / / Calculate perpendicular direction (90 degrees)

[0433] const perpendicular = {

[0434] x: -mainDirection.y,

[0435] y: mainDirection.x

[0436] };

[0437] / / Generate multiple possible directions considering 30-45 degree angles

[0438] const directions = [];

[0439] const angles = [minAngle, (minAngle + maxAngle) / 2, maxAngle];

[0440] for (const angle of angles) {

[0441] const angleRad = angle × Math.PI / 180;

[0442] / / Clockwise and counter-clockwise directions

[0443] for (const sign of [-1, 1]) {

[0444] / / Rotate the main direction vector

[0445] const rotatedX = mainDirection.x × Math.cos(sign × angleRad) -

[0446] mainDirection.y × Math.sin(sign × angleRad);

[0447] const rotatedY = mainDirection.x × Math.sin(sign × angleRad) +

[0448] mainDirection.y × Math.cos(sign × angleRad);

[0449] directions.push({ x: rotatedX, y: rotatedY});

[0450] }

[0451] }

[0452] / / Normalize all directions

[0453] return directions.map(dir => {

[0454] const magnitude = Math.sqrt(dir.x × dir.x + dir.y × dir.y);

[0455] return { x: dir.x / magnitude, y: dir.y / magnitude};

[0456] });}

[0457] /

[0458] Select optimal branch direction

[0459] @param {Object} branchPoint - Branch point

[0460] @param {Array} directions - Array of candidate directions

[0461] @param {Array} ridgePoints - Ridge Point Set

[0462] @param {number} slopeThreshold - Slope threshold (degrees)

[0463] @returns {Object|null} - Optimal direction or null

[0464] / function selectBestBranchDirection(branchPoint, directions,ridgePoints, slopeThreshold) {

[0465] let bestDirection = null;

[0466] Let bestScore = -Infinity;

[0467] for (const direction of directions) {

[0468] / / Evaluate the score in this direction

[0469] const score = evaluateDirection(branchPoint, direction,ridgePoints, slopeThreshold);

[0470] if (score > bestScore) {

[0471] bestScore = score;

[0472] bestDirection = direction;

[0473] }

[0474] }

[0475] return bestDirection;}

[0476] /

[0477] Score for evaluating branch direction

[0478] @param {Object} branchPoint - Branch point

[0479] @param {Object} direction - Direction vector

[0480] @param {Array} ridgePoints - Ridge Point Set

[0481] @param {number} slopeThreshold - Slope threshold (degrees)

[0482] @returns {number} - Score

[0483] / function evaluateDirection(branchPoint, direction, ridgePoints,slopeThreshold) {

[0484] const searchRadius = 100; / / Search radius (meters)

[0485] const pointsInDirection = [];

[0486] / / Find the point in this direction

[0487] for (const point of ridgePoints) {

[0488] const dx = point.x - branchPoint.x;

[0489] const dy = point.y - branchPoint.y;

[0490] const distance = Math.sqrt(dx × dx + dy × dy);

[0491] if (distance > 0 && distance <= searchRadius) {

[0492] / / Calculate the cosine of the angle between the point and the direction.

[0493] const dotProduct = (dx / distance) × direction.x + (dy / distance) × direction.y;

[0494] / / Only consider points with an angle less than 60 degrees

[0495] if (dotProduct > 0.5) {

[0496] pointsInDirection.push({ point, distance, dotProduct});

[0497] }

[0498] }

[0499] }

[0500] if (pointsInDirection.length === 0) return -Infinity;

[0501] / / Calculate the average slope

[0502] let totalSlope = 0;

[0503] let validPoints = 0;

[0504] for (const item of pointsInDirection) {

[0505] const slope = calculateSlope(branchPoint, item.point);

[0506] if (slope <= slopeThreshold) {

[0507] totalSlope += slope;

[0508] validPoints++;

[0509] }

[0510] }

[0511] if (validPoints === 0) return -Infinity;

[0512] const avgSlope = totalSlope / validPoints;

[0513] / / Score calculation: smaller slope is better, better consistency of direction

[0514] return validPoints × (1 - avgSlope / slopeThreshold);}

[0515] /

[0516] Calculate the slope (in degrees) between two points

[0517] @param {Object} p1 - Point 1

[0518] @param {Object} p2 - Point 2

[0519] @returns {number} - Slope (in degrees)

[0520] / function calculateSlope(p1, p2) {

[0521] const dx = p2.x - p1.x;

[0522] const dy = p2.y - p1.y;

[0523] const horizontalDistance = Math.sqrt(dx × dx + dy × dy);

[0524] const verticalDistance = Math.abs(p2.z - p1.z);

[0525] return Math.atan2(verticalDistance, horizontalDistance) × 180 / Math.PI;}

[0526] /

[0527] Find the next point on a branch path

[0528] @param {Object} currentPoint - Current point

[0529] @param {Object} direction - Direction vector

[0530] @param {Array} ridgePoints - Ridge Point Set

[0531] @param {number} searchRadius - Search radius

[0532] @param {number} slopeThreshold - Slope threshold

[0533] @returns {Object|null} - Next point or null

[0534] / function findNextBranchPoint(currentPoint, direction, ridgePoints,searchRadius, slopeThreshold) {

[0535] let bestPoint = null;

[0536] Let bestScore = -Infinity;

[0537] for (const point of ridgePoints) {

[0538] const dx = point.x - currentPoint.x;

[0539] const dy = point.y - currentPoint.y;

[0540] const distance = Math.sqrt(dx × dx + dy × dy);

[0541] if (distance > 0 && distance <= searchRadius) {

[0542] / / Consistency of calculation and direction

[0543] const dirConsistency = (dx / distance) × direction.x + (dy / distance) × direction.y;

[0544] / / Calculate slope

[0545] const slope = calculateSlope(currentPoint, point);

[0546] / / Check if the slope is acceptable

[0547] if (slope <= slopeThreshold) {

[0548] / / Calculate score: the farther the better, the more consistent the direction the better

[0549] const score = distance × dirConsistency;

[0550] if (score > bestScore) {

[0551] bestScore = score;

[0552] bestPoint = point;

[0553] }

[0554] }

[0555] }

[0556] }

[0557] return bestPoint;}

[0558] S4: Fan coordinate calculation, starting from the starting point determined in S2, along the main chain and branch path planned in S3, combined with the elevation gradient obtained in S1 to calculate the coordinates of each fan;

[0559] In the S4 fan coordinate calculation, the main chain path has a basic step size of 3D, where D is the diameter of the fan impeller, and the branch path has a basic step size of 2D. When the slope is > 20°, the step size increases by 20%. In coordinate calculation, the starting point is moved along the path by a step size, and the actual distance is corrected by combining the elevation gradient. The forward direction is dynamically updated until the path endpoint.

[0560] Branch coordinate calculation: Starting from the turning point of the main chain path, calculate the branch fan coordinates according to the branch path rules to form a chain network of "main chain + branch";

[0561] Where the main logic of the algorithm is:

[0562] Main chain fan position calculation:

[0563] 1. Use 3D as the basic step size;

[0564] 2. Adjust actual step length according to local slope (increase 20% when slope > 20°);

[0565] 3. Correct theoretical position based on ridge line point set;

[0566] 4. Dynamically update forward direction;

[0567] Branch turbine position calculation:

[0568] 5. Start from the branch point of the main chain;

[0569] 6. Use 2D as the basic step length;

[0570] 7. Expand in the direction perpendicular to the main chain;

[0571] 8. Limit the branch path slope to no more than 15°;

[0572] Direction control:

[0573] 9. The main chain direction is automatically adjusted based on local terrain features;

[0574] 10. The branch direction forms a 30-45 degree angle with the main chain;

[0575] 11. Ensure that the turbine arrangement direction matches the wind energy resource distribution.

[0576] In the application of the S5 wake effect suppression algorithm, the upwind turbine spacing is ≥10 times the elevation difference, the downwind turbine spacing is ≥20 times the elevation difference, the elevation difference is the absolute value of the elevation difference between adjacent turbines, and the actual distance is the three-dimensional straight-line distance between adjacent turbines; if the spacing does not meet the requirements, move the turbine position along the path direction to meet the requirements;

[0577] In the application of the S5 wake effect suppression algorithm, the cross staggered arrangement applies a lateral offset of 0.5D to the branch turbine by calculating the vector perpendicular to the branch direction, where D is the stagger offset of the turbine impeller diameter, and the offset directions of adjacent branch turbines are opposite to form alternating positive and negative offsets, including the following algorithms:

[0578] /

[0579] Apply staggered layout optimization

[0580] @param {Array} mainTurbines - Main chain turbine position

[0581] @param {Array} branchTurbines - Branch turbine position

[0582] @param {number} turbineDiameter - Turbine impeller diameter (meters)

[0583] function applyStaggeredLayout(mainTurbines, branchTurbines, turbineDiameter) {

[0584] const offset = turbineDiameter × 0.5; / / lateral offset

[0585] / / Group by branch

[0586] const branchGroups = groupBranchTurbines(branchTurbines);

[0587] / / Apply staggered layout to each branch

[0588] for (let i = 0; i < branchGroups.length; i++) {

[0589] const branch = branchGroups[i];

[0590] / / Determine branch direction (relative to main chain)

[0591] const branchDirection = getBranchDirection(branch[0], mainTurbines);

[0592] / / Calculate vector perpendicular to branch direction

[0593] const perpendicularVector = {

[0594] x: -branchDirection.y,

[0595] y: branchDirection.x

[0596] };

[0597] / / Normalize

[0598] const magnitude = Math.sqrt(perpendicularVector.x × perpendicularVector.x +

[0599] perpendicularVector.y × perpendicularVector.y);

[0600] perpendicularVector.x / = magnitude;

[0601] perpendicularVector.y / = magnitude;

[0602] / / Apply interleaved offset

[0603] for (let j = 0; j < branch.length; j++) {

[0604] / / Alternating positive and negative offsets

[0605] const sign = j % 2 === 0 ? 1 : -1;

[0606] const offsetX = perpendicularVector.x × offset × sign;

[0607] const offsetY = perpendicularVector.y × offset × sign;

[0608] / / Find the index of the fan in the original array and adjust

[0609] const index = branchTurbines.findIndex(t => t === branch[j]);

[0610] if (index !== -1) {

[0611] branchTurbines[index] = {

[0612] ...branch[j],

[0613] x: branch[j].x + offsetX,

[0614] y: branch[j].y + offsetY

[0615] };

[0616] }

[0617] }

[0618] }}

[0619] S5: Application of wake effect suppression algorithm. Based on the wind turbine coordinates obtained in S4, calculate the elevation difference and actual distance between adjacent wind turbines, adjust their positions according to the spacing rules of the downwind and leeward directions, and adopt a staggered arrangement.

[0620] S6: Fan screening, status marking and coordinate output. Based on the adjustment results of S5, the fan is screened and its status is marked. The three-dimensional coordinates of the fans that meet the conditions and the related list and layout diagram are output.

[0621] In the S6 wind turbine screening, status marking, and coordinate output, the screening and marking rules are as follows: wind turbines with a spacing of less than 10 times the elevation difference in the windward direction are marked in red and removed; wind turbines with a spacing of less than 20 times the elevation difference in the leeward direction are marked in yellow and require spacing optimization; wind turbines that meet the spacing requirements are marked in green and retained. The coordinate output includes the three-dimensional coordinates (X, Y, Z) of green wind turbines and a chained layout coordinate list, including the wind turbine number, coordinate values, elevation difference, and layout diagram. The wind turbine screening and status display algorithm is as follows:

[0622] /

[0623] Fan screening and status marking

[0624] @param {Array} turbines - turbine location data

[0625] @param {number} windDirection - Prevailing wind direction (angle)

[0626] @returns {Array} - Tagged wind turbine data

[0627] / function filterAndMarkTurbines(turbines, windDirection) {

[0628] return turbines.map((turbine, index) => {

[0629] if (index === 0) return { ...turbine, status: 'green'}; / / The first turbine passes by default.

[0630] const prevTurbine = turbines[index - 1];

[0631] const distance = calculateDistance(turbine, prevTurbine);

[0632] const elevationDiff = Math.abs(turbine.z - prevTurbine.z);

[0633] / / Calculate the angle between the turbine's line and the prevailing wind direction

[0634] const angle = calculateAngleWithWindDirection(turbine,prevTurbine, windDirection);

[0635] const isDownwind = angle < 90; / / Determine if it's downwind

[0636] / / Apply the filtering rules

[0637] let status;

[0638] if (isDownwind && distance < 10 × elevationDiff) {

[0639] status ='red'; / / Downwind but not enough distance, reject

[0640] } else if (!isDownwind && distance < 20 × elevationDiff) {

[0641] status = 'yellow'; / / Upwind and not enough distance, needs optimization

[0642] } else {

[0643] status = 'green'; / / Meets the requirements

[0644] }

[0645] return {...turbine, status, distance, elevationDiff, isDownwind};

[0646] });}

[0647] While embodiments of the application have been shown and described, it is to be understood that the embodiments described are merely exemplary of the principles and application of the present application. Numerous modifications and adaptions can be effected without departing from the spirit and scope of the present application, which is not limited to the exact construction and arrangement described. It is intended, therefore, to cover all modifications and adaptions that fall within the scope of the claims and their equivalents.

Claims

1. A mountain wind farm wind turbine chain layout data optimization calculation method, characterized in that, The method comprises the following steps: S1: ridge line extraction and elevation driven vector construction, obtaining digital elevation model data of the target area, extracting the ridge line through the watershed analysis method, calculating the elevation gradient and slope direction vector of each point along the ridge line based on the three-dimensional coordinates of the ridge line, and forming an elevation driven vector field to provide terrain data support for S2; S2: starting point determination and initial direction calibration, based on the ridge line and elevation driven vector field obtained in S1, selecting the maximum elevation point in the ridge line range as the starting point, and calibrating the initial direction along the positive elevation vector of the ridge line with the starting point as the origin to provide a starting reference for S3; S3: chain layout path planning, based on the starting point and initial direction determined in S2, the main chain path is determined along the positive elevation vector of the ridge line, and when the terrain is suddenly changed, a branch path is generated along the elevation gentle slope direction perpendicular to the main chain to provide a path basis for S4; S4: fan coordinate calculation, starting from the starting point determined in S2, along the main chain and branch path planned in S3, and combining the elevation gradient obtained in S1 to calculate the coordinates of each fan; S5: application of wake effect suppression algorithm, based on the fan coordinates obtained in S4, the elevation difference and actual distance of adjacent fans are calculated, the positions are adjusted according to the upwind and leeward spacing rules, and the cross staggered arrangement is adopted; S6: fan screening, state marking and coordinate output, based on the adjustment results of S5, the fans are screened and marked, and the three-dimensional coordinates of the fans meeting the conditions, the related list and the layout diagram are output.

2. The method according to claim 1, wherein, In the S1 ridge line extraction and elevation driven vector construction, when processing the digital elevation model data, the cell size and neighborhood search radius need to be set, the digital elevation model grid is constructed, the slope and slope direction of each point are calculated, and then the ridge line is extracted by applying the watershed analysis, and the elevation driven vector field includes the slope, slope direction and elevation gradient parameters.

3. The method according to claim 1, wherein, In the S1 ridge line extraction and elevation driven vector construction, when extracting the ridge line, the digital elevation model grid is traversed, it is judged whether the elevation of a point is greater than the elevations of its surrounding 8 neighboring points to determine the ridge point, and then the ridge points are connected to form a continuous ridge line according to the elevation vector field.

4. The method according to claim 1, wherein, In the S2 starting point determination and initial direction calibration, the starting point is the point with the maximum elevation in the ridge line range, and its three-dimensional coordinates are X0, Y0, Z0, the initial direction calibration needs to calculate the elevation gradient vector of the starting point, and the dominant wind direction angle range is 0-360 degrees, with north as 0, clockwise increase adjustment, so that the calibrated direction is not perpendicular to the dominant wind direction.

5. The method according to claim 1, wherein, In the S3 chain layout path planning, the width of the main chain path is 3 times the fan impeller diameter, the terrain mutation refers to the elevation difference > 50m, the branch path is generated along the elevation gentle slope direction perpendicular to the main chain and the slope < 15°, and the included angle between the branch path and the main chain is 30°~45°.

6. The method according to claim 1, wherein, In the S3 chain layout path planning, when the main chain path is generated, the ridge line points need to be sorted from high to low according to the elevation, and the chain is expanded from the starting point along the ridge line; when the branch path is generated, the direction of the main chain at the branch point needs to be calculated first, then a plurality of possible directions perpendicular to the main chain are generated, and the optimal direction is selected by evaluating the slope and direction consistency.

7. The method according to claim 1, wherein, In the S4 fan coordinate calculation, the main chain path basic step length is 3D, where D is the fan impeller diameter, and the branch path basic step length is 2D, and when the slope is > 20°, the step length increases by 20%, and the coordinates are calculated from the starting point along the path moving step length, combined with the elevation gradient correction actual distance, dynamically updating the forward direction until the path endpoint.

8. The method according to claim 1, wherein, In the application of the S5 wake effect suppression algorithm, the upwind fan spacing is ≥10 times the elevation difference, and the downwind fan spacing is ≥20 times the elevation difference, the elevation difference is the absolute value of the elevation difference between adjacent fans, and the actual distance is the three-dimensional straight line distance between adjacent fans; If the spacing does not meet the requirements, move the fan position along the path direction to meet the requirements.

9. The method according to claim 1, wherein, In the application of the S5 wake effect suppression algorithm, the cross staggered arrangement is achieved by calculating the vector perpendicular to the branch direction, and applying a lateral offset of 0.5D to the branch fan, where D is the staggered offset of the fan impeller diameter, and the offset directions of adjacent branch fans are opposite to form alternating positive and negative offsets.

10. The method according to claim 1, wherein, In the S6 fan screening, state marking and coordinate output, the screening marking rules are: the fan with upwind spacing <10 times the elevation difference is marked red and rejected, the fan with downwind spacing <20 times the elevation difference is marked yellow and needs to be optimized spacing, and the fan that meets the spacing requirements is marked green and retained; the coordinate output content includes the three-dimensional coordinates X, Y, Z of the green fan, the chain layout coordinate list, including the fan number, coordinate value, elevation difference and layout diagram.

Citation Information

Patent Citations

  • Automatic fan arrangement method under complex terrain

    CN118296803A

  • Complex mountain fan arrangement optimization method

    CN120524639A