Differential D4053 Diff 17902 binaries/data/mods/public/maps/random/rmgen/placer/noncentered/WedgePlacer.js
Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/maps/random/rmgen/placer/noncentered/WedgePlacer.js
- This file was added.
/** | |||||
* The WedgePlacer returns all tiles between a center point and two angles. | |||||
*/ | |||||
function WedgePlacer(centerPoint, startAngle, stopAngle, failFraction = 100) { | |||||
lyv: This doesn't really need n^2 atan2 calls. Given these wedges extend to infinity, they can be… | |||||
lyvUnsubmitted Done Inline Actions[obligatory "I am not the one reviewing/testing/committing this and that's merely a suggestion"] lyv: [obligatory "I am not the one reviewing/testing/committing this and that's merely a suggestion"] | |||||
kalimapsAuthorUnsubmitted Not Done Inline ActionsIt's only used on this map for now, but I'm also using it on other maps in progress. There's an existing, but unused player placement type called "arc" which basically compresses the radial player placement. For example, you can use this wedge placer to define wedges of neutral territory between teams and add more specific resource types to those areas. Like adding more metal in the neutral wedge than you do in the team wedge. kalimaps: It's only used on this map for now, but I'm also using it on other maps in progress. There's an… | |||||
this.normalize = 0; | |||||
Not Done Inline ActionsRather than adding a new placer, its better to instead modify DiskPlacer to accept the two angle parameters. It would be more generic and can be used for more cases rather than this sole requirement. lyv: Rather than adding a new placer, its better to instead modify `DiskPlacer` to accept the two… | |||||
this.centerPoint = centerPoint; | |||||
this.startAngle = startAngle; | |||||
this.stopAngle = stopAngle; | |||||
// add 2 * Math.PI to ensure a positive angle | |||||
if (this.startAngle < 0 || this.stopAngle < 0) { | |||||
this.normalize = 2 * Math.PI; | |||||
this.startAngle = startAngle + this.normalize; | |||||
this.stopAngle = stopAngle + this.normalize; | |||||
} | |||||
this.failFraction = failFraction; | |||||
} | |||||
WedgePlacer.prototype.place = function (constraint) { | |||||
let points = []; | |||||
let count = 0; | |||||
let failed = 0; | |||||
for (let x = 0; x < g_Map.getSize(); ++x) { | |||||
for (let y = 0; y < g_Map.getSize(); ++y) { | |||||
++count; | |||||
let point = new Vector2D(x, y); | |||||
let radians = Math.atan2(point.y - this.centerPoint.y, point.x - this.centerPoint.x) + this.normalize; | |||||
if (radians < 0) { | |||||
radians += 2 * Math.PI; | |||||
} | |||||
// check if this angle is between the two angles (plus an optional full rotation) | |||||
if (g_Map.inMapBounds(point) && ((radians >= this.startAngle && radians < this.stopAngle) || (radians + 2 * Math.PI >= this.startAngle && radians + 2 * Math.PI < this.stopAngle)) && constraint.allows(point)) { | |||||
points.push(point); | |||||
} else { | |||||
++failed; | |||||
} | |||||
} | |||||
} | |||||
return failed <= this.failFraction * count ? points : undefined; | |||||
} |
Wildfire Games · Phabricator
This doesn't really need n^2 atan2 calls. Given these wedges extend to infinity, they can be considered as triangles with at least one axis aligned edge meaning you can just use a scanline fill.
I guess a better consideration would be why this is a non-centered placer. Why not change the DiskPlacer to accept sectors instead? As of now, this seems extremely map specific to the case involving circular sectors of an infinitely large disk I guess. But that shouldn't necessarily be a requirement.